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 
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
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  unsigned int 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 triggerd 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 static void
1235 seed_peers (void *cls)
1236 {
1237  struct RPSPeer *peer = cls;
1238  unsigned int amount;
1239  unsigned int i;
1240 
1241  // TODO if malicious don't seed mal peers
1242  amount = round (.5 * num_peers);
1243 
1244  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Seeding peers:\n");
1245  for (i = 0; i < amount; i++)
1246  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Seeding %u. peer: %s\n",
1247  i,
1248  GNUNET_i2s (&rps_peer_ids[i]));
1249 
1250  GNUNET_RPS_seed_ids (peer->rps_handle, amount, rps_peer_ids);
1251 }
1252 
1253 
1257 void
1258 info_cb (void *cb_cls,
1259  struct GNUNET_TESTBED_Operation *op,
1260  const struct GNUNET_TESTBED_PeerInformation *pinfo,
1261  const char *emsg)
1262 {
1263  struct OpListEntry *entry = (struct OpListEntry *) cb_cls;
1264 
1265  (void) op;
1266 
1267  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1268  {
1269  return;
1270  }
1271 
1272  if ((NULL == pinfo) || (NULL != emsg))
1273  {
1274  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got Error: %s\n", emsg);
1276  return;
1277  }
1278 
1280  "Peer %u is %s\n",
1281  entry->index,
1282  GNUNET_i2s (pinfo->result.id));
1283 
1284  rps_peer_ids[entry->index] = *(pinfo->result.id);
1285  rps_peers[entry->index].peer_id = &rps_peer_ids[entry->index];
1286 
1289  &rps_peer_ids[entry->index],
1290  &rps_peers[entry->index],
1292  tofile ("/tmp/rps/peer_ids",
1293  "%u\t%s\n",
1294  entry->index,
1295  GNUNET_i2s_full (&rps_peer_ids[entry->index]));
1296 
1297  GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1299  GNUNET_free (entry);
1300 }
1301 
1302 
1312 static void
1314  struct GNUNET_TESTBED_Operation *op,
1315  void *ca_result,
1316  const char *emsg)
1317 {
1318  struct RPSPeer *rps_peer = cls;
1319  struct GNUNET_RPS_Handle *rps = ca_result;
1320 
1321  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1322  {
1323  return;
1324  }
1325 
1326  rps_peer->rps_handle = rps;
1327  rps_peer->online = GNUNET_YES;
1328  num_peers_online++;
1329 
1330  GNUNET_assert (op == rps_peer->op);
1331  if (NULL != emsg)
1332  {
1334  "Failed to connect to RPS service: %s\n",
1335  emsg);
1336  ok = 1;
1338  return;
1339  }
1340 
1342  "Started client successfully (%u)\n",
1343  rps_peer->index);
1344 
1345  cur_test_run.main_test (rps_peer);
1346 }
1347 
1348 
1359 static void *
1361  const struct GNUNET_CONFIGURATION_Handle *cfg)
1362 {
1363  struct GNUNET_RPS_Handle *h;
1364 
1365  h = GNUNET_RPS_connect (cfg);
1366 
1367  if (NULL != cur_test_run.pre_test)
1368  cur_test_run.pre_test (cls, h);
1369 
1370  return h;
1371 }
1372 
1373 
1383 static void *
1385  const struct GNUNET_CONFIGURATION_Handle *cfg)
1386 {
1387  struct RPSPeer *peer = cls;
1388 
1389  peer->stats_h = GNUNET_STATISTICS_create ("rps-profiler", cfg);
1390  return peer->stats_h;
1391 }
1392 
1393 
1400 static void
1402 {
1403  struct RPSPeer *peer = cls;
1404 
1405  // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1406  // (peer->stats_h, "core", "# peers connected",
1407  // stat_iterator, peer));
1408  // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1409  // (peer->stats_h, "nse", "# peers connected",
1410  // stat_iterator, peer));
1411  GNUNET_STATISTICS_destroy (op_result, GNUNET_NO);
1412  peer->stats_h = NULL;
1413 }
1414 
1415 
1426 static void
1427 stat_complete_cb (void *cls,
1428  struct GNUNET_TESTBED_Operation *op,
1429  void *ca_result,
1430  const char *emsg)
1431 {
1432  // struct GNUNET_STATISTICS_Handle *sh = ca_result;
1433  // struct RPSPeer *peer = (struct RPSPeer *) cls;
1434  (void) cls;
1435  (void) op;
1436  (void) ca_result;
1437 
1438  if (NULL != emsg)
1439  {
1440  GNUNET_break (0);
1441  return;
1442  }
1443  // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1444  // (sh, "core", "# peers connected",
1445  // stat_iterator, peer));
1446  // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1447  // (sh, "nse", "# peers connected",
1448  // stat_iterator, peer));
1449 }
1450 
1451 
1459 static void
1461  void *op_result)
1462 {
1463  struct RPSPeer *peer = cls;
1464  struct GNUNET_RPS_Handle *h = op_result;
1465  struct PendingReply *pending_rep;
1466 
1468  "disconnect_adapter (%u)\n",
1469  peer->index);
1470  GNUNET_assert (NULL != peer);
1471  if (NULL != peer->rps_handle)
1472  {
1473  while (NULL != (pending_rep = peer->pending_rep_head))
1474  {
1475  cancel_request (pending_rep);
1476  }
1477  GNUNET_assert (h == peer->rps_handle);
1478  if (NULL != h)
1479  {
1481  h = NULL;
1482  }
1483  peer->rps_handle = NULL;
1484  }
1485 }
1486 
1487 
1488 /***********************************************************************
1489 * Definition of tests
1490 ***********************************************************************/
1491 
1499 static void
1501  uint64_t n,
1502  const struct GNUNET_PeerIdentity *recv_peers)
1503 {
1504  struct RPSPeer *rps_peer;
1505  struct PendingReply *pending_rep = (struct PendingReply *) cls;
1506  unsigned int i;
1507 
1508  rps_peer = pending_rep->rps_peer;
1510  rps_peer->pending_rep_tail,
1511  pending_rep);
1512  rps_peer->num_pending_reps--;
1514  "[%s] got %" PRIu64 " peers:\n",
1515  GNUNET_i2s (rps_peer->peer_id),
1516  n);
1517 
1518  for (i = 0; i < n; i++)
1519  {
1521  "%u: %s\n",
1522  i,
1523  GNUNET_i2s (&recv_peers[i]));
1524 
1525  rps_peer->num_recv_ids++;
1526  }
1527 
1528  if (GNUNET_YES != post_test)
1529  return;
1531  return;
1532  if (0 == evaluate ())
1533  {
1535  "Test succeeded before end of duration\n");
1536  if (NULL != post_test_task)
1537  GNUNET_SCHEDULER_cancel (post_test_task);
1538  post_test_task = GNUNET_SCHEDULER_add_now (&post_test_op, NULL);
1539  GNUNET_assert (NULL != post_test_task);
1540  }
1541 }
1542 
1543 
1544 static void
1545 profiler_reply_handle_info (void *cls,
1546  const struct GNUNET_PeerIdentity *recv_peer,
1547  double probability,
1548  uint32_t num_observed);
1549 
1553 static void
1554 request_peers (void *cls)
1555 {
1556  struct PendingRequest *pending_req = cls;
1557  struct RPSPeer *rps_peer;
1558  struct PendingReply *pending_rep;
1559 
1560  rps_peer = pending_req->rps_peer;
1561  GNUNET_assert (1 <= rps_peer->num_pending_reqs);
1563  rps_peer->pending_req_tail,
1564  pending_req);
1565  rps_peer->num_pending_reqs--;
1566  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1567  return;
1569  "Requesting one peer\n");
1570  pending_rep = GNUNET_new (struct PendingReply);
1571  pending_rep->rps_peer = rps_peer;
1572  // pending_rep->req_handle = GNUNET_RPS_request_peers (rps_peer->rps_handle,
1573  // 1,
1574  // cur_test_run.reply_handle,
1575  // pending_rep);
1576  pending_rep->req_handle = GNUNET_RPS_request_peer_info (rps_peer->rps_handle,
1578  pending_rep);
1580  rps_peer->pending_rep_tail,
1581  pending_rep);
1582  rps_peer->num_pending_reps++;
1583 }
1584 
1585 
1590 void
1592 {
1593  unsigned int i;
1594  struct PendingRequest *pending_req;
1595 
1597  "Scheduling %u - %u missing requests\n",
1598  rps_peer->num_ids_to_request,
1599  rps_peer->num_pending_reqs + rps_peer->num_pending_reps);
1600  GNUNET_assert (rps_peer->num_pending_reqs + rps_peer->num_pending_reps <=
1601  rps_peer->num_ids_to_request);
1602  for (i = rps_peer->num_pending_reqs + rps_peer->num_pending_reps;
1603  i < rps_peer->num_ids_to_request; i++)
1604  {
1605  pending_req = GNUNET_new (struct PendingRequest);
1606  pending_req->rps_peer = rps_peer;
1610  request_peers,
1611  pending_req);
1613  rps_peer->pending_req_tail,
1614  pending_req);
1615  rps_peer->num_pending_reqs++;
1616  }
1617 }
1618 
1619 
1620 void
1622 {
1624  "Cancelling all (pending) requests.\n");
1625  while (NULL != rps_peer->pending_req_head)
1627  GNUNET_assert (0 == rps_peer->num_pending_reqs);
1628  while (NULL != rps_peer->pending_rep_head)
1629  cancel_request (rps_peer->pending_rep_head);
1630  GNUNET_assert (0 == rps_peer->num_pending_reps);
1631 }
1632 
1633 
1634 /***********************************
1635 * MALICIOUS
1636 ***********************************/
1637 
1641 static void
1642 mal_init_peer (struct RPSPeer *rps_peer)
1643 {
1644  if (rps_peer->index >= round (portion * num_peers))
1645  rps_peer->num_ids_to_request = 1;
1646 }
1647 
1648 
1657 static void
1658 mal_pre (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
1659 {
1660  #if ENABLE_MALICIOUS
1661  uint32_t num_mal_peers;
1662 
1663  GNUNET_assert ((1 >= portion) &&
1664  (0 < portion));
1665  num_mal_peers = round (portion * num_peers);
1666 
1667  if (rps_peer->index < num_mal_peers)
1668  {
1670  "%u. peer [%s] of %" PRIu32
1671  " malicious peers turning malicious\n",
1672  rps_peer->index,
1673  GNUNET_i2s (rps_peer->peer_id),
1674  num_mal_peers);
1675 
1676  GNUNET_RPS_act_malicious (h, mal_type, num_mal_peers,
1677  rps_peer_ids, target_peer);
1678  }
1679  #endif /* ENABLE_MALICIOUS */
1680 }
1681 
1682 
1683 static void
1684 mal_cb (struct RPSPeer *rps_peer)
1685 {
1686  uint32_t num_mal_peers;
1687 
1688  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1689  {
1690  return;
1691  }
1692 
1693  #if ENABLE_MALICIOUS
1694  GNUNET_assert ((1 >= portion) &&
1695  (0 < portion));
1696  num_mal_peers = round (portion * num_peers);
1697 
1698  if (rps_peer->index >= num_mal_peers)
1699  { /* It's useless to ask a malicious peer about a random sample -
1700  it's not sampling */
1703  seed_peers, rps_peer);
1704  schedule_missing_requests (rps_peer);
1705  }
1706  #endif /* ENABLE_MALICIOUS */
1707 }
1708 
1709 
1710 /***********************************
1711 * CHURN
1712 ***********************************/
1713 
1714 static void
1715 churn (void *cls);
1716 
1728 static void
1729 churn_test_cb (struct RPSPeer *rps_peer)
1730 {
1731  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1732  {
1733  return;
1734  }
1735 
1736  /* Start churn */
1737  if ((HAVE_CHURN == cur_test_run.have_churn) && (NULL == churn_task))
1738  {
1740  "Starting churn task\n");
1741  churn_task = GNUNET_SCHEDULER_add_delayed (
1743  churn,
1744  NULL);
1745  }
1746  else
1747  {
1749  "Not starting churn task\n");
1750  }
1751 
1752  schedule_missing_requests (rps_peer);
1753 }
1754 
1755 
1756 /***********************************
1757 * PROFILER
1758 ***********************************/
1759 
1767 static void
1768 churn_cb (void *cls,
1769  struct GNUNET_TESTBED_Operation *op,
1770  const char *emsg)
1771 {
1772  // FIXME
1773  struct OpListEntry *entry = cls;
1774 
1775  (void) op;
1776 
1777  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1778  {
1779  return;
1780  }
1781 
1783  if (NULL != emsg)
1784  {
1786  "Failed to start/stop RPS at a peer\n");
1788  return;
1789  }
1790  GNUNET_assert (0 != entry->delta);
1791 
1792  num_peers_online += entry->delta;
1793 
1794  if (PEER_GO_OFFLINE == entry->delta)
1795  { /* Peer hopefully just went offline */
1796  if (GNUNET_YES != rps_peers[entry->index].online)
1797  {
1799  "peer %s was expected to go offline but is still marked as online\n",
1800  GNUNET_i2s (rps_peers[entry->index].peer_id));
1801  GNUNET_break (0);
1802  }
1803  else
1804  {
1806  "peer %s probably went offline as expected\n",
1807  GNUNET_i2s (rps_peers[entry->index].peer_id));
1808  }
1809  rps_peers[entry->index].online = GNUNET_NO;
1810  }
1811 
1812  else if (PEER_GO_ONLINE < entry->delta)
1813  { /* Peer hopefully just went online */
1814  if (GNUNET_NO != rps_peers[entry->index].online)
1815  {
1817  "peer %s was expected to go online but is still marked as offline\n",
1818  GNUNET_i2s (rps_peers[entry->index].peer_id));
1819  GNUNET_break (0);
1820  }
1821  else
1822  {
1824  "peer %s probably went online as expected\n",
1825  GNUNET_i2s (rps_peers[entry->index].peer_id));
1826  if (NULL != cur_test_run.pre_test)
1827  {
1828  cur_test_run.pre_test (&rps_peers[entry->index],
1829  rps_peers[entry->index].rps_handle);
1830  schedule_missing_requests (&rps_peers[entry->index]);
1831  }
1832  }
1833  rps_peers[entry->index].online = GNUNET_YES;
1834  }
1835  else
1836  {
1838  "Invalid value for delta: %i\n", entry->delta);
1839  GNUNET_break (0);
1840  }
1841 
1842  GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1843  rps_peers[entry->index].entry_op_manage = NULL;
1844  GNUNET_free (entry);
1845  // if (num_peers_in_round[current_round] == peers_running)
1846  // run_round ();
1847 }
1848 
1849 
1858 static void
1859 manage_service_wrapper (unsigned int i, unsigned int j,
1860  enum PEER_ONLINE_DELTA delta,
1861  double prob_go_on_off)
1862 {
1863  struct OpListEntry *entry = NULL;
1864  uint32_t prob;
1865 
1866  /* make sure that management operation is not already scheduled */
1867  if (NULL != rps_peers[j].entry_op_manage)
1868  {
1869  return;
1870  }
1871 
1873  UINT32_MAX);
1875  "%u. selected peer (%u: %s) is %s.\n",
1876  i,
1877  j,
1878  GNUNET_i2s (rps_peers[j].peer_id),
1879  (PEER_GO_ONLINE == delta) ? "online" : "offline");
1880  if (prob < prob_go_on_off * UINT32_MAX)
1881  {
1883  "%s goes %s\n",
1884  GNUNET_i2s (rps_peers[j].peer_id),
1885  (PEER_GO_OFFLINE == delta) ? "offline" : "online");
1886 
1887  if (PEER_GO_OFFLINE == delta)
1888  cancel_pending_req_rep (&rps_peers[j]);
1889  entry = make_oplist_entry ();
1890  entry->delta = delta;
1891  entry->index = j;
1892  entry->op = GNUNET_TESTBED_peer_manage_service (NULL,
1893  testbed_peers[j],
1894  "rps",
1895  &churn_cb,
1896  entry,
1897  (PEER_GO_OFFLINE == delta) ?
1898  0 : 1);
1899  rps_peers[j].entry_op_manage = entry;
1900  }
1901 }
1902 
1903 
1904 static void
1905 churn (void *cls)
1906 {
1907  unsigned int i;
1908  unsigned int j;
1909  double portion_online;
1910  unsigned int *permut;
1911  double prob_go_offline;
1912  double portion_go_online;
1913  double portion_go_offline;
1914 
1915  (void) cls;
1916 
1917  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1918  {
1919  return;
1920  }
1922  "Churn function executing\n");
1923 
1924  churn_task = NULL; /* Should be invalid by now */
1925 
1926  /* Compute the probability for an online peer to go offline
1927  * this round */
1928  portion_online = num_peers_online * 1.0 / num_peers;
1930  "Portion online: %f\n",
1931  portion_online);
1932  portion_go_online = ((1 - portion_online) * .5 * .66);
1934  "Portion that should go online: %f\n",
1935  portion_go_online);
1936  portion_go_offline = (portion_online + portion_go_online) - .75;
1938  "Portion that probably goes offline: %f\n",
1939  portion_go_offline);
1940  prob_go_offline = portion_go_offline / (portion_online * .5);
1942  "Probability of a selected online peer to go offline: %f\n",
1943  prob_go_offline);
1944 
1946  (unsigned int) num_peers);
1947 
1948  /* Go over 50% randomly chosen peers */
1949  for (i = 0; i < .5 * num_peers; i++)
1950  {
1951  j = permut[i];
1952 
1953  /* If online, shut down with certain probability */
1954  if (GNUNET_YES == rps_peers[j].online)
1955  {
1956  manage_service_wrapper (i, j, -1, prob_go_offline);
1957  }
1958 
1959  /* If offline, restart with certain probability */
1960  else if (GNUNET_NO == rps_peers[j].online)
1961  {
1962  manage_service_wrapper (i, j, 1, 0.66);
1963  }
1964  }
1965 
1966  GNUNET_free (permut);
1967 
1968  churn_task = GNUNET_SCHEDULER_add_delayed (
1970  churn,
1971  NULL);
1972 }
1973 
1974 
1978 static void
1979 profiler_init_peer (struct RPSPeer *rps_peer)
1980 {
1982  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer shall request %i peers\n",
1983  rps_peer->num_ids_to_request);
1984 }
1985 
1986 
1994 static void
1996  uint64_t n,
1997  const struct GNUNET_PeerIdentity *recv_peers)
1998 {
1999  struct RPSPeer *rps_peer;
2000  struct RPSPeer *rcv_rps_peer;
2001  char file_name_buf[128];
2002  char file_name_dh_buf[128];
2003  char file_name_dhr_buf[128];
2004  char file_name_dhru_buf[128];
2005  char *file_name = file_name_buf;
2006  char *file_name_dh = file_name_dh_buf;
2007  char *file_name_dhr = file_name_dhr_buf;
2008  char *file_name_dhru = file_name_dhru_buf;
2009  unsigned int i;
2010  struct PendingReply *pending_rep = (struct PendingReply *) cls;
2011 
2012  pending_rep->req_handle = NULL;
2013  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
2014  rps_peer = pending_rep->rps_peer;
2015  (void) GNUNET_asprintf (&file_name,
2016  "/tmp/rps/received_ids-%u",
2017  rps_peer->index);
2018 
2019  (void) GNUNET_asprintf (&file_name_dh,
2020  "/tmp/rps/diehard_input-%u",
2021  rps_peer->index);
2022  (void) GNUNET_asprintf (&file_name_dhr,
2023  "/tmp/rps/diehard_input_raw-%u",
2024  rps_peer->index);
2025  (void) GNUNET_asprintf (&file_name_dhru,
2026  "/tmp/rps/diehard_input_raw_aligned-%u",
2027  rps_peer->index);
2029  "[%s] got %" PRIu64 " peers:\n",
2030  GNUNET_i2s (rps_peer->peer_id),
2031  n);
2032  for (i = 0; i < n; i++)
2033  {
2035  "%u: %s\n",
2036  i,
2037  GNUNET_i2s (&recv_peers[i]));
2038  tofile (file_name,
2039  "%s\n",
2040  GNUNET_i2s_full (&recv_peers[i]));
2041  rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get (peer_map, &recv_peers[i]);
2042  GNUNET_assert (NULL != rcv_rps_peer);
2043  tofile (file_name_dh,
2044  "%" PRIu32 "\n",
2045  (uint32_t) rcv_rps_peer->index);
2046 #ifdef TO_FILE
2047  to_file_raw (file_name_dhr,
2048  (char *) &rcv_rps_peer->index,
2049  sizeof(uint32_t));
2050  to_file_raw_unaligned (file_name_dhru,
2051  (char *) &rcv_rps_peer->index,
2052  sizeof(uint32_t),
2053  bits_needed);
2054 #endif /* TO_FILE */
2055  }
2056  default_reply_handle (cls, n, recv_peers);
2057 }
2058 
2059 
2067 static void
2069  const struct GNUNET_PeerIdentity *recv_peer,
2070  double probability,
2071  uint32_t num_observed)
2072 {
2073  struct RPSPeer *rps_peer;
2074  struct RPSPeer *rcv_rps_peer;
2075  char file_name_buf[128];
2076  char file_name_dh_buf[128];
2077  char file_name_dhr_buf[128];
2078  char file_name_dhru_buf[128];
2079  char *file_name = file_name_buf;
2080  char *file_name_dh = file_name_dh_buf;
2081  char *file_name_dhr = file_name_dhr_buf;
2082  char *file_name_dhru = file_name_dhru_buf;
2083  unsigned int i;
2084  struct PendingReply *pending_rep = (struct PendingReply *) cls;
2085 
2086  pending_rep->req_handle = NULL;
2087  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
2088  rps_peer = pending_rep->rps_peer;
2089  (void) GNUNET_asprintf (&file_name,
2090  "/tmp/rps/received_ids-%u",
2091  rps_peer->index);
2092 
2093  (void) GNUNET_asprintf (&file_name_dh,
2094  "/tmp/rps/diehard_input-%u",
2095  rps_peer->index);
2096  (void) GNUNET_asprintf (&file_name_dhr,
2097  "/tmp/rps/diehard_input_raw-%u",
2098  rps_peer->index);
2099  (void) GNUNET_asprintf (&file_name_dhru,
2100  "/tmp/rps/diehard_input_raw_aligned-%u",
2101  rps_peer->index);
2103  "[%s] got peer with info:\n",
2104  GNUNET_i2s (rps_peer->peer_id));
2106  " %s\n",
2107  GNUNET_i2s (recv_peer));
2108  tofile (file_name,
2109  "%s %d %" PRIu32 " \n",
2110  GNUNET_i2s_full (recv_peer),
2111  probability,
2112  num_observed);
2113  rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get (peer_map, recv_peer);
2114  GNUNET_assert (NULL != rcv_rps_peer);
2115  tofile (file_name_dh,
2116  "%" PRIu32 "\n",
2117  (uint32_t) rcv_rps_peer->index);
2118 #ifdef TO_FILE
2119  to_file_raw (file_name_dhr,
2120  (char *) &rcv_rps_peer->index,
2121  sizeof(uint32_t));
2122  to_file_raw_unaligned (file_name_dhru,
2123  (char *) &rcv_rps_peer->index,
2124  sizeof(uint32_t),
2125  bits_needed);
2126 #endif /* TO_FILE */
2127  default_reply_handle (cls, 1, recv_peer);
2128 }
2129 
2130 
2131 static void
2132 profiler_cb (struct RPSPeer *rps_peer)
2133 {
2134  if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
2135  {
2136  return;
2137  }
2138 
2139  /* Start churn */
2140  if ((HAVE_CHURN == cur_test_run.have_churn) && (NULL == churn_task))
2141  {
2143  "Starting churn task\n");
2144  churn_task = GNUNET_SCHEDULER_add_delayed (
2146  churn,
2147  NULL);
2148  }
2149  else
2150  {
2152  "Not starting churn task\n");
2153  }
2154 
2155  /* Only request peer ids at one peer.
2156  * (It's the before-last because last one is target of the focussed attack.)
2157  */
2158  if (0 < rps_peer->num_ids_to_request)
2159  schedule_missing_requests (rps_peer);
2160 }
2161 
2162 
2172 static int
2173 file_name_cb (void *cls, const char *filename)
2174 {
2175  if (NULL != strstr (filename, "sampler_el"))
2176  {
2177  struct RPS_SamplerElement *s_elem;
2178  struct GNUNET_CRYPTO_AuthKey auth_key;
2179  const char *key_char;
2180  uint32_t i;
2181  (void) cls;
2182 
2183  key_char = filename + 20; /* Length of "/tmp/rps/sampler_el-" */
2184  tofile (filename, "--------------------------\n");
2185 
2186  auth_key = string_to_auth_key (key_char);
2187  s_elem = RPS_sampler_elem_create ();
2188  RPS_sampler_elem_set (s_elem, auth_key);
2189 
2190  for (i = 0; i < num_peers; i++)
2191  {
2192  RPS_sampler_elem_next (s_elem, &rps_peer_ids[i]);
2193  }
2194  RPS_sampler_elem_destroy (s_elem);
2195  }
2196  return GNUNET_OK;
2197 }
2198 
2199 
2205 static int
2207 {
2208 #ifdef TO_FILE
2209  /* Compute perfect sample for each sampler element */
2210  if (-1 == GNUNET_DISK_directory_scan ("/tmp/rps/", file_name_cb, NULL))
2211  {
2212  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Scan of directory failed\n");
2213  }
2214 #endif /* TO_FILE */
2215 
2216  return evaluate ();
2217 }
2218 
2219 
2227 static int
2228 is_in_view (uint32_t a, uint32_t b)
2229 {
2230  uint32_t i;
2231 
2232  for (i = 0; i < rps_peers[a].cur_view_count; i++)
2233  {
2234  if (0 == memcmp (rps_peers[b].peer_id,
2235  &rps_peers[a].cur_view[i],
2236  sizeof(struct GNUNET_PeerIdentity)))
2237  {
2238  return GNUNET_YES;
2239  }
2240  }
2241  return GNUNET_NO;
2242 }
2243 
2244 
2245 static uint32_t
2247 {
2248  uint32_t i;
2249 
2250  for (i = 0; i < num_peers; i++)
2251  {
2252  if (0 == memcmp (pid,
2253  rps_peers[i].peer_id,
2254  sizeof(struct GNUNET_PeerIdentity)))
2255  {
2256  return i;
2257  }
2258  }
2259  // return 0; /* Should not happen - make compiler happy */
2261  "No known _PeerIdentity %s!\n",
2262  GNUNET_i2s_full (pid));
2263  GNUNET_assert (0);
2264 }
2265 
2266 
2275 static uint32_t
2276 count_containing_views (uint32_t a, uint32_t b)
2277 {
2278  uint32_t i;
2279  uint32_t peer_idx;
2280  uint32_t count = 0;
2281 
2282  for (i = 0; i < rps_peers[a].cur_view_count; i++)
2283  {
2284  peer_idx = get_idx_of_pid (&rps_peers[a].cur_view[i]);
2285  if (GNUNET_YES == is_in_view (peer_idx, b))
2286  {
2287  count++;
2288  }
2289  }
2290  return count;
2291 }
2292 
2293 
2300 static void
2301 compute_probabilities (uint32_t peer_idx)
2302 {
2303  // double probs[num_peers] = { 0 };
2304  double probs[num_peers];
2305  double probs_hist[num_peers]; /* Probability respecting the history */
2306  size_t probs_as_str_size = (num_peers * 10 + 2) * sizeof(char);
2307  char *probs_as_str = GNUNET_malloc (probs_as_str_size);
2308  char *probs_as_str_cpy;
2309  uint32_t i;
2310  double prob_push;
2311  double prob_pull;
2312  uint32_t view_size;
2313  uint32_t cont_views;
2314  uint32_t number_of_being_in_pull_events;
2315  int tmp;
2316  double sum_non_zero_prob = 0;
2317  double sum_non_zero_prob_hist = 0;
2318 
2320  "Computing probabilities for peer %" PRIu32 "\n", peer_idx);
2321  /* Firstly without knowledge of old views */
2322  for (i = 0; i < num_peers; i++)
2323  {
2325  "\tfor peer %" PRIu32 ":\n", i);
2326  view_size = rps_peers[i].cur_view_count;
2328  "\t\tview_size: %" PRIu32 "\n", view_size);
2329  /* For peer i the probability of being sampled is
2330  * evenly distributed among all possibly observed peers. */
2331  /* We could have observed a peer in three cases:
2332  * 1. peer sent a push
2333  * 2. peer was contained in a pull reply
2334  * 3. peer was in history (sampler) - ignored for now */
2335  /* 1. Probability of having received a push from peer i */
2336  if ((GNUNET_YES == is_in_view (i, peer_idx)) &&
2337  (1 <= (0.45 * view_size)))
2338  {
2339  if (0 == binom (view_size, 0.45 * view_size))
2340  prob_push = 0;
2341  else
2342  {
2343  prob_push = 1.0 * binom (0.45 * view_size, 1)
2344  /
2345  binom (view_size, 0.45 * view_size);
2346  }
2348  "\t\t%" PRIu32 " is in %" PRIu32 "'s view, prob: %f\n",
2349  peer_idx,
2350  i,
2351  prob_push);
2353  "\t\tposs choices from view: %" PRIu32 ", containing i: %"
2354  PRIu32 "\n",
2355  binom (view_size, 0.45 * view_size),
2356  binom (0.45 * view_size, 1));
2357  }
2358  else
2359  {
2360  prob_push = 0;
2362  "\t\t%" PRIu32 " is not in %" PRIu32 "'s view, prob: 0\n",
2363  peer_idx,
2364  i);
2365  }
2366  /* 2. Probability of peer i being contained in pulls */
2367  view_size = rps_peers[peer_idx].cur_view_count;
2368  cont_views = count_containing_views (peer_idx, i);
2369  number_of_being_in_pull_events =
2370  (binom (view_size, 0.45 * view_size)
2371  - binom (view_size - cont_views, 0.45 * view_size));
2372  if (0 != number_of_being_in_pull_events)
2373  {
2374  prob_pull = number_of_being_in_pull_events
2375  /
2376  (1.0 * binom (view_size, 0.45 * view_size));
2377  }
2378  else
2379  {
2380  prob_pull = 0;
2381  }
2382  probs[i] = prob_push + prob_pull - (prob_push * prob_pull);
2384  "\t\t%" PRIu32 " has %" PRIu32 " of %" PRIu32
2385  " peers in its view who know %" PRIu32 " prob: %f\n",
2386  peer_idx,
2387  cont_views,
2388  view_size,
2389  i,
2390  prob_pull);
2392  "\t\tnumber of possible pull combinations: %" PRIu32 "\n",
2393  binom (view_size, 0.45 * view_size));
2395  "\t\tnumber of possible pull combinations without %" PRIu32
2396  ": %" PRIu32 "\n",
2397  i,
2398  binom (view_size - cont_views, 0.45 * view_size));
2400  "\t\tnumber of possible pull combinations with %" PRIu32
2401  ": %" PRIu32 "\n",
2402  i,
2403  number_of_being_in_pull_events);
2404 
2405  probs_hist[i] = 0.9 * rps_peers[peer_idx].eval_probs_cache[i] + probs[i];
2406  rps_peers[peer_idx].eval_probs_cache[i] = probs_hist[i];
2407 
2408  sum_non_zero_prob += probs[i];
2409  sum_non_zero_prob_hist += probs_hist[i];
2410  }
2411  /* normalize */
2412  if (0 != sum_non_zero_prob)
2413  {
2414  for (i = 0; i < num_peers; i++)
2415  {
2416  probs[i] = probs[i] * (1.0 / sum_non_zero_prob);
2417  }
2418  }
2419  if (0 != sum_non_zero_prob_hist)
2420  {
2421  for (i = 0; i < num_peers; i++)
2422  {
2423  probs_hist[i] = probs_hist[i] * (1.0 / sum_non_zero_prob_hist);
2424  }
2425  }
2426 
2427  /* str repr */
2428  for (i = 0; i < num_peers; i++)
2429  {
2430  probs_as_str_cpy = GNUNET_strndup (probs_as_str, probs_as_str_size);
2431  tmp = GNUNET_snprintf (probs_as_str,
2432  probs_as_str_size,
2433  "%s %7.6f", probs_as_str_cpy, probs[i]);
2434  GNUNET_free (probs_as_str_cpy);
2435  GNUNET_assert (0 <= tmp);
2436  }
2437 
2438  to_file_w_len (rps_peers[peer_idx].file_name_probs,
2439  probs_as_str_size,
2440  probs_as_str);
2441 
2442  probs_as_str[0] = '\0';
2443  for (i = 0; i < num_peers; i++)
2444  {
2445  probs_as_str_cpy = GNUNET_strndup (probs_as_str, probs_as_str_size);
2446  tmp = GNUNET_snprintf (probs_as_str,
2447  probs_as_str_size,
2448  "%s %7.6f", probs_as_str_cpy, probs_hist[i]);
2449  GNUNET_free (probs_as_str_cpy);
2450  GNUNET_assert (0 <= tmp);
2451  }
2452 
2453  to_file_w_len (rps_peers[peer_idx].file_name_probs_hist,
2454  probs_as_str_size,
2455  probs_as_str);
2456  GNUNET_free (probs_as_str);
2457 }
2458 
2459 
2469 static uint32_t
2470 count_peer_in_views_2 (uint32_t peer_idx)
2471 {
2472  uint32_t i, j;
2473  uint32_t count = 0;
2474 
2475  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2476  {
2477  for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2478  {
2479  if (0 == memcmp (rps_peers[peer_idx].peer_id,
2480  &rps_peers[i].cur_view[j],
2481  sizeof(struct GNUNET_PeerIdentity)))
2482  {
2483  count++;
2484  break;
2485  }
2486  }
2487  }
2488  rps_peers[peer_idx].count_in_views = count;
2489  return count;
2490 }
2491 
2492 
2493 static uint32_t
2495 {
2496  uint32_t i;
2497 
2498  view_sizes = 0;
2499  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2500  {
2501  view_sizes += rps_peers[i].cur_view_count;
2502  }
2503  return view_sizes;
2504 }
2505 
2506 
2507 static void
2508 count_peer_in_views (uint32_t *count_peers)
2509 {
2510  uint32_t i, j;
2511 
2512  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2513  {
2514  for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2515  {
2516  if (0 == memcmp (rps_peers[i].peer_id,
2517  &rps_peers[i].cur_view[j],
2518  sizeof(struct GNUNET_PeerIdentity)))
2519  {
2520  count_peers[i]++;
2521  }
2522  }
2523  }
2524 }
2525 
2526 
2527 void
2529 {
2530  uint32_t i;
2531  /* ith entry represents the numer of occurrences in other peer's views */
2532  uint32_t *count_peers = GNUNET_new_array (num_peers, uint32_t);
2533  uint32_t views_total_size;
2534  double expected;
2535  /* deviation from expected number of peers */
2536  double *deviation = GNUNET_new_array (num_peers, double);
2537 
2538  views_total_size = 0;
2539  expected = 0;
2540 
2541  /* For each peer count its representation in other peer's views*/
2542  for (i = 0; i < num_peers; i++) /* Peer to count */
2543  {
2544  views_total_size += rps_peers[i].cur_view_count;
2545  count_peer_in_views (count_peers);
2547  "Counted representation of %" PRIu32 "th peer [%s]: %" PRIu32
2548  "\n",
2549  i,
2550  GNUNET_i2s (rps_peers[i].peer_id),
2551  count_peers[i]);
2552  }
2553 
2555  "size of all views combined: %" PRIu32 "\n",
2556  views_total_size);
2557  expected = ((double) 1 / num_peers) * views_total_size;
2559  "Expected number of occurrences of each peer in all views: %f\n",
2560  expected);
2561  for (i = 0; i < num_peers; i++) /* Peer to count */
2562  {
2563  deviation[i] = expected - count_peers[i];
2565  "Deviation from expectation: %f\n", deviation[i]);
2566  }
2567  GNUNET_free (count_peers);
2568  GNUNET_free (deviation);
2569 }
2570 
2571 
2572 void
2574 {
2575  uint32_t i;
2576 
2577  for (i = 0; i < num_peers; i++) /* Peer to count */
2578  {
2580  "View size of %" PRIu32 ". [%s] is %" PRIu32 "\n",
2581  i,
2582  GNUNET_i2s (rps_peers[i].peer_id),
2583  rps_peers[i].cur_view_count);
2584  }
2585 }
2586 
2587 
2588 void
2590 {
2591  compute_diversity ();
2592  print_view_sizes ();
2593 }
2594 
2595 
2596 void
2597 view_update_cb (void *cls,
2598  uint64_t view_size,
2599  const struct GNUNET_PeerIdentity *peers)
2600 {
2602  "View was updated (%" PRIu64 ")\n", view_size);
2603  struct RPSPeer *rps_peer = (struct RPSPeer *) cls;
2604  to_file ("/tmp/rps/view_sizes.txt",
2605  "%" PRIu64 " %" PRIu32 "",
2606  rps_peer->index,
2607  view_size);
2608  for (uint64_t i = 0; i < view_size; i++)
2609  {
2611  "\t%s\n", GNUNET_i2s (&peers[i]));
2612  }
2613  GNUNET_array_grow (rps_peer->cur_view,
2614  rps_peer->cur_view_count,
2615  view_size);
2616  // *rps_peer->cur_view = *peers;
2617  GNUNET_memcpy (rps_peer->cur_view,
2618  peers,
2619  view_size * sizeof(struct GNUNET_PeerIdentity));
2620  to_file ("/tmp/rps/count_in_views.txt",
2621  "%" PRIu64 " %" PRIu32 "",
2622  rps_peer->index,
2623  count_peer_in_views_2 (rps_peer->index));
2625  if (0 != view_size)
2626  {
2627  to_file ("/tmp/rps/repr.txt",
2628  "%" PRIu64 /* index */
2629  " %" PRIu32 /* occurrence in views */
2630  " %" PRIu32 /* view sizes */
2631  " %f" /* fraction of repr in views */
2632  " %f" /* average view size */
2633  " %f" /* prob of occurrence in view slot */
2634  " %f" "", /* exp frac of repr in views */
2635  rps_peer->index,
2636  count_peer_in_views_2 (rps_peer->index),
2637  view_sizes,
2638  count_peer_in_views_2 (rps_peer->index) / (view_size * 1.0), /* fraction of representation in views */
2639  view_sizes / (view_size * 1.0), /* average view size */
2640  1.0 / view_size, /* prob of occurrence in view slot */
2641  (1.0 / view_size) * (view_sizes / view_size) /* expected fraction of repr in views */
2642  );
2643  }
2644  compute_probabilities (rps_peer->index);
2646 }
2647 
2648 
2649 static void
2650 pre_profiler (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
2651 {
2652  rps_peer->file_name_probs =
2653  store_prefix_file_name (rps_peer->index, "probs");
2654  rps_peer->file_name_probs_hist =
2655  store_prefix_file_name (rps_peer->index, "probs_hist");
2656  GNUNET_RPS_view_request (h, 0, view_update_cb, rps_peer);
2657 }
2658 
2659 
2660 void
2662 {
2663  uint64_t sums[STAT_TYPE_MAX] = { 0 };
2664 
2665  for (uint32_t i = 0; i < num_peers; i++)
2666  {
2667  to_file ("/tmp/rps/final_stats.csv",
2668  "%" PRIu32 ", " /* index */
2669  "%s, %" /* id */
2670  PRIu64 ", %" /* rounds */
2671  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %"
2672  PRIu64 ", %" /* blocking */
2673  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* issued */
2674  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* sent */
2675  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %"
2676  PRIu64 ", %" /* recv */
2677  PRIu64 ", %" /* view size */
2678  PRIu64 ", %" /* known peers */
2679  PRIu64 ", %" /* valid peers */
2680  PRIu64 ", %" /* learned peers */
2681  PRIu64 ", %" /* pending online checks */
2682  PRIu64 ", %" /* unrequested pull replies */
2683  PRIu64 ", %" /* peers in push map */
2684  PRIu64 ", %" /* peers in pull map */
2685  PRIu64 ", %" /* peers in view */
2686  PRIu64 "\n" /* view size aim */,
2687  i,
2688  GNUNET_i2s (rps_peers[i].peer_id),
2689  rps_peers[i].stats[STAT_TYPE_ROUNDS],
2690  rps_peers[i].stats[STAT_TYPE_BLOCKS],
2691  rps_peers[i].stats[STAT_TYPE_BLOCKS_MANY_PUSH],
2692  rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PUSH],
2693  rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PULL],
2696  rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND],
2697  rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND_MH],
2698  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ],
2699  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ_MH],
2700  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REP],
2701  rps_peers[i].stats[STAT_TYPE_SENT_PUSH_SEND],
2702  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ],
2703  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ_MH],
2704  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REP],
2705  rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND],
2706  rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND_MH],
2707  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ],
2708  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ_MH],
2709  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP_MH],
2710  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP],
2711  rps_peers[i].stats[STAT_TYPE_VIEW_SIZE],
2712  rps_peers[i].stats[STAT_TYPE_KNOWN_PEERS],
2713  rps_peers[i].stats[STAT_TYPE_VALID_PEERS],
2714  rps_peers[i].stats[STAT_TYPE_LEARND_PEERS],
2715  rps_peers[i].stats[STAT_TYPE_PENDING_ONLINE_CHECKS],
2717  rps_peers[i].stats[STAT_TYPE_PEERS_IN_PUSH_MAP],
2718  rps_peers[i].stats[STAT_TYPE_PEERS_IN_PULL_MAP],
2719  rps_peers[i].stats[STAT_TYPE_PEERS_IN_VIEW],
2720  rps_peers[i].stats[STAT_TYPE_VIEW_SIZE_AIM]);
2721  for (enum STAT_TYPE stat_type = STAT_TYPE_ROUNDS;
2723  stat_type++)
2724  {
2725  sums[stat_type] += rps_peers[i].stats[stat_type];
2726  }
2727  }
2728  to_file ("/tmp/rps/final_stats.dat",
2729  "SUM %"
2730  PRIu64 " %" /* rounds */
2731  PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
2732  " %" /* blocking */
2733  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* issued */
2734  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* sent */
2735  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %"
2736  PRIu64 ", %" /* recv */
2737  PRIu64 ", %" /* view size */
2738  PRIu64 ", %" /* known peers */
2739  PRIu64 ", %" /* valid peers */
2740  PRIu64 ", %" /* learned peers */
2741  PRIu64 ", %" /* pending online checks */
2742  PRIu64 ", %" /* unrequested pull replies */
2743  PRIu64 ", %" /* peers in push map */
2744  PRIu64 ", %" /* peers in pull map */
2745  PRIu64 ", %" /* peers in view */
2746  PRIu64 "\n" /* view size aim */,
2747  sums[STAT_TYPE_ROUNDS],
2748  sums[STAT_TYPE_BLOCKS],
2769  sums[STAT_TYPE_VIEW_SIZE],
2770  sums[STAT_TYPE_KNOWN_PEERS],
2771  sums[STAT_TYPE_VALID_PEERS],
2772  sums[STAT_TYPE_LEARND_PEERS],
2778  sums[STAT_TYPE_VIEW_SIZE_AIM]);
2779 }
2780 
2781 
2793 void
2795  int success)
2796 {
2797  struct STATcls *stat_cls = (struct STATcls *) cls;
2798  struct RPSPeer *rps_peer = stat_cls->rps_peer;
2799 
2800  rps_peer->h_stat_get[stat_cls->stat_type] = NULL;
2801  if (GNUNET_OK == success)
2802  {
2803  /* set flag that we we got the value */
2804  rps_peer->stat_collected_flags |= BIT (stat_cls->stat_type);
2805  }
2806  else
2807  {
2809  "Peer %u did not receive statistics value\n",
2810  rps_peer->index);
2811  GNUNET_free (stat_cls);
2812  GNUNET_break (0);
2813  return;
2814  }
2815 
2816  if ((NULL != rps_peer->stat_op) &&
2818  rps_peer)) )
2819  {
2821  }
2822 
2823  write_final_stats ();
2825  {
2826  // write_final_stats ();
2827  GNUNET_free (stat_cls);
2829  "Shutting down\n");
2831  }
2832  else
2833  {
2834  GNUNET_free (stat_cls);
2835  }
2836 }
2837 
2838 
2849 int
2850 stat_iterator (void *cls,
2851  const char *subsystem,
2852  const char *name,
2853  uint64_t value,
2854  int is_persistent)
2855 {
2856  const struct STATcls *stat_cls = (const struct STATcls *) cls;
2857  struct RPSPeer *rps_peer = (struct RPSPeer *) stat_cls->rps_peer;
2858  enum STAT_TYPE stat_type;
2859 
2860  (void) subsystem;
2861  (void) is_persistent;
2862 
2864  "Got stat value: %s - %" PRIu64 " (%u)\n",
2865  name,
2866  value,
2867  rps_peer->index);
2868  to_file (rps_peer->file_name_stats,
2869  "%s: %" PRIu64 "\n",
2870  name,
2871  value);
2872  stat_type = stat_str_2_type (name);
2875  rps_peer->stats[stat_type] = value;
2876  return GNUNET_OK;
2877 }
2878 
2879 
2880 void
2881 post_profiler (struct RPSPeer *rps_peer)
2882 {
2884  {
2885  return;
2886  }
2887 
2889  "Going to request statistic values with mask 0x%" PRIx32 "\n",
2891 
2892  struct STATcls *stat_cls;
2893  uint32_t stat_type;
2894  for (stat_type = STAT_TYPE_ROUNDS;
2895  stat_type < STAT_TYPE_MAX;
2896  stat_type++)
2897  {
2898  if (BIT (stat_type) & cur_test_run.stat_collect_flags)
2899  {
2900  stat_cls = GNUNET_malloc (sizeof(struct STATcls));
2901  stat_cls->rps_peer = rps_peer;
2902  stat_cls->stat_type = stat_type;
2903  rps_peer->file_name_stats =
2904  store_prefix_file_name (rps_peer->peer_id, "stats");
2905  rps_peer->h_stat_get[stat_type] =
2906  GNUNET_STATISTICS_get (rps_peer->stats_h,
2907  "rps",
2908  stat_type_strings [stat_type],
2910  stat_iterator,
2911  (struct STATcls *) stat_cls);
2912  GNUNET_assert (NULL != rps_peer->h_stat_get);
2914  "Requested statistics for %s (peer %" PRIu32 ")\n",
2915  stat_type_strings [stat_type],
2916  rps_peer->index);
2917  }
2918  }
2919  GNUNET_free (rps_peer->eval_probs_cache);
2920 }
2921 
2922 
2923 /***********************************************************************
2924 * /Definition of tests
2925 ***********************************************************************/
2926 
2927 
2940 static void
2941 test_run (void *cls,
2942  struct GNUNET_TESTBED_RunHandle *h,
2943  unsigned int n_peers,
2944  struct GNUNET_TESTBED_Peer **peers,
2945  unsigned int links_succeeded,
2946  unsigned int links_failed)
2947 {
2948  unsigned int i;
2949  struct OpListEntry *entry;
2950 
2951  (void) cls;
2952  (void) h;
2953  (void) links_failed;
2954 
2955  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RUN was called\n");
2956 
2957  /* Check whether we timed out */
2958  if ((n_peers != num_peers) ||
2959  (NULL == peers) ||
2960  (0 == links_succeeded) )
2961  {
2963  "Going down due to args (eg. timeout)\n");
2964  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tn_peers: %u\n", n_peers);
2965  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tnum_peers: %" PRIu32 "\n",
2966  num_peers);
2967  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tpeers: %p\n", peers);
2968  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tlinks_succeeded: %u\n",
2969  links_succeeded);
2970  ok = 1;
2972  return;
2973  }
2974 
2975 
2976  /* Initialize peers */
2977  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "going to initialise peers\n");
2978  testbed_peers = peers;
2979  num_peers_online = 0;
2980  for (i = 0; i < num_peers; i++)
2981  {
2982  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "initialising %u\n", i);
2983  entry = make_oplist_entry ();
2984  entry->index = i;
2985  rps_peers[i].index = i;
2986  if (NULL != cur_test_run.init_peer)
2987  cur_test_run.init_peer (&rps_peers[i]);
2989  {
2990  rps_peers->cur_view_count = 0;
2991  rps_peers->cur_view = NULL;
2992  }
2993  entry->op = GNUNET_TESTBED_peer_get_information (peers[i],
2995  &info_cb,
2996  entry);
2997  }
2998 
2999  /* Bring peers up */
3000  GNUNET_assert (num_peers == n_peers);
3001  for (i = 0; i < n_peers; i++)
3002  {
3003  rps_peers[i].index = i;
3004  rps_peers[i].op =
3005  GNUNET_TESTBED_service_connect (&rps_peers[i],
3006  peers[i],
3007  "rps",
3009  &rps_peers[i],
3012  &rps_peers[i]);
3013  /* Connect all peers to statistics service */
3015  {
3017  "Connecting to statistics service\n");
3018  rps_peers[i].stat_op =
3020  peers[i],
3021  "statistics",
3023  &rps_peers[i],
3026  &rps_peers[i]);
3027  }
3028  }
3029 
3030  if (NULL != churn_task)
3031  GNUNET_SCHEDULER_cancel (churn_task);
3032  post_test_task = GNUNET_SCHEDULER_add_delayed (duration, &post_test_op, NULL);
3033  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "timeout for shutdown is %lu\n",
3034  timeout.rel_value_us / 1000000);
3035  shutdown_task = GNUNET_SCHEDULER_add_delayed (timeout,
3037  NULL);
3039 }
3040 
3041 
3048 static void
3049 run (void *cls,
3050  char *const *args,
3051  const char *cfgfile,
3052  const struct GNUNET_CONFIGURATION_Handle *cfg)
3053 {
3054  // int ret_value;
3055  (void) cls;
3056  (void) args;
3057  (void) cfgfile;
3058 
3059  /* Defaults for tests */
3060  churn_task = NULL;
3061 
3062  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n");
3063  cur_test_run.name = "test-rps-profiler";
3064  if (0 == num_peers)
3065  num_peers = 10;
3066  mal_type = 3;
3068  // cur_test_run.pre_test = mal_pre;
3075  if (0 == cur_test_run.num_requests)
3077  // cur_test_run.have_churn = HAVE_CHURN;
3082  | BIT (STAT_TYPE_BLOCKS)
3114 
3115  /* 'Clean' directory */
3116  (void) GNUNET_DISK_directory_remove ("/tmp/rps/");
3117  GNUNET_DISK_directory_create ("/tmp/rps/");
3118  if (0 == duration.rel_value_us)
3119  {
3120  if (0 == timeout.rel_value_us)
3121  {
3124  (90 * 1.2)
3125  + (0.01 * num_peers));
3126  }
3127  else
3128  {
3130  (timeout.rel_value_us / 1000000)
3131  * 0.75);
3132  }
3133  }
3134  else
3135  {
3136  if (0 == timeout.rel_value_us)
3137  {
3140  / 1000000)
3141  * 1.2) + (0.01 * num_peers));
3142  }
3143  }
3146  "duration is %lus\n",
3147  duration.rel_value_us / 1000000);
3149  "timeout is %lus\n",
3150  timeout.rel_value_us / 1000000);
3151 
3152  /* Compute number of bits for representing largest peer id */
3153  for (bits_needed = 1; (1 << bits_needed) < num_peers; bits_needed++)
3154  ;
3156  "Need %u bits to represent %" PRIu32 " peers\n",
3157  bits_needed,
3158  num_peers);
3159 
3160  rps_peers = GNUNET_new_array (num_peers, struct RPSPeer);
3162  rps_peer_ids = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
3163  if ((2 == mal_type) ||
3164  (3 == mal_type))
3165  target_peer = &rps_peer_ids[num_peers - 2];
3166 
3167  ok = 1;
3168  GNUNET_TESTBED_run (NULL,
3169  cfg,
3170  num_peers,
3171  0, /* event mask */
3172  NULL,
3173  NULL,
3174  &test_run,
3175  NULL);
3176 }
3177 
3178 
3186 int
3187 main (int argc, char *argv[])
3188 {
3189  int ret_value;
3190  struct GNUNET_GETOPT_CommandLineOption options[] = {
3192  "num-peers",
3193  "COUNT",
3194  gettext_noop ("number of peers to start"),
3195  &num_peers),
3197  "duration",
3198  "DURATION",
3199  gettext_noop (
3200  "duration of the profiling"),
3201  &duration),
3203  "timeout",
3204  "TIMEOUT",
3205  gettext_noop (
3206  "timeout for the profiling"),
3207  &timeout),
3209  "num-requests",
3210  "COUNT",
3211  gettext_noop ("number of PeerIDs to request"),
3214  };
3215 
3216  unsetenv ("XDG_DATA_HOME");
3217  unsetenv ("XDG_CONFIG_HOME");
3218  // if (GNUNET_OK !=
3219  // GNUNET_STRINGS_get_utf8_args (argc, argv,
3220  // &argc, &argv))
3221  // return 2;
3222  ret_value = 0;
3223  if (GNUNET_OK !=
3224  GNUNET_PROGRAM_run (argc,
3225  argv,
3226  "gnunet-rps-profiler",
3227  gettext_noop (
3228  "Measure quality and performance of the RPS service."),
3229  options,
3230  &run,
3231  NULL))
3232  {
3233  ret_value = 1;
3234  }
3235  if (0 != ret_value)
3236  {
3238  "Test did not run successfully!\n");
3239  }
3240  else
3241  {
3242  ret_value = cur_test_run.eval_cb ();
3244  {
3245  GNUNET_array_grow (rps_peers->cur_view,
3246  rps_peers->cur_view_count,
3247  0);
3248  }
3249  GNUNET_free (rps_peers);
3250  GNUNET_free (rps_peer_ids);
3252  }
3253  return ret_value;
3254 }
3255 
3256 
3257 /* 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.
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:1345
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.
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:1036
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:589
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:1300
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: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
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:78
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:75
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:912
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
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:526
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
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: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.
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:1253
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 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:1231
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.
struct GNUNET_STATISTICS_Handle * stats
Handle to the statistics service.
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:820
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:1280
int GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1029
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:442
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: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:2044
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...
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.
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...
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.
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:367
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:77
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: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.
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:1268
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.
union GNUNET_TESTBED_PeerInformation::@61 result
The result of the get information operation; Choose according to the pit.
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:966