GNUnet  0.10.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 
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 replys 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 stat_str_2_type (const char *stat_str)
164 {
165  if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_NO_PULL],
166  stat_str,
167  strlen (stat_type_strings[STAT_TYPE_BLOCKS_NO_PULL])))
168  {
170  }
172  stat_str,
173  strlen (stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL])))
174  {
176  }
177  else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH],
178  stat_str,
179  strlen (stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH])))
180  {
182  }
183  else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL],
184  stat_str,
185  strlen (stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL])))
186  {
188  }
189  else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH],
190  stat_str,
191  strlen (stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH])))
192  {
194  }
195  else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS],
196  stat_str,
197  strlen (stat_type_strings[STAT_TYPE_BLOCKS])))
198  {
199  return STAT_TYPE_BLOCKS;
200  }
201  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ROUNDS],
202  stat_str,
203  strlen (stat_type_strings[STAT_TYPE_ROUNDS])))
204  {
205  return STAT_TYPE_ROUNDS;
206  }
207  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND],
208  stat_str,
209  strlen (stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND])))
210  {
212  }
213  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND_MH],
214  stat_str,
215  strlen (stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND_MH])))
216  {
218  }
219  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ],
220  stat_str,
221  strlen (stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ])))
222  {
224  }
225  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ_MH],
226  stat_str,
227  strlen (stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ_MH])))
228  {
230  }
231  else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PULL_REP],
232  stat_str,
233  strlen (stat_type_strings[STAT_TYPE_ISSUED_PULL_REP])))
234  {
236  }
237  else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PUSH_SEND],
238  stat_str,
239  strlen (stat_type_strings[STAT_TYPE_SENT_PUSH_SEND])))
240  {
242  }
243  else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PULL_REQ],
244  stat_str,
245  strlen (stat_type_strings[STAT_TYPE_SENT_PULL_REQ])))
246  {
248  }
249  else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PULL_REQ_MH],
250  stat_str,
251  strlen (stat_type_strings[STAT_TYPE_SENT_PULL_REQ_MH])))
252  {
254  }
255  else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PULL_REP],
256  stat_str,
257  strlen (stat_type_strings[STAT_TYPE_SENT_PULL_REP])))
258  {
260  }
261  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PUSH_SEND],
262  stat_str,
263  strlen (stat_type_strings[STAT_TYPE_RECV_PUSH_SEND])))
264  {
266  }
267  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PUSH_SEND_MH],
268  stat_str,
269  strlen (stat_type_strings[STAT_TYPE_RECV_PUSH_SEND_MH])))
270  {
272  }
273  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REQ],
274  stat_str,
275  strlen (stat_type_strings[STAT_TYPE_RECV_PULL_REQ])))
276  {
278  }
279  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REQ_MH],
280  stat_str,
281  strlen (stat_type_strings[STAT_TYPE_RECV_PULL_REQ_MH])))
282  {
284  }
285  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REP],
286  stat_str,
287  strlen (stat_type_strings[STAT_TYPE_RECV_PULL_REP])))
288  {
290  }
291  else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REP_MH],
292  stat_str,
293  strlen (stat_type_strings[STAT_TYPE_RECV_PULL_REP_MH])))
294  {
296  }
297  else if (0 == strncmp (stat_type_strings[STAT_TYPE_VIEW_SIZE],
298  stat_str,
299  strlen (stat_type_strings[STAT_TYPE_VIEW_SIZE])))
300  {
301  return STAT_TYPE_VIEW_SIZE;
302  }
303  else if (0 == strncmp (stat_type_strings[STAT_TYPE_KNOWN_PEERS],
304  stat_str,
305  strlen (stat_type_strings[STAT_TYPE_KNOWN_PEERS])))
306  {
307  return STAT_TYPE_KNOWN_PEERS;
308  }
309  else if (0 == strncmp (stat_type_strings[STAT_TYPE_VALID_PEERS],
310  stat_str,
311  strlen (stat_type_strings[STAT_TYPE_VALID_PEERS])))
312  {
313  return STAT_TYPE_VALID_PEERS;
314  }
315  else if (0 == strncmp (stat_type_strings[STAT_TYPE_LEARND_PEERS],
316  stat_str,
317  strlen (stat_type_strings[STAT_TYPE_LEARND_PEERS])))
318  {
319  return STAT_TYPE_LEARND_PEERS;
320  }
321  else if (0 == strncmp (stat_type_strings[STAT_TYPE_PENDING_ONLINE_CHECKS],
322  stat_str,
323  strlen (stat_type_strings[STAT_TYPE_PENDING_ONLINE_CHECKS])))
324  {
326  }
328  stat_str,
329  strlen (stat_type_strings[STAT_TYPE_UNREQUESTED_PULL_REPLIES])))
330  {
332  }
333  else if (0 == strncmp (stat_type_strings[STAT_TYPE_PEERS_IN_PUSH_MAP],
334  stat_str,
335  strlen (stat_type_strings[STAT_TYPE_PEERS_IN_PUSH_MAP])))
336  {
338  }
339  else if (0 == strncmp (stat_type_strings[STAT_TYPE_PEERS_IN_PULL_MAP],
340  stat_str,
341  strlen (stat_type_strings[STAT_TYPE_PEERS_IN_PULL_MAP])))
342  {
344  }
345  else if (0 == strncmp (stat_type_strings[STAT_TYPE_PEERS_IN_VIEW],
346  stat_str,
347  strlen (stat_type_strings[STAT_TYPE_PEERS_IN_VIEW])))
348  {
350  }
351  else if (0 == strncmp (stat_type_strings[STAT_TYPE_VIEW_SIZE_AIM],
352  stat_str,
353  strlen (stat_type_strings[STAT_TYPE_VIEW_SIZE_AIM])))
354  {
356  }
357  return STAT_TYPE_MAX;
358 }
359 
360 
373 };
374 
378 struct OpListEntry
379 {
383  struct OpListEntry *next;
384 
388  struct OpListEntry *prev;
389 
394 
400 
404  unsigned int index;
405 };
406 
410 static struct OpListEntry *oplist_head;
411 
415 static struct OpListEntry *oplist_tail;
416 
417 
422 {
428 
433 
437  struct RPSPeer *rps_peer;
438 };
439 
440 
445 {
451 
456 
460  struct RPSPeer *rps_peer;
461 };
462 
463 
467 struct RPSPeer
468 {
472  unsigned int index;
473 
478 
483 
488 
492  //struct GNUNET_RPS_Request_Handle *req_handle;
493 
497  int online;
498 
502  unsigned int num_ids_to_request;
503 
509 
513  unsigned int num_pending_reqs;
514 
520 
524  unsigned int num_pending_reps;
525 
529  unsigned int num_recv_ids;
530 
535 
540 
545 
552 
556  const char *file_name_stats;
557 
561  const char *file_name_probs;
562 
566  const char *file_name_probs_hist;
567 
572 
576  uint32_t cur_view_count;
577 
581  uint32_t count_in_views;
582 
586  uint64_t stats[STAT_TYPE_MAX];
591 
597 };
598 
602 static struct RPSPeer *rps_peers;
603 
608 
613 
618 
622 static unsigned int num_peers_online;
623 
627 static unsigned int view_sizes;
628 
632 static int ok;
633 
638 
643 
644 
649 
653 typedef void (*InitPeer) (struct RPSPeer *rps_peer);
654 
661 typedef void (*PreTest) (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h);
662 
672 typedef void (*MainTest) (struct RPSPeer *rps_peer);
673 
677 typedef void (*ReplyHandle) (void *cls,
678  uint64_t n,
679  const struct GNUNET_PeerIdentity *recv_peers);
680 
684 typedef void (*PostTest) (struct RPSPeer *peer);
685 
689 typedef int (*EvaluationCallback) (void);
690 
703 };
704 
713 
718 };
719 
728 
733 };
734 
743 
748 };
749 
754 {
758  char *name;
759 
764 
769 
774 
779 
784 
789 
794 
798  uint32_t num_requests;
799 
803  enum OPTION_CHURN have_churn;
804 
808  enum OPTION_QUICK_QUIT have_quick_quit;
809 
813  enum OPTION_COLLECT_STATISTICS have_collect_statistics;
814 
818  enum OPTION_COLLECT_VIEW have_collect_view;
819 
825 } cur_test_run;
826 
830 static int post_test;
831 
835 static int in_shutdown;
836 
840 static void
841 tofile_ (const char *file_name, const char *line)
842 {
843  struct GNUNET_DISK_FileHandle *f;
844  /* char output_buffer[512]; */
845  size_t size;
846  /* int size; */
847  size_t size2;
848 
849  if (NULL == (f = GNUNET_DISK_file_open (file_name,
857  {
859  "Not able to open file %s\n",
860  file_name);
861  return;
862  }
863  /* size = GNUNET_snprintf (output_buffer,
864  sizeof (output_buffer),
865  "%llu %s\n",
866  GNUNET_TIME_absolute_get ().abs_value_us,
867  line);
868  if (0 > size)
869  {
870  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
871  "Failed to write string to buffer (size: %i)\n",
872  size);
873  return;
874  } */
875 
876  size = strlen (line) * sizeof (char);
877 
878  size2 = GNUNET_DISK_file_write (f, line, size);
879  if (size != size2)
880  {
882  "Unable to write to file! (Size: %lu, size2: %lu)\n",
883  size,
884  size2);
886  {
888  "Unable to close file\n");
889  }
890  return;
891  }
892 
894  {
896  "Unable to close file\n");
897  }
898 }
899 
903 #define tofile(file_name, ...) do {\
904  char tmp_buf[512];\
905  int size;\
906  size = GNUNET_snprintf(tmp_buf,sizeof(tmp_buf),__VA_ARGS__);\
907  if (0 > size)\
908  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,\
909  "Failed to create tmp_buf\n");\
910  else\
911  tofile_(file_name,tmp_buf);\
912  } while (0);
913 
914 
919 /* static void
920 ids_to_file (char *file_name,
921  struct GNUNET_PeerIdentity *peer_ids,
922  unsigned int num_peer_ids)
923 {
924  unsigned int i;
925 
926  for (i=0 ; i < num_peer_ids ; i++)
927  {
928  to_file (file_name,
929  "%u\t%s",
930  i,
931  GNUNET_i2s_full (&peer_ids[i]));
932  }
933 } */
934 
938 static int
939 evaluate (void)
940 {
941  unsigned int i;
942  int tmp_ok;
943 
944  tmp_ok = 1;
945 
946  for (i = 0; i < num_peers; i++)
947  {
949  "%u. peer [%s] received %u of %u expected peer_ids: %i\n",
950  i,
951  GNUNET_i2s (rps_peers[i].peer_id),
952  rps_peers[i].num_recv_ids,
953  rps_peers[i].num_ids_to_request,
954  (rps_peers[i].num_ids_to_request == rps_peers[i].num_recv_ids));
955  tmp_ok &= (rps_peers[i].num_ids_to_request == rps_peers[i].num_recv_ids);
956  }
957  return tmp_ok? 0 : 1;
958 }
959 
960 
964 static struct OpListEntry *
966 {
967  struct OpListEntry *entry;
968 
969  entry = GNUNET_new (struct OpListEntry);
970  GNUNET_CONTAINER_DLL_insert_tail (oplist_head, oplist_tail, entry);
971  return entry;
972 }
973 
974 
985  const struct RPSPeer *rps_peer)
986 {
989  rps_peer->stat_collected_flags))
990  {
991  return GNUNET_NO;
992  }
993  return GNUNET_YES;
994 }
1003 {
1004  uint32_t i;
1005 
1006  for (i = 0; i < num_peers; i++)
1007  {
1009  {
1011  "At least Peer %" PRIu32 " did not yet receive all statistics values\n",
1012  i);
1013  return GNUNET_NO;
1014  }
1015  }
1017  "All peers received their statistics values\n");
1018  return GNUNET_YES;
1019 }
1020 
1021 static void
1022 rps_disconnect_adapter (void *cls,
1023  void *op_result);
1024 
1025 static void
1026 cancel_pending_req (struct PendingRequest *pending_req)
1027 {
1028  struct RPSPeer *rps_peer;
1029 
1030  rps_peer = pending_req->rps_peer;
1032  rps_peer->pending_req_tail,
1033  pending_req);
1034  rps_peer->num_pending_reqs--;
1036  "Cancelling pending rps get request\n");
1037  GNUNET_SCHEDULER_cancel (pending_req->request_task);
1038  GNUNET_free (pending_req);
1039 }
1040 
1041 static void
1042 cancel_request (struct PendingReply *pending_rep)
1043 {
1044  struct RPSPeer *rps_peer;
1045 
1046  rps_peer = pending_rep->rps_peer;
1048  rps_peer->pending_rep_tail,
1049  pending_rep);
1050  rps_peer->num_pending_reps--;
1052  "Cancelling rps get reply\n");
1053  GNUNET_assert (NULL != pending_rep->req_handle);
1055  pending_rep->req_handle = NULL;
1056  GNUNET_free (pending_rep);
1057  pending_rep = NULL;
1058 }
1059 
1060 void
1061 clean_peer (unsigned peer_index)
1062 {
1063  struct PendingRequest *pending_req;
1064 
1065  while (NULL != (pending_req = rps_peers[peer_index].pending_req_head))
1066  {
1067  cancel_pending_req (pending_req);
1068  }
1069  pending_req = rps_peers[peer_index].pending_req_head;
1070  rps_disconnect_adapter (&rps_peers[peer_index],
1071  &rps_peers[peer_index].rps_handle);
1072  for (unsigned stat_type = STAT_TYPE_ROUNDS;
1074  stat_type++)
1075  {
1076  if (NULL != rps_peers[peer_index].h_stat_get[stat_type])
1077  {
1079  "(%u) did not yet receive stat value for `%s'\n",
1080  rps_peers[peer_index].index,
1081  stat_type_strings[stat_type]);
1083  rps_peers[peer_index].h_stat_get[stat_type]);
1084  }
1085  }
1086  if (NULL != rps_peers[peer_index].op)
1087  {
1088  GNUNET_TESTBED_operation_done (rps_peers[peer_index].op);
1089  rps_peers[peer_index].op = NULL;
1090  }
1091 }
1092 
1096 static void
1097 shutdown_op (void *cls)
1098 {
1099  unsigned int i;
1100  struct OpListEntry *entry;
1101  (void) cls;
1102 
1104  "Shutdown task scheduled, going down.\n");
1106 
1107  if (NULL != shutdown_task)
1108  {
1109  GNUNET_SCHEDULER_cancel (shutdown_task);
1110  shutdown_task = NULL;
1111  }
1112  if (NULL != post_test_task)
1113  {
1114  GNUNET_SCHEDULER_cancel (post_test_task);
1115  post_test_task = NULL;
1116  }
1117  if (NULL != churn_task)
1118  {
1119  GNUNET_SCHEDULER_cancel (churn_task);
1120  churn_task = NULL;
1121  }
1122  entry = oplist_head;
1123  while (NULL != (entry = oplist_head))
1124  {
1126  "Operation still pending on shutdown (%u)\n",
1127  entry->index);
1129  GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1130  GNUNET_free (entry);
1131  }
1132  for (i = 0; i < num_peers; i++)
1133  {
1134  clean_peer (i);
1135  }
1136  close_all_files();
1137 }
1138 
1139 static void
1140 trigger_shutdown (void *cls)
1141 {
1142  (void) cls;
1143 
1145  "Shutdown was triggerd by timeout, going down.\n");
1146  shutdown_task = NULL;
1148 }
1149 
1150 
1154 static void
1155 post_test_op (void *cls)
1156 {
1157  unsigned int i;
1158  (void) cls;
1159 
1160  post_test_task = NULL;
1163  "Executing post test op.\n");
1164  if (NULL != churn_task)
1165  {
1166  GNUNET_SCHEDULER_cancel (churn_task);
1167  churn_task = NULL;
1168  }
1169  for (i = 0; i < num_peers; i++)
1170  {
1172  "Executing post test op. (peer %" PRIu32 ")\n",
1173  rps_peers[i].index);
1174  if (NULL != rps_peers[i].op)
1175  {
1176  GNUNET_TESTBED_operation_done (rps_peers[i].op);
1177  rps_peers[i].op = NULL;
1179  "Cancelled testbed operation\n");
1180  }
1181  if (NULL != cur_test_run.post_test)
1182  {
1183  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing post_test for peer %u\n", i);
1184  cur_test_run.post_test (&rps_peers[i]);
1185  }
1186  }
1187  /* If we do not collect statistics, shut down directly */
1190  {
1191  GNUNET_SCHEDULER_cancel (shutdown_task);
1192  shutdown_task = NULL;
1194  }
1195 }
1196 
1197 
1201 static void
1202 seed_peers (void *cls)
1203 {
1204  struct RPSPeer *peer = cls;
1205  unsigned int amount;
1206  unsigned int i;
1207 
1208  // TODO if malicious don't seed mal peers
1209  amount = round (.5 * num_peers);
1210 
1211  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Seeding peers:\n");
1212  for (i = 0 ; i < amount ; i++)
1213  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Seeding %u. peer: %s\n",
1214  i,
1215  GNUNET_i2s (&rps_peer_ids[i]));
1216 
1217  GNUNET_RPS_seed_ids (peer->rps_handle, amount, rps_peer_ids);
1218 }
1219 
1220 
1224  void
1225 info_cb (void *cb_cls,
1226  struct GNUNET_TESTBED_Operation *op,
1227  const struct GNUNET_TESTBED_PeerInformation *pinfo,
1228  const char *emsg)
1229 {
1230  struct OpListEntry *entry = (struct OpListEntry *) cb_cls;
1231  (void) op;
1232 
1234  {
1235  return;
1236  }
1237 
1238  if (NULL == pinfo || NULL != emsg)
1239  {
1240  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got Error: %s\n", emsg);
1242  return;
1243  }
1244 
1246  "Peer %u is %s\n",
1247  entry->index,
1248  GNUNET_i2s (pinfo->result.id));
1249 
1250  rps_peer_ids[entry->index] = *(pinfo->result.id);
1251  rps_peers[entry->index].peer_id = &rps_peer_ids[entry->index];
1252 
1255  &rps_peer_ids[entry->index],
1256  &rps_peers[entry->index],
1258  tofile ("/tmp/rps/peer_ids",
1259  "%u\t%s\n",
1260  entry->index,
1261  GNUNET_i2s_full (&rps_peer_ids[entry->index]));
1262 
1263  GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1265  GNUNET_free (entry);
1266 }
1267 
1268 
1278 static void
1280  struct GNUNET_TESTBED_Operation *op,
1281  void *ca_result,
1282  const char *emsg)
1283 {
1284  struct RPSPeer *rps_peer = cls;
1285  struct GNUNET_RPS_Handle *rps = ca_result;
1286 
1288  {
1289  return;
1290  }
1291 
1292  rps_peer->rps_handle = rps;
1293  rps_peer->online = GNUNET_YES;
1294  num_peers_online++;
1295 
1296  GNUNET_assert (op == rps_peer->op);
1297  if (NULL != emsg)
1298  {
1300  "Failed to connect to RPS service: %s\n",
1301  emsg);
1302  ok = 1;
1304  return;
1305  }
1306 
1308  "Started client successfully (%u)\n",
1309  rps_peer->index);
1310 
1311  cur_test_run.main_test (rps_peer);
1312 }
1313 
1314 
1325 static void *
1327  const struct GNUNET_CONFIGURATION_Handle *cfg)
1328 {
1329  struct GNUNET_RPS_Handle *h;
1330 
1331  h = GNUNET_RPS_connect (cfg);
1332 
1333  if (NULL != cur_test_run.pre_test)
1334  cur_test_run.pre_test (cls, h);
1335 
1336  return h;
1337 }
1338 
1348 static void *
1350  const struct GNUNET_CONFIGURATION_Handle *cfg)
1351 {
1352  struct RPSPeer *peer = cls;
1353 
1354  peer->stats_h = GNUNET_STATISTICS_create ("rps-profiler", cfg);
1355  return peer->stats_h;
1356 }
1357 
1364 static void
1366 {
1367  struct RPSPeer *peer = cls;
1368 
1369  //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1370  // (peer->stats_h, "core", "# peers connected",
1371  // stat_iterator, peer));
1372  //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1373  // (peer->stats_h, "nse", "# peers connected",
1374  // stat_iterator, peer));
1375  GNUNET_STATISTICS_destroy (op_result, GNUNET_NO);
1376  peer->stats_h = NULL;
1377 }
1378 
1389 static void
1390 stat_complete_cb (void *cls,
1391  struct GNUNET_TESTBED_Operation *op,
1392  void *ca_result,
1393  const char *emsg )
1394 {
1395  //struct GNUNET_STATISTICS_Handle *sh = ca_result;
1396  //struct RPSPeer *peer = (struct RPSPeer *) cls;
1397  (void) cls;
1398  (void) op;
1399  (void) ca_result;
1400 
1401  if (NULL != emsg)
1402  {
1403  GNUNET_break (0);
1404  return;
1405  }
1406  //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1407  // (sh, "core", "# peers connected",
1408  // stat_iterator, peer));
1409  //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1410  // (sh, "nse", "# peers connected",
1411  // stat_iterator, peer));
1412 }
1413 
1414 
1422 static void
1424  void *op_result)
1425 {
1426  struct RPSPeer *peer = cls;
1427  struct GNUNET_RPS_Handle *h = op_result;
1428  struct PendingReply *pending_rep;
1429 
1431  "disconnect_adapter (%u)\n",
1432  peer->index);
1433  GNUNET_assert (NULL != peer);
1434  if (NULL != peer->rps_handle)
1435  {
1436  while (NULL != (pending_rep = peer->pending_rep_head))
1437  {
1438  cancel_request (pending_rep);
1439  }
1440  GNUNET_assert (h == peer->rps_handle);
1441  if (NULL != h)
1442  {
1444  h = NULL;
1445  }
1446  peer->rps_handle = NULL;
1447  }
1448 }
1449 
1450 
1451 /***********************************************************************
1452  * Definition of tests
1453 ***********************************************************************/
1454 
1462 static void
1464  uint64_t n,
1465  const struct GNUNET_PeerIdentity *recv_peers)
1466 {
1467  struct RPSPeer *rps_peer;
1468  struct PendingReply *pending_rep = (struct PendingReply *) cls;
1469  unsigned int i;
1470 
1471  rps_peer = pending_rep->rps_peer;
1473  rps_peer->pending_rep_tail,
1474  pending_rep);
1475  rps_peer->num_pending_reps--;
1477  "[%s] got %" PRIu64 " peers:\n",
1478  GNUNET_i2s (rps_peer->peer_id),
1479  n);
1480 
1481  for (i = 0; i < n; i++)
1482  {
1484  "%u: %s\n",
1485  i,
1486  GNUNET_i2s (&recv_peers[i]));
1487 
1488  rps_peer->num_recv_ids++;
1489  }
1490 
1491  if (GNUNET_YES != post_test) return;
1493  if (0 == evaluate())
1494  {
1496  "Test succeeded before end of duration\n");
1497  if (NULL != post_test_task) GNUNET_SCHEDULER_cancel (post_test_task);
1498  post_test_task = GNUNET_SCHEDULER_add_now (&post_test_op, NULL);
1499  GNUNET_assert (NULL != post_test_task);
1500  }
1501 }
1502 
1503 
1504 static void
1505 profiler_reply_handle_info (void *cls,
1506  const struct GNUNET_PeerIdentity *recv_peer,
1507  double probability,
1508  uint32_t num_observed);
1509 
1513 static void
1514 request_peers (void *cls)
1515 {
1516  struct PendingRequest *pending_req = cls;
1517  struct RPSPeer *rps_peer;
1518  struct PendingReply *pending_rep;
1519 
1520  rps_peer = pending_req->rps_peer;
1521  GNUNET_assert (1 <= rps_peer->num_pending_reqs);
1523  rps_peer->pending_req_tail,
1524  pending_req);
1525  rps_peer->num_pending_reqs--;
1526  if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test) return;
1528  "Requesting one peer\n");
1529  pending_rep = GNUNET_new (struct PendingReply);
1530  pending_rep->rps_peer = rps_peer;
1531  //pending_rep->req_handle = GNUNET_RPS_request_peers (rps_peer->rps_handle,
1532  // 1,
1533  // cur_test_run.reply_handle,
1534  // pending_rep);
1535  pending_rep->req_handle = GNUNET_RPS_request_peer_info (rps_peer->rps_handle,
1537  pending_rep);
1539  rps_peer->pending_rep_tail,
1540  pending_rep);
1541  rps_peer->num_pending_reps++;
1542 }
1543 
1544 
1549 void
1551 {
1552  unsigned int i;
1553  struct PendingRequest *pending_req;
1554 
1556  "Scheduling %u - %u missing requests\n",
1557  rps_peer->num_ids_to_request,
1558  rps_peer->num_pending_reqs + rps_peer->num_pending_reps);
1559  GNUNET_assert (rps_peer->num_pending_reqs + rps_peer->num_pending_reps <=
1560  rps_peer->num_ids_to_request);
1561  for (i = rps_peer->num_pending_reqs + rps_peer->num_pending_reps;
1562  i < rps_peer->num_ids_to_request; i++)
1563  {
1564  pending_req = GNUNET_new (struct PendingRequest);
1565  pending_req->rps_peer = rps_peer;
1569  request_peers,
1570  pending_req);
1572  rps_peer->pending_req_tail,
1573  pending_req);
1574  rps_peer->num_pending_reqs++;
1575  }
1576 }
1577 
1578 void
1580 {
1582  "Cancelling all (pending) requests.\n");
1583  while (NULL != rps_peer->pending_req_head)
1585  GNUNET_assert (0 == rps_peer->num_pending_reqs);
1586  while (NULL != rps_peer->pending_rep_head)
1587  cancel_request (rps_peer->pending_rep_head);
1588  GNUNET_assert (0 == rps_peer->num_pending_reps);
1589 }
1590 
1591 /***********************************
1592  * MALICIOUS
1593 ***********************************/
1594 
1598 static void mal_init_peer (struct RPSPeer *rps_peer)
1599 {
1600  if (rps_peer->index >= round (portion * num_peers))
1601  rps_peer->num_ids_to_request = 1;
1602 }
1603 
1604 
1613 static void
1614 mal_pre (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
1615 {
1616  #if ENABLE_MALICIOUS
1617  uint32_t num_mal_peers;
1618 
1619  GNUNET_assert ( (1 >= portion) &&
1620  (0 < portion) );
1621  num_mal_peers = round (portion * num_peers);
1622 
1623  if (rps_peer->index < num_mal_peers)
1624  {
1626  "%u. peer [%s] of %" PRIu32 " malicious peers turning malicious\n",
1627  rps_peer->index,
1628  GNUNET_i2s (rps_peer->peer_id),
1629  num_mal_peers);
1630 
1631  GNUNET_RPS_act_malicious (h, mal_type, num_mal_peers,
1632  rps_peer_ids, target_peer);
1633  }
1634  #endif /* ENABLE_MALICIOUS */
1635 }
1636 
1637 static void
1638 mal_cb (struct RPSPeer *rps_peer)
1639 {
1640  uint32_t num_mal_peers;
1641 
1643  {
1644  return;
1645  }
1646 
1647  #if ENABLE_MALICIOUS
1648  GNUNET_assert ( (1 >= portion) &&
1649  (0 < portion) );
1650  num_mal_peers = round (portion * num_peers);
1651 
1652  if (rps_peer->index >= num_mal_peers)
1653  { /* It's useless to ask a malicious peer about a random sample -
1654  it's not sampling */
1656  seed_peers, rps_peer);
1657  schedule_missing_requests (rps_peer);
1658  }
1659  #endif /* ENABLE_MALICIOUS */
1660 }
1661 
1662 /***********************************
1663  * CHURN
1664 ***********************************/
1665 
1666 static void
1667 churn (void *cls);
1668 
1680 static void
1681 churn_test_cb (struct RPSPeer *rps_peer)
1682 {
1684  {
1685  return;
1686  }
1687 
1688  /* Start churn */
1689  if (HAVE_CHURN == cur_test_run.have_churn && NULL == churn_task)
1690  {
1692  "Starting churn task\n");
1693  churn_task = GNUNET_SCHEDULER_add_delayed (
1695  churn,
1696  NULL);
1697  } else {
1699  "Not starting churn task\n");
1700  }
1701 
1702  schedule_missing_requests (rps_peer);
1703 }
1704 
1705 /***********************************
1706  * PROFILER
1707 ***********************************/
1708 
1716 static void
1717 churn_cb (void *cls,
1718  struct GNUNET_TESTBED_Operation *op,
1719  const char *emsg)
1720 {
1721  // FIXME
1722  struct OpListEntry *entry = cls;
1723  (void) op;
1724 
1726  {
1727  return;
1728  }
1729 
1731  if (NULL != emsg)
1732  {
1733  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start/stop RPS at a peer\n");
1735  return;
1736  }
1737  GNUNET_assert (0 != entry->delta);
1738 
1739  num_peers_online += entry->delta;
1740 
1741  if (PEER_GO_OFFLINE == entry->delta)
1742  { /* Peer hopefully just went offline */
1743  if (GNUNET_YES != rps_peers[entry->index].online)
1744  {
1746  "peer %s was expected to go offline but is still marked as online\n",
1747  GNUNET_i2s (rps_peers[entry->index].peer_id));
1748  GNUNET_break (0);
1749  }
1750  else
1751  {
1753  "peer %s probably went offline as expected\n",
1754  GNUNET_i2s (rps_peers[entry->index].peer_id));
1755  }
1756  rps_peers[entry->index].online = GNUNET_NO;
1757  }
1758 
1759  else if (PEER_GO_ONLINE < entry->delta)
1760  { /* Peer hopefully just went online */
1761  if (GNUNET_NO != rps_peers[entry->index].online)
1762  {
1764  "peer %s was expected to go online but is still marked as offline\n",
1765  GNUNET_i2s (rps_peers[entry->index].peer_id));
1766  GNUNET_break (0);
1767  }
1768  else
1769  {
1771  "peer %s probably went online as expected\n",
1772  GNUNET_i2s (rps_peers[entry->index].peer_id));
1773  if (NULL != cur_test_run.pre_test)
1774  {
1775  cur_test_run.pre_test (&rps_peers[entry->index],
1776  rps_peers[entry->index].rps_handle);
1777  schedule_missing_requests (&rps_peers[entry->index]);
1778  }
1779  }
1780  rps_peers[entry->index].online = GNUNET_YES;
1781  }
1782  else
1783  {
1785  "Invalid value for delta: %i\n", entry->delta);
1786  GNUNET_break (0);
1787  }
1788 
1789  GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1790  rps_peers[entry->index].entry_op_manage = NULL;
1791  GNUNET_free (entry);
1792  //if (num_peers_in_round[current_round] == peers_running)
1793  // run_round ();
1794 }
1795 
1804 static void
1805 manage_service_wrapper (unsigned int i, unsigned int j,
1806  enum PEER_ONLINE_DELTA delta,
1807  double prob_go_on_off)
1808 {
1809  struct OpListEntry *entry = NULL;
1810  uint32_t prob;
1811 
1812  /* make sure that management operation is not already scheduled */
1813  if (NULL != rps_peers[j].entry_op_manage)
1814  {
1815  return;
1816  }
1817 
1819  UINT32_MAX);
1821  "%u. selected peer (%u: %s) is %s.\n",
1822  i,
1823  j,
1824  GNUNET_i2s (rps_peers[j].peer_id),
1825  (PEER_GO_ONLINE == delta) ? "online" : "offline");
1826  if (prob < prob_go_on_off * UINT32_MAX)
1827  {
1829  "%s goes %s\n",
1830  GNUNET_i2s (rps_peers[j].peer_id),
1831  (PEER_GO_OFFLINE == delta) ? "offline" : "online");
1832 
1833  if (PEER_GO_OFFLINE == delta)
1834  cancel_pending_req_rep (&rps_peers[j]);
1835  entry = make_oplist_entry ();
1836  entry->delta = delta;
1837  entry->index = j;
1838  entry->op = GNUNET_TESTBED_peer_manage_service (NULL,
1839  testbed_peers[j],
1840  "rps",
1841  &churn_cb,
1842  entry,
1843  (PEER_GO_OFFLINE == delta) ? 0 : 1);
1844  rps_peers[j].entry_op_manage = entry;
1845  }
1846 }
1847 
1848 
1849 static void
1850 churn (void *cls)
1851 {
1852  unsigned int i;
1853  unsigned int j;
1854  double portion_online;
1855  unsigned int *permut;
1856  double prob_go_offline;
1857  double portion_go_online;
1858  double portion_go_offline;
1859  (void) cls;
1860 
1862  {
1863  return;
1864  }
1866  "Churn function executing\n");
1867 
1868  churn_task = NULL; /* Should be invalid by now */
1869 
1870  /* Compute the probability for an online peer to go offline
1871  * this round */
1872  portion_online = num_peers_online * 1.0 / num_peers;
1874  "Portion online: %f\n",
1875  portion_online);
1876  portion_go_online = ((1 - portion_online) * .5 * .66);
1878  "Portion that should go online: %f\n",
1879  portion_go_online);
1880  portion_go_offline = (portion_online + portion_go_online) - .75;
1882  "Portion that probably goes offline: %f\n",
1883  portion_go_offline);
1884  prob_go_offline = portion_go_offline / (portion_online * .5);
1886  "Probability of a selected online peer to go offline: %f\n",
1887  prob_go_offline);
1888 
1890  (unsigned int) num_peers);
1891 
1892  /* Go over 50% randomly chosen peers */
1893  for (i = 0; i < .5 * num_peers; i++)
1894  {
1895  j = permut[i];
1896 
1897  /* If online, shut down with certain probability */
1898  if (GNUNET_YES == rps_peers[j].online)
1899  {
1900  manage_service_wrapper (i, j, -1, prob_go_offline);
1901  }
1902 
1903  /* If offline, restart with certain probability */
1904  else if (GNUNET_NO == rps_peers[j].online)
1905  {
1906  manage_service_wrapper (i, j, 1, 0.66);
1907  }
1908  }
1909 
1910  GNUNET_free (permut);
1911 
1912  churn_task = GNUNET_SCHEDULER_add_delayed (
1914  churn,
1915  NULL);
1916 }
1917 
1918 
1922 static void profiler_init_peer (struct RPSPeer *rps_peer)
1923 {
1925  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer shall request %i peers\n",
1926  rps_peer->num_ids_to_request);
1927 }
1928 
1929 
1937 static void
1939  uint64_t n,
1940  const struct GNUNET_PeerIdentity *recv_peers)
1941 {
1942  struct RPSPeer *rps_peer;
1943  struct RPSPeer *rcv_rps_peer;
1944  char file_name_buf[128];
1945  char file_name_dh_buf[128];
1946  char file_name_dhr_buf[128];
1947  char file_name_dhru_buf[128];
1948  char *file_name = file_name_buf;
1949  char *file_name_dh = file_name_dh_buf;
1950  char *file_name_dhr = file_name_dhr_buf;
1951  char *file_name_dhru = file_name_dhru_buf;
1952  unsigned int i;
1953  struct PendingReply *pending_rep = (struct PendingReply *) cls;
1954 
1955  pending_rep->req_handle = NULL;
1956  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
1957  rps_peer = pending_rep->rps_peer;
1958  (void) GNUNET_asprintf (&file_name,
1959  "/tmp/rps/received_ids-%u",
1960  rps_peer->index);
1961 
1962  (void) GNUNET_asprintf (&file_name_dh,
1963  "/tmp/rps/diehard_input-%u",
1964  rps_peer->index);
1965  (void) GNUNET_asprintf (&file_name_dhr,
1966  "/tmp/rps/diehard_input_raw-%u",
1967  rps_peer->index);
1968  (void) GNUNET_asprintf (&file_name_dhru,
1969  "/tmp/rps/diehard_input_raw_aligned-%u",
1970  rps_peer->index);
1972  "[%s] got %" PRIu64 " peers:\n",
1973  GNUNET_i2s (rps_peer->peer_id),
1974  n);
1975  for (i = 0; i < n; i++)
1976  {
1978  "%u: %s\n",
1979  i,
1980  GNUNET_i2s (&recv_peers[i]));
1981  tofile (file_name,
1982  "%s\n",
1983  GNUNET_i2s_full (&recv_peers[i]));
1984  rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get (peer_map, &recv_peers[i]);
1985  GNUNET_assert (NULL != rcv_rps_peer);
1986  tofile (file_name_dh,
1987  "%" PRIu32 "\n",
1988  (uint32_t) rcv_rps_peer->index);
1989 #ifdef TO_FILE
1990  to_file_raw (file_name_dhr,
1991  (char *) &rcv_rps_peer->index,
1992  sizeof (uint32_t));
1993  to_file_raw_unaligned (file_name_dhru,
1994  (char *) &rcv_rps_peer->index,
1995  sizeof (uint32_t),
1996  bits_needed);
1997 #endif /* TO_FILE */
1998  }
1999  default_reply_handle (cls, n, recv_peers);
2000 }
2001 
2002 
2010 static void
2012  const struct GNUNET_PeerIdentity *recv_peer,
2013  double probability,
2014  uint32_t num_observed)
2015 {
2016  struct RPSPeer *rps_peer;
2017  struct RPSPeer *rcv_rps_peer;
2018  char file_name_buf[128];
2019  char file_name_dh_buf[128];
2020  char file_name_dhr_buf[128];
2021  char file_name_dhru_buf[128];
2022  char *file_name = file_name_buf;
2023  char *file_name_dh = file_name_dh_buf;
2024  char *file_name_dhr = file_name_dhr_buf;
2025  char *file_name_dhru = file_name_dhru_buf;
2026  unsigned int i;
2027  struct PendingReply *pending_rep = (struct PendingReply *) cls;
2028 
2029  pending_rep->req_handle = NULL;
2030  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
2031  rps_peer = pending_rep->rps_peer;
2032  (void) GNUNET_asprintf (&file_name,
2033  "/tmp/rps/received_ids-%u",
2034  rps_peer->index);
2035 
2036  (void) GNUNET_asprintf (&file_name_dh,
2037  "/tmp/rps/diehard_input-%u",
2038  rps_peer->index);
2039  (void) GNUNET_asprintf (&file_name_dhr,
2040  "/tmp/rps/diehard_input_raw-%u",
2041  rps_peer->index);
2042  (void) GNUNET_asprintf (&file_name_dhru,
2043  "/tmp/rps/diehard_input_raw_aligned-%u",
2044  rps_peer->index);
2046  "[%s] got peer with info:\n",
2047  GNUNET_i2s (rps_peer->peer_id));
2049  " %s\n",
2050  GNUNET_i2s (recv_peer));
2051  tofile (file_name,
2052  "%s %d %" PRIu32 " \n",
2053  GNUNET_i2s_full (recv_peer),
2054  probability,
2055  num_observed);
2056  rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get (peer_map, recv_peer);
2057  GNUNET_assert (NULL != rcv_rps_peer);
2058  tofile (file_name_dh,
2059  "%" PRIu32 "\n",
2060  (uint32_t) rcv_rps_peer->index);
2061 #ifdef TO_FILE
2062  to_file_raw (file_name_dhr,
2063  (char *) &rcv_rps_peer->index,
2064  sizeof (uint32_t));
2065  to_file_raw_unaligned (file_name_dhru,
2066  (char *) &rcv_rps_peer->index,
2067  sizeof (uint32_t),
2068  bits_needed);
2069 #endif /* TO_FILE */
2070  default_reply_handle (cls, 1, recv_peer);
2071 }
2072 
2073 
2074 static void
2075 profiler_cb (struct RPSPeer *rps_peer)
2076 {
2078  {
2079  return;
2080  }
2081 
2082  /* Start churn */
2083  if (HAVE_CHURN == cur_test_run.have_churn && NULL == churn_task)
2084  {
2086  "Starting churn task\n");
2087  churn_task = GNUNET_SCHEDULER_add_delayed (
2089  churn,
2090  NULL);
2091  } else {
2093  "Not starting churn task\n");
2094  }
2095 
2096  /* Only request peer ids at one peer.
2097  * (It's the before-last because last one is target of the focussed attack.)
2098  */
2099  if (0 < rps_peer->num_ids_to_request)
2100  schedule_missing_requests (rps_peer);
2101 }
2102 
2112 static int
2113 file_name_cb (void *cls, const char *filename)
2114 {
2115  if (NULL != strstr (filename, "sampler_el"))
2116  {
2117  struct RPS_SamplerElement *s_elem;
2118  struct GNUNET_CRYPTO_AuthKey auth_key;
2119  const char *key_char;
2120  uint32_t i;
2121  (void) cls;
2122 
2123  key_char = filename + 20; /* Length of "/tmp/rps/sampler_el-" */
2124  tofile (filename, "--------------------------\n");
2125 
2126  auth_key = string_to_auth_key (key_char);
2127  s_elem = RPS_sampler_elem_create ();
2128  RPS_sampler_elem_set (s_elem, auth_key);
2129 
2130  for (i = 0; i < num_peers; i++)
2131  {
2132  RPS_sampler_elem_next (s_elem, &rps_peer_ids[i]);
2133  }
2134  RPS_sampler_elem_destroy (s_elem);
2135  }
2136  return GNUNET_OK;
2137 }
2138 
2144 static int
2146 {
2147 #ifdef TO_FILE
2148  /* Compute perfect sample for each sampler element */
2149  if (-1 == GNUNET_DISK_directory_scan ("/tmp/rps/", file_name_cb, NULL))
2150  {
2151  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Scan of directory failed\n");
2152  }
2153 #endif /* TO_FILE */
2154 
2155  return evaluate ();
2156 }
2157 
2158 
2166 static int is_in_view (uint32_t a, uint32_t b)
2167 {
2168  uint32_t i;
2169  for (i = 0; i < rps_peers[a].cur_view_count; i++)
2170  {
2171  if (0 == memcmp (rps_peers[b].peer_id,
2172  &rps_peers[a].cur_view[i],
2173  sizeof (struct GNUNET_PeerIdentity)))
2174  {
2175  return GNUNET_YES;
2176  }
2177  }
2178  return GNUNET_NO;
2179 }
2180 
2181 static uint32_t get_idx_of_pid (const struct GNUNET_PeerIdentity *pid)
2182 {
2183  uint32_t i;
2184 
2185  for (i = 0; i < num_peers; i++)
2186  {
2187  if (0 == memcmp (pid,
2188  rps_peers[i].peer_id,
2189  sizeof (struct GNUNET_PeerIdentity)))
2190  {
2191  return i;
2192  }
2193  }
2194  //return 0; /* Should not happen - make compiler happy */
2196  "No known _PeerIdentity %s!\n",
2197  GNUNET_i2s_full (pid));
2198  GNUNET_assert (0);
2199 }
2200 
2209 static uint32_t count_containing_views (uint32_t a, uint32_t b)
2210 {
2211  uint32_t i;
2212  uint32_t peer_idx;
2213  uint32_t count = 0;
2214 
2215  for (i = 0; i < rps_peers[a].cur_view_count; i++)
2216  {
2217  peer_idx = get_idx_of_pid (&rps_peers[a].cur_view[i]);
2218  if (GNUNET_YES == is_in_view (peer_idx, b))
2219  {
2220  count++;
2221  }
2222  }
2223  return count;
2224 }
2225 
2232 static void compute_probabilities (uint32_t peer_idx)
2233 {
2234  //double probs[num_peers] = { 0 };
2235  double probs[num_peers];
2236  double probs_hist[num_peers]; /* Probability respecting the history */
2237  size_t probs_as_str_size = (num_peers * 10 + 2) * sizeof (char);
2238  char *probs_as_str = GNUNET_malloc (probs_as_str_size);
2239  char *probs_as_str_cpy;
2240  uint32_t i;
2241  double prob_push;
2242  double prob_pull;
2243  uint32_t view_size;
2244  uint32_t cont_views;
2245  uint32_t number_of_being_in_pull_events;
2246  int tmp;
2247  double sum_non_zero_prob = 0;
2248  double sum_non_zero_prob_hist = 0;
2249 
2251  "Computing probabilities for peer %" PRIu32 "\n", peer_idx);
2252  /* Firstly without knowledge of old views */
2253  for (i = 0; i < num_peers; i++)
2254  {
2256  "\tfor peer %" PRIu32 ":\n", i);
2257  view_size = rps_peers[i].cur_view_count;
2259  "\t\tview_size: %" PRIu32 "\n", view_size);
2260  /* For peer i the probability of being sampled is
2261  * evenly distributed among all possibly observed peers. */
2262  /* We could have observed a peer in three cases:
2263  * 1. peer sent a push
2264  * 2. peer was contained in a pull reply
2265  * 3. peer was in history (sampler) - ignored for now */
2266  /* 1. Probability of having received a push from peer i */
2267  if ((GNUNET_YES == is_in_view (i, peer_idx)) &&
2268  (1 <= (0.45 * view_size)))
2269  {
2270  if (0 == binom (view_size, 0.45 * view_size)) prob_push = 0;
2271  else
2272  {
2273  prob_push = 1.0 * binom (0.45 * view_size, 1)
2274  /
2275  binom (view_size, 0.45 * view_size);
2276  }
2278  "\t\t%" PRIu32 " is in %" PRIu32 "'s view, prob: %f\n",
2279  peer_idx,
2280  i,
2281  prob_push);
2283  "\t\tposs choices from view: %" PRIu32 ", containing i: %" PRIu32 "\n",
2284  binom (view_size, 0.45 * view_size),
2285  binom (0.45 * view_size, 1));
2286  } else {
2287  prob_push = 0;
2289  "\t\t%" PRIu32 " is not in %" PRIu32 "'s view, prob: 0\n",
2290  peer_idx,
2291  i);
2292  }
2293  /* 2. Probability of peer i being contained in pulls */
2294  view_size = rps_peers[peer_idx].cur_view_count;
2295  cont_views = count_containing_views (peer_idx, i);
2296  number_of_being_in_pull_events =
2297  (binom (view_size, 0.45 * view_size) -
2298  binom (view_size - cont_views, 0.45 * view_size));
2299  if (0 != number_of_being_in_pull_events)
2300  {
2301  prob_pull = number_of_being_in_pull_events
2302  /
2303  (1.0 * binom (view_size, 0.45 * view_size));
2304  } else
2305  {
2306  prob_pull = 0;
2307  }
2308  probs[i] = prob_push + prob_pull - (prob_push * prob_pull);
2310  "\t\t%" PRIu32 " has %" PRIu32 " of %" PRIu32
2311  " peers in its view who know %" PRIu32 " prob: %f\n",
2312  peer_idx,
2313  cont_views,
2314  view_size,
2315  i,
2316  prob_pull);
2318  "\t\tnumber of possible pull combinations: %" PRIu32 "\n",
2319  binom (view_size, 0.45 * view_size));
2321  "\t\tnumber of possible pull combinations without %" PRIu32
2322  ": %" PRIu32 "\n",
2323  i,
2324  binom (view_size - cont_views, 0.45 * view_size));
2326  "\t\tnumber of possible pull combinations with %" PRIu32
2327  ": %" PRIu32 "\n",
2328  i,
2329  number_of_being_in_pull_events);
2330 
2331  probs_hist[i] = 0.9 * rps_peers[peer_idx].eval_probs_cache[i] + probs[i];
2332  rps_peers[peer_idx].eval_probs_cache[i] = probs_hist[i];
2333 
2334  sum_non_zero_prob += probs[i];
2335  sum_non_zero_prob_hist += probs_hist[i];
2336  }
2337  /* normalize */
2338  if (0 != sum_non_zero_prob)
2339  {
2340  for (i = 0; i < num_peers; i++)
2341  {
2342  probs[i] = probs[i] * (1.0 / sum_non_zero_prob);
2343  }
2344  }
2345  if (0 != sum_non_zero_prob_hist)
2346  {
2347  for (i = 0; i < num_peers; i++)
2348  {
2349  probs_hist[i] = probs_hist[i] * (1.0 / sum_non_zero_prob_hist);
2350  }
2351  }
2352 
2353  /* str repr */
2354  for (i = 0; i < num_peers; i++)
2355  {
2356  probs_as_str_cpy = GNUNET_strndup (probs_as_str, probs_as_str_size);
2357  tmp = GNUNET_snprintf (probs_as_str,
2358  probs_as_str_size,
2359  "%s %7.6f", probs_as_str_cpy, probs[i]);
2360  GNUNET_free (probs_as_str_cpy);
2361  GNUNET_assert (0 <= tmp);
2362  }
2363 
2364  to_file_w_len (rps_peers[peer_idx].file_name_probs,
2365  probs_as_str_size,
2366  probs_as_str);
2367 
2368  probs_as_str[0] = '\0';
2369  for (i = 0; i < num_peers; i++)
2370  {
2371  probs_as_str_cpy = GNUNET_strndup (probs_as_str, probs_as_str_size);
2372  tmp = GNUNET_snprintf (probs_as_str,
2373  probs_as_str_size,
2374  "%s %7.6f", probs_as_str_cpy, probs_hist[i]);
2375  GNUNET_free (probs_as_str_cpy);
2376  GNUNET_assert (0 <= tmp);
2377  }
2378 
2379  to_file_w_len (rps_peers[peer_idx].file_name_probs_hist,
2380  probs_as_str_size,
2381  probs_as_str);
2382  GNUNET_free (probs_as_str);
2383 }
2384 
2394 static uint32_t count_peer_in_views_2 (uint32_t peer_idx)
2395 {
2396  uint32_t i, j;
2397  uint32_t count = 0;
2398 
2399  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2400  {
2401  for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2402  {
2403  if (0 == memcmp (rps_peers[peer_idx].peer_id,
2404  &rps_peers[i].cur_view[j],
2405  sizeof (struct GNUNET_PeerIdentity)))
2406  {
2407  count++;
2408  break;
2409  }
2410  }
2411  }
2412  rps_peers[peer_idx].count_in_views = count;
2413  return count;
2414 }
2415 
2416 static uint32_t cumulated_view_sizes ()
2417 {
2418  uint32_t i;
2419 
2420  view_sizes = 0;
2421  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2422  {
2423  view_sizes += rps_peers[i].cur_view_count;
2424  }
2425  return view_sizes;
2426 }
2427 
2428 static void count_peer_in_views (uint32_t *count_peers)
2429 {
2430  uint32_t i, j;
2431 
2432  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2433  {
2434  for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2435  {
2436  if (0 == memcmp (rps_peers[i].peer_id,
2437  &rps_peers[i].cur_view[j],
2438  sizeof (struct GNUNET_PeerIdentity)))
2439  {
2440  count_peers[i]++;
2441  }
2442  }
2443  }
2444 }
2445 
2447 {
2448  uint32_t i;
2449  /* ith entry represents the numer of occurrences in other peer's views */
2450  uint32_t *count_peers = GNUNET_new_array (num_peers, uint32_t);
2451  uint32_t views_total_size;
2452  double expected;
2453  /* deviation from expected number of peers */
2454  double *deviation = GNUNET_new_array (num_peers, double);
2455 
2456  views_total_size = 0;
2457  expected = 0;
2458 
2459  /* For each peer count its representation in other peer's views*/
2460  for (i = 0; i < num_peers; i++) /* Peer to count */
2461  {
2462  views_total_size += rps_peers[i].cur_view_count;
2463  count_peer_in_views (count_peers);
2465  "Counted representation of %" PRIu32 "th peer [%s]: %" PRIu32"\n",
2466  i,
2467  GNUNET_i2s (rps_peers[i].peer_id),
2468  count_peers[i]);
2469  }
2470 
2472  "size of all views combined: %" PRIu32 "\n",
2473  views_total_size);
2474  expected = ((double) 1/num_peers) * views_total_size;
2476  "Expected number of occurrences of each peer in all views: %f\n",
2477  expected);
2478  for (i = 0; i < num_peers; i++) /* Peer to count */
2479  {
2480  deviation[i] = expected - count_peers[i];
2482  "Deviation from expectation: %f\n", deviation[i]);
2483  }
2484  GNUNET_free (count_peers);
2485  GNUNET_free (deviation);
2486 }
2487 
2489 {
2490  uint32_t i;
2491 
2492  for (i = 0; i < num_peers; i++) /* Peer to count */
2493  {
2495  "View size of %" PRIu32 ". [%s] is %" PRIu32 "\n",
2496  i,
2497  GNUNET_i2s (rps_peers[i].peer_id),
2498  rps_peers[i].cur_view_count);
2499  }
2500 }
2501 
2503 {
2505  print_view_sizes();
2506 }
2507 
2508 void view_update_cb (void *cls,
2509  uint64_t view_size,
2510  const struct GNUNET_PeerIdentity *peers)
2511 {
2513  "View was updated (%" PRIu64 ")\n", view_size);
2514  struct RPSPeer *rps_peer = (struct RPSPeer *) cls;
2515  to_file ("/tmp/rps/view_sizes.txt",
2516  "%" PRIu64 " %" PRIu32 "",
2517  rps_peer->index,
2518  view_size);
2519  for (uint64_t i = 0; i < view_size; i++)
2520  {
2522  "\t%s\n", GNUNET_i2s (&peers[i]));
2523  }
2524  GNUNET_array_grow (rps_peer->cur_view,
2525  rps_peer->cur_view_count,
2526  view_size);
2527  //*rps_peer->cur_view = *peers;
2528  GNUNET_memcpy (rps_peer->cur_view,
2529  peers,
2530  view_size * sizeof (struct GNUNET_PeerIdentity));
2531  to_file ("/tmp/rps/count_in_views.txt",
2532  "%" PRIu64 " %" PRIu32 "",
2533  rps_peer->index,
2534  count_peer_in_views_2 (rps_peer->index));
2536  if (0 != view_size)
2537  {
2538  to_file ("/tmp/rps/repr.txt",
2539  "%" PRIu64 /* index */
2540  " %" PRIu32 /* occurrence in views */
2541  " %" PRIu32 /* view sizes */
2542  " %f" /* fraction of repr in views */
2543  " %f" /* average view size */
2544  " %f" /* prob of occurrence in view slot */
2545  " %f" "", /* exp frac of repr in views */
2546  rps_peer->index,
2547  count_peer_in_views_2 (rps_peer->index),
2548  view_sizes,
2549  count_peer_in_views_2 (rps_peer->index) / (view_size * 1.0), /* fraction of representation in views */
2550  view_sizes / (view_size * 1.0), /* average view size */
2551  1.0 /view_size, /* prob of occurrence in view slot */
2552  (1.0/view_size) * (view_sizes/view_size) /* expected fraction of repr in views */
2553  );
2554  }
2555  compute_probabilities (rps_peer->index);
2557 }
2558 
2559 static void
2560 pre_profiler (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
2561 {
2562  rps_peer->file_name_probs =
2563  store_prefix_file_name (rps_peer->index, "probs");
2564  rps_peer->file_name_probs_hist =
2565  store_prefix_file_name (rps_peer->index, "probs_hist");
2566  GNUNET_RPS_view_request (h, 0, view_update_cb, rps_peer);
2567 }
2568 
2569 void write_final_stats (void){
2570  uint64_t sums[STAT_TYPE_MAX] = { 0 };
2571 
2572  for (uint32_t i = 0; i < num_peers; i++)
2573  {
2574  to_file ("/tmp/rps/final_stats.csv",
2575  "%" PRIu32 ", " /* index */
2576  "%s, %" /* id */
2577  PRIu64 ", %" /* rounds */
2578  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* blocking */
2579  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* issued */
2580  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* sent */
2581  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* recv */
2582  PRIu64 ", %" /* view size */
2583  PRIu64 ", %" /* known peers */
2584  PRIu64 ", %" /* valid peers */
2585  PRIu64 ", %" /* learned peers */
2586  PRIu64 ", %" /* pending online checks */
2587  PRIu64 ", %" /* unrequested pull replies */
2588  PRIu64 ", %" /* peers in push map */
2589  PRIu64 ", %" /* peers in pull map */
2590  PRIu64 ", %" /* peers in view */
2591  PRIu64 "\n"/* view size aim */,
2592  i,
2593  GNUNET_i2s (rps_peers[i].peer_id),
2594  rps_peers[i].stats[STAT_TYPE_ROUNDS],
2595  rps_peers[i].stats[STAT_TYPE_BLOCKS],
2596  rps_peers[i].stats[STAT_TYPE_BLOCKS_MANY_PUSH],
2597  rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PUSH],
2598  rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PULL],
2601  rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND],
2602  rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND_MH],
2603  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ],
2604  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ_MH],
2605  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REP],
2606  rps_peers[i].stats[STAT_TYPE_SENT_PUSH_SEND],
2607  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ],
2608  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ_MH],
2609  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REP],
2610  rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND],
2611  rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND_MH],
2612  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ],
2613  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ_MH],
2614  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP_MH],
2615  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP],
2616  rps_peers[i].stats[STAT_TYPE_VIEW_SIZE],
2617  rps_peers[i].stats[STAT_TYPE_KNOWN_PEERS],
2618  rps_peers[i].stats[STAT_TYPE_VALID_PEERS],
2619  rps_peers[i].stats[STAT_TYPE_LEARND_PEERS],
2620  rps_peers[i].stats[STAT_TYPE_PENDING_ONLINE_CHECKS],
2622  rps_peers[i].stats[STAT_TYPE_PEERS_IN_PUSH_MAP],
2623  rps_peers[i].stats[STAT_TYPE_PEERS_IN_PULL_MAP],
2624  rps_peers[i].stats[STAT_TYPE_PEERS_IN_VIEW],
2625  rps_peers[i].stats[STAT_TYPE_VIEW_SIZE_AIM]);
2626  for (enum STAT_TYPE stat_type = STAT_TYPE_ROUNDS;
2628  stat_type++)
2629  {
2630  sums[stat_type] += rps_peers[i].stats[stat_type];
2631  }
2632  }
2633  to_file ("/tmp/rps/final_stats.dat",
2634  "SUM %"
2635  PRIu64 " %" /* rounds */
2636  PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" /* blocking */
2637  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* issued */
2638  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* sent */
2639  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* recv */
2640  PRIu64 ", %" /* view size */
2641  PRIu64 ", %" /* known peers */
2642  PRIu64 ", %" /* valid peers */
2643  PRIu64 ", %" /* learned peers */
2644  PRIu64 ", %" /* pending online checks */
2645  PRIu64 ", %" /* unrequested pull replies */
2646  PRIu64 ", %" /* peers in push map */
2647  PRIu64 ", %" /* peers in pull map */
2648  PRIu64 ", %" /* peers in view */
2649  PRIu64 "\n"/* view size aim */,
2650  sums[STAT_TYPE_ROUNDS],
2651  sums[STAT_TYPE_BLOCKS],
2672  sums[STAT_TYPE_VIEW_SIZE],
2673  sums[STAT_TYPE_KNOWN_PEERS],
2674  sums[STAT_TYPE_VALID_PEERS],
2675  sums[STAT_TYPE_LEARND_PEERS],
2681  sums[STAT_TYPE_VIEW_SIZE_AIM]);
2682 }
2683 
2695 void
2697  int success)
2698 {
2699  struct STATcls *stat_cls = (struct STATcls *) cls;
2700  struct RPSPeer *rps_peer = stat_cls->rps_peer;
2701 
2702  rps_peer->h_stat_get[stat_cls->stat_type] = NULL;
2703  if (GNUNET_OK == success)
2704  {
2705  /* set flag that we we got the value */
2706  rps_peer->stat_collected_flags |= BIT(stat_cls->stat_type);
2707  } else {
2709  "Peer %u did not receive statistics value\n",
2710  rps_peer->index);
2711  GNUNET_free (stat_cls);
2712  GNUNET_break (0);
2713  return;
2714  }
2715 
2716  if (NULL != rps_peer->stat_op &&
2718  {
2720  }
2721 
2722  write_final_stats ();
2724  {
2725  //write_final_stats ();
2726  GNUNET_free (stat_cls);
2728  "Shutting down\n");
2730  } else {
2731  GNUNET_free (stat_cls);
2732  }
2733 }
2734 
2745 int
2746 stat_iterator (void *cls,
2747  const char *subsystem,
2748  const char *name,
2749  uint64_t value,
2750  int is_persistent)
2751 {
2752  const struct STATcls *stat_cls = (const struct STATcls *) cls;
2753  struct RPSPeer *rps_peer = (struct RPSPeer *) stat_cls->rps_peer;
2754  enum STAT_TYPE stat_type;
2755  (void) subsystem;
2756  (void) is_persistent;
2757 
2759  "Got stat value: %s - %" PRIu64 " (%u)\n",
2760  name,
2761  value,
2762  rps_peer->index);
2763  to_file (rps_peer->file_name_stats,
2764  "%s: %" PRIu64 "\n",
2765  name,
2766  value);
2767  stat_type = stat_str_2_type (name);
2770  rps_peer->stats[stat_type] = value;
2771  return GNUNET_OK;
2772 }
2773 
2774 
2775 void
2776 post_profiler (struct RPSPeer *rps_peer)
2777 {
2779  {
2780  return;
2781  }
2782 
2784  "Going to request statistic values with mask 0x%" PRIx32 "\n",
2786 
2787  struct STATcls *stat_cls;
2788  uint32_t stat_type;
2789  for (stat_type = STAT_TYPE_ROUNDS;
2790  stat_type < STAT_TYPE_MAX;
2791  stat_type++)
2792  {
2793  if (BIT(stat_type) & cur_test_run.stat_collect_flags)
2794  {
2795  stat_cls = GNUNET_malloc (sizeof (struct STATcls));
2796  stat_cls->rps_peer = rps_peer;
2797  stat_cls->stat_type = stat_type;
2798  rps_peer->file_name_stats =
2799  store_prefix_file_name (rps_peer->peer_id, "stats");
2800  rps_peer->h_stat_get[stat_type] =
2801  GNUNET_STATISTICS_get (rps_peer->stats_h,
2802  "rps",
2803  stat_type_strings [stat_type],
2805  stat_iterator,
2806  (struct STATcls *) stat_cls);
2807  GNUNET_assert (NULL != rps_peer->h_stat_get);
2809  "Requested statistics for %s (peer %" PRIu32 ")\n",
2810  stat_type_strings [stat_type],
2811  rps_peer->index);
2812  }
2813  }
2814  GNUNET_free (rps_peer->eval_probs_cache);
2815 }
2816 
2817 
2818 /***********************************************************************
2819  * /Definition of tests
2820 ***********************************************************************/
2821 
2822 
2835 static void
2836 test_run (void *cls,
2837  struct GNUNET_TESTBED_RunHandle *h,
2838  unsigned int n_peers,
2839  struct GNUNET_TESTBED_Peer **peers,
2840  unsigned int links_succeeded,
2841  unsigned int links_failed)
2842 {
2843  unsigned int i;
2844  struct OpListEntry *entry;
2845  (void) cls;
2846  (void) h;
2847  (void) links_failed;
2848 
2849  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RUN was called\n");
2850 
2851  /* Check whether we timed out */
2852  if (n_peers != num_peers ||
2853  NULL == peers ||
2854  0 == links_succeeded)
2855  {
2856  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Going down due to args (eg. timeout)\n");
2857  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tn_peers: %u\n", n_peers);
2858  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tnum_peers: %" PRIu32 "\n", num_peers);
2859  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tpeers: %p\n", peers);
2860  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tlinks_succeeded: %u\n", links_succeeded);
2861  ok = 1;
2863  return;
2864  }
2865 
2866 
2867  /* Initialize peers */
2868  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "going to initialise peers\n");
2869  testbed_peers = peers;
2870  num_peers_online = 0;
2871  for (i = 0; i < num_peers; i++)
2872  {
2873  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "initialising %u\n", i);
2874  entry = make_oplist_entry ();
2875  entry->index = i;
2876  rps_peers[i].index = i;
2877  if (NULL != cur_test_run.init_peer)
2878  cur_test_run.init_peer (&rps_peers[i]);
2880  {
2881  rps_peers->cur_view_count = 0;
2882  rps_peers->cur_view = NULL;
2883  }
2884  entry->op = GNUNET_TESTBED_peer_get_information (peers[i],
2886  &info_cb,
2887  entry);
2888  }
2889 
2890  /* Bring peers up */
2891  GNUNET_assert (num_peers == n_peers);
2892  for (i = 0; i < n_peers; i++)
2893  {
2894  rps_peers[i].index = i;
2895  rps_peers[i].op =
2896  GNUNET_TESTBED_service_connect (&rps_peers[i],
2897  peers[i],
2898  "rps",
2900  &rps_peers[i],
2903  &rps_peers[i]);
2904  /* Connect all peers to statistics service */
2906  {
2908  "Connecting to statistics service\n");
2909  rps_peers[i].stat_op =
2911  peers[i],
2912  "statistics",
2914  &rps_peers[i],
2917  &rps_peers[i]);
2918  }
2919  }
2920 
2921  if (NULL != churn_task)
2922  GNUNET_SCHEDULER_cancel (churn_task);
2923  post_test_task = GNUNET_SCHEDULER_add_delayed (duration, &post_test_op, NULL);
2924  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "timeout for shutdown is %lu\n", timeout.rel_value_us/1000000);
2925  shutdown_task = GNUNET_SCHEDULER_add_delayed (timeout,
2927  NULL);
2929 }
2930 
2931 
2938 static void
2939 run (void *cls,
2940  char *const *args,
2941  const char *cfgfile,
2942  const struct GNUNET_CONFIGURATION_Handle *cfg)
2943 {
2944  //int ret_value;
2945  (void) cls;
2946  (void) args;
2947  (void) cfgfile;
2948 
2949  /* Defaults for tests */
2950  churn_task = NULL;
2951 
2952  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n");
2953  cur_test_run.name = "test-rps-profiler";
2954  if (0 == num_peers)
2955  num_peers = 10;
2956  mal_type = 3;
2958  //cur_test_run.pre_test = mal_pre;
2966  //cur_test_run.have_churn = HAVE_CHURN;
3003 
3004  /* 'Clean' directory */
3005  (void) GNUNET_DISK_directory_remove ("/tmp/rps/");
3006  GNUNET_DISK_directory_create ("/tmp/rps/");
3007  if (0 == duration.rel_value_us)
3008  {
3009  if (0 == timeout.rel_value_us)
3010  {
3013  (90 * 1.2) +
3014  (0.01 * num_peers));
3015  }
3016  else
3017  {
3019  (timeout.rel_value_us/1000000)
3020  * 0.75);
3021  }
3022  }
3023  else
3024  {
3025  if (0 == timeout.rel_value_us)
3026  {
3028  ((duration.rel_value_us/1000000)
3029  * 1.2) + (0.01 * num_peers));
3030  }
3031  }
3034  "duration is %lus\n",
3035  duration.rel_value_us/1000000);
3037  "timeout is %lus\n",
3038  timeout.rel_value_us/1000000);
3039 
3040  /* Compute number of bits for representing largest peer id */
3041  for (bits_needed = 1; (1 << bits_needed) < num_peers; bits_needed++)
3042  ;
3044  "Need %u bits to represent %" PRIu32 " peers\n",
3045  bits_needed,
3046  num_peers);
3047 
3048  rps_peers = GNUNET_new_array (num_peers, struct RPSPeer);
3050  rps_peer_ids = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
3051  if ( (2 == mal_type) ||
3052  (3 == mal_type))
3053  target_peer = &rps_peer_ids[num_peers - 2];
3054 
3055  ok = 1;
3056  GNUNET_TESTBED_run (NULL,
3057  cfg,
3058  num_peers,
3059  0, /* event mask */
3060  NULL,
3061  NULL,
3062  &test_run,
3063  NULL);
3064 }
3065 
3073 int
3074 main (int argc, char *argv[])
3075 {
3076  int ret_value;
3077  struct GNUNET_GETOPT_CommandLineOption options[] = {
3079  "num-peers",
3080  "COUNT",
3081  gettext_noop ("number of peers to start"),
3082  &num_peers),
3084  "duration",
3085  "DURATION",
3086  gettext_noop ("duration of the profiling"),
3087  &duration),
3089  "timeout",
3090  "TIMEOUT",
3091  gettext_noop ("timeout for the profiling"),
3092  &timeout),
3094  "num-requests",
3095  "COUNT",
3096  gettext_noop ("number of PeerIDs to request"),
3099  };
3100 
3101  unsetenv ("XDG_DATA_HOME");
3102  unsetenv ("XDG_CONFIG_HOME");
3103  //if (GNUNET_OK !=
3104  // GNUNET_STRINGS_get_utf8_args (argc, argv,
3105  // &argc, &argv))
3106  // return 2;
3107  ret_value = 0;
3108  if (GNUNET_OK !=
3109  GNUNET_PROGRAM_run (argc,
3110  argv,
3111  "gnunet-rps-profiler",
3112  gettext_noop ("Measure quality and performance of the RPS service."),
3113  options,
3114  &run,
3115  NULL))
3116  {
3117  ret_value = 1;
3118  }
3119  if (0 != ret_value)
3120  {
3122  "Test did not run successfully!\n");
3123  }
3124  else
3125  {
3126  ret_value = cur_test_run.eval_cb();
3128  {
3129  GNUNET_array_grow (rps_peers->cur_view,
3130  rps_peers->cur_view_count,
3131  0);
3132  }
3133  GNUNET_free (rps_peers);
3134  GNUNET_free (rps_peer_ids);
3136  }
3137  return ret_value;
3138 }
3139 
3140 /* 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.
static struct GNUNET_STATISTICS_Handle * stats
Handle for statistics.
unsigned int index
Index of the peer.
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.
int GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1817
static int is_in_view(uint32_t a, uint32_t b)
is b in view of a?
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.
union GNUNET_TESTBED_PeerInformation::@64 result
The result of the get information operation; Choose according to the pit.
void GNUNET_RPS_seed_ids(struct GNUNET_RPS_Handle *h, uint32_t n, const struct GNUNET_PeerIdentity *ids)
Seed rps service with peerIDs.
Definition: rps_api.c:1029
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.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
void RPS_sampler_elem_destroy(struct RPS_SamplerElement *sampler_elem)
Destroy a sampler element.
struct PendingRequest * prev
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:714
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:1293
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 faciliating 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.
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:244
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?
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
Type of malicious peer to test.
Linked list of things we still need to do.
static char * peer_id
Option –peer.
Definition: gnunet-cadet.c:42
#define GNUNET_NO
Definition: gnunet_common.h:81
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).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:1233
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:1248
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
numer 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:524
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:94
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
static int post_test
Did we finish the test?
static unsigned int num_peers_online
Number of online peers.
struct PendingRequest * pending_req_tail
static void mal_cb(struct RPSPeer *rps_peer)
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:836
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.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
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:1246
static char * stat_type_strings[]
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_memcpy(dst, src, n)
static char * line
Desired phone line (string to be converted to a hash).
static void mal_init_peer(struct RPSPeer *rps_peer)
Initialise only non-mal RPSPeers.
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)
Cancle an issued single info request.
Definition: rps_api.c:1217
It is NOT ok for the test to quit before the timeout triggers.
static void churn(void *cls)
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.
static void mal_pre(struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
Set peers to (non-)malicious before execution.
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:1049
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:1273
int GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1359
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:439
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.
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:988
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:2046
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.
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...
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
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.
const char * name
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.
static void seed_peers(void *cls)
Seed peers.
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
Definition: configuration.c:85
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...
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.
int 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:361
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)
#define GNUNET_YES
Definition: gnunet_common.h:80
PreTest pre_test
Called directly after connecting to the service.
static void trigger_shutdown(void *cls)
static void churn_test_cb(struct RPSPeer *rps_peer)
Starts churn.
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:139
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.
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:1673
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.
static double portion
Portion of malicious peers.
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:965