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 
77 enum STAT_TYPE {
110  STAT_TYPE_MAX, /* 32 */
111 };
112 
113 static char* stat_type_strings[] = {
114  "# rounds",
115  "# rounds blocked",
116  "# rounds blocked - too many pushes",
117  "# rounds blocked - no pushes",
118  "# rounds blocked - no pull replies",
119  "# rounds blocked - too many pushes, no pull replies",
120  "# rounds blocked - no pushes, no pull replies",
121  "# push send issued",
122  "# push send issued (multi-hop peer)",
123  "# pull request send issued",
124  "# pull request send issued (multi-hop peer)",
125  "# pull reply send issued",
126  "# pushes sent",
127  "# pull requests sent",
128  "# pull requests sent (multi-hop peer)",
129  "# pull replys sent",
130  "# push message received",
131  "# push message received (multi-hop peer)",
132  "# pull request message received",
133  "# pull request message received (multi-hop peer)",
134  "# pull reply messages received",
135  "# pull reply messages received (multi-hop peer)",
136  "view size",
137  "# known peers",
138  "# valid peers",
139  "# learnd peers",
140  "# pending online checks",
141  "# unrequested pull replies",
142  "# peers in push map at end of round",
143  "# peers in pull map at end of round",
144  "# peers in view at end of round",
145  "view size aim",
146 };
147 
148 struct STATcls {
149  struct RPSPeer *rps_peer;
151 };
152 
153 
161 enum STAT_TYPE stat_str_2_type(const char *stat_str)
162 {
164  stat_str,
165  strlen(stat_type_strings[STAT_TYPE_BLOCKS_NO_PULL])))
166  {
168  }
170  stat_str,
171  strlen(stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL])))
172  {
174  }
175  else if (0 == strncmp(stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH],
176  stat_str,
177  strlen(stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH])))
178  {
180  }
182  stat_str,
183  strlen(stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL])))
184  {
186  }
187  else if (0 == strncmp(stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH],
188  stat_str,
189  strlen(stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH])))
190  {
192  }
193  else if (0 == strncmp(stat_type_strings[STAT_TYPE_BLOCKS],
194  stat_str,
195  strlen(stat_type_strings[STAT_TYPE_BLOCKS])))
196  {
197  return STAT_TYPE_BLOCKS;
198  }
199  else if (0 == strncmp(stat_type_strings[STAT_TYPE_ROUNDS],
200  stat_str,
201  strlen(stat_type_strings[STAT_TYPE_ROUNDS])))
202  {
203  return STAT_TYPE_ROUNDS;
204  }
205  else if (0 == strncmp(stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND],
206  stat_str,
207  strlen(stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND])))
208  {
210  }
211  else if (0 == strncmp(stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND_MH],
212  stat_str,
213  strlen(stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND_MH])))
214  {
216  }
217  else if (0 == strncmp(stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ],
218  stat_str,
219  strlen(stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ])))
220  {
222  }
223  else if (0 == strncmp(stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ_MH],
224  stat_str,
225  strlen(stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ_MH])))
226  {
228  }
229  else if (0 == strncmp(stat_type_strings[STAT_TYPE_ISSUED_PULL_REP],
230  stat_str,
231  strlen(stat_type_strings[STAT_TYPE_ISSUED_PULL_REP])))
232  {
234  }
235  else if (0 == strncmp(stat_type_strings[STAT_TYPE_SENT_PUSH_SEND],
236  stat_str,
237  strlen(stat_type_strings[STAT_TYPE_SENT_PUSH_SEND])))
238  {
240  }
241  else if (0 == strncmp(stat_type_strings[STAT_TYPE_SENT_PULL_REQ],
242  stat_str,
243  strlen(stat_type_strings[STAT_TYPE_SENT_PULL_REQ])))
244  {
246  }
247  else if (0 == strncmp(stat_type_strings[STAT_TYPE_SENT_PULL_REQ_MH],
248  stat_str,
249  strlen(stat_type_strings[STAT_TYPE_SENT_PULL_REQ_MH])))
250  {
252  }
253  else if (0 == strncmp(stat_type_strings[STAT_TYPE_SENT_PULL_REP],
254  stat_str,
255  strlen(stat_type_strings[STAT_TYPE_SENT_PULL_REP])))
256  {
258  }
259  else if (0 == strncmp(stat_type_strings[STAT_TYPE_RECV_PUSH_SEND],
260  stat_str,
261  strlen(stat_type_strings[STAT_TYPE_RECV_PUSH_SEND])))
262  {
264  }
265  else if (0 == strncmp(stat_type_strings[STAT_TYPE_RECV_PUSH_SEND_MH],
266  stat_str,
267  strlen(stat_type_strings[STAT_TYPE_RECV_PUSH_SEND_MH])))
268  {
270  }
271  else if (0 == strncmp(stat_type_strings[STAT_TYPE_RECV_PULL_REQ],
272  stat_str,
273  strlen(stat_type_strings[STAT_TYPE_RECV_PULL_REQ])))
274  {
276  }
277  else if (0 == strncmp(stat_type_strings[STAT_TYPE_RECV_PULL_REQ_MH],
278  stat_str,
279  strlen(stat_type_strings[STAT_TYPE_RECV_PULL_REQ_MH])))
280  {
282  }
283  else if (0 == strncmp(stat_type_strings[STAT_TYPE_RECV_PULL_REP],
284  stat_str,
285  strlen(stat_type_strings[STAT_TYPE_RECV_PULL_REP])))
286  {
288  }
289  else if (0 == strncmp(stat_type_strings[STAT_TYPE_RECV_PULL_REP_MH],
290  stat_str,
291  strlen(stat_type_strings[STAT_TYPE_RECV_PULL_REP_MH])))
292  {
294  }
295  else if (0 == strncmp(stat_type_strings[STAT_TYPE_VIEW_SIZE],
296  stat_str,
297  strlen(stat_type_strings[STAT_TYPE_VIEW_SIZE])))
298  {
299  return STAT_TYPE_VIEW_SIZE;
300  }
301  else if (0 == strncmp(stat_type_strings[STAT_TYPE_KNOWN_PEERS],
302  stat_str,
303  strlen(stat_type_strings[STAT_TYPE_KNOWN_PEERS])))
304  {
305  return STAT_TYPE_KNOWN_PEERS;
306  }
307  else if (0 == strncmp(stat_type_strings[STAT_TYPE_VALID_PEERS],
308  stat_str,
309  strlen(stat_type_strings[STAT_TYPE_VALID_PEERS])))
310  {
311  return STAT_TYPE_VALID_PEERS;
312  }
313  else if (0 == strncmp(stat_type_strings[STAT_TYPE_LEARND_PEERS],
314  stat_str,
315  strlen(stat_type_strings[STAT_TYPE_LEARND_PEERS])))
316  {
317  return STAT_TYPE_LEARND_PEERS;
318  }
319  else if (0 == strncmp(stat_type_strings[STAT_TYPE_PENDING_ONLINE_CHECKS],
320  stat_str,
321  strlen(stat_type_strings[STAT_TYPE_PENDING_ONLINE_CHECKS])))
322  {
324  }
326  stat_str,
327  strlen(stat_type_strings[STAT_TYPE_UNREQUESTED_PULL_REPLIES])))
328  {
330  }
331  else if (0 == strncmp(stat_type_strings[STAT_TYPE_PEERS_IN_PUSH_MAP],
332  stat_str,
333  strlen(stat_type_strings[STAT_TYPE_PEERS_IN_PUSH_MAP])))
334  {
336  }
337  else if (0 == strncmp(stat_type_strings[STAT_TYPE_PEERS_IN_PULL_MAP],
338  stat_str,
339  strlen(stat_type_strings[STAT_TYPE_PEERS_IN_PULL_MAP])))
340  {
342  }
343  else if (0 == strncmp(stat_type_strings[STAT_TYPE_PEERS_IN_VIEW],
344  stat_str,
345  strlen(stat_type_strings[STAT_TYPE_PEERS_IN_VIEW])))
346  {
348  }
349  else if (0 == strncmp(stat_type_strings[STAT_TYPE_VIEW_SIZE_AIM],
350  stat_str,
351  strlen(stat_type_strings[STAT_TYPE_VIEW_SIZE_AIM])))
352  {
354  }
355  return STAT_TYPE_MAX;
356 }
357 
358 
371 };
372 
376 struct OpListEntry {
380  struct OpListEntry *next;
381 
385  struct OpListEntry *prev;
386 
391 
397 
401  unsigned int index;
402 };
403 
407 static struct OpListEntry *oplist_head;
408 
412 static struct OpListEntry *oplist_tail;
413 
414 
418 struct PendingReply {
424 
429 
433  struct RPSPeer *rps_peer;
434 };
435 
436 
446 
451 
455  struct RPSPeer *rps_peer;
456 };
457 
458 
462 struct RPSPeer {
466  unsigned int index;
467 
472 
477 
482 
486  //struct GNUNET_RPS_Request_Handle *req_handle;
487 
491  int online;
492 
496  unsigned int num_ids_to_request;
497 
503 
507  unsigned int num_pending_reqs;
508 
514 
518  unsigned int num_pending_reps;
519 
523  unsigned int num_recv_ids;
524 
529 
534 
539 
546 
550  const char *file_name_stats;
551 
555  const char *file_name_probs;
556 
560  const char *file_name_probs_hist;
561 
566 
570  uint32_t cur_view_count;
571 
575  uint32_t count_in_views;
576 
580  uint64_t stats[STAT_TYPE_MAX];
585 
591 };
592 
596 static struct RPSPeer *rps_peers;
597 
602 
607 
612 
616 static unsigned int num_peers_online;
617 
621 static unsigned int view_sizes;
622 
626 static int ok;
627 
632 
637 
638 
643 
647 typedef void (*InitPeer) (struct RPSPeer *rps_peer);
648 
655 typedef void (*PreTest) (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h);
656 
666 typedef void (*MainTest) (struct RPSPeer *rps_peer);
667 
671 typedef void (*ReplyHandle) (void *cls,
672  uint64_t n,
673  const struct GNUNET_PeerIdentity *recv_peers);
674 
678 typedef void (*PostTest) (struct RPSPeer *peer);
679 
683 typedef int (*EvaluationCallback) (void);
684 
697 };
698 
707 
712 };
713 
722 
727 };
728 
737 
742 };
743 
751  char *name;
752 
757 
762 
767 
772 
777 
782 
787 
791  uint32_t num_requests;
792 
796  enum OPTION_CHURN have_churn;
797 
801  enum OPTION_QUICK_QUIT have_quick_quit;
802 
806  enum OPTION_COLLECT_STATISTICS have_collect_statistics;
807 
811  enum OPTION_COLLECT_VIEW have_collect_view;
812 
818 } cur_test_run;
819 
823 static int post_test;
824 
828 static int in_shutdown;
829 
833 static void
834 tofile_(const char *file_name, const char *line)
835 {
836  struct GNUNET_DISK_FileHandle *f;
837  /* char output_buffer[512]; */
838  size_t size;
839  /* int size; */
840  size_t size2;
841 
842  if (NULL == (f = GNUNET_DISK_file_open(file_name,
850  {
852  "Not able to open file %s\n",
853  file_name);
854  return;
855  }
856  /* size = GNUNET_snprintf (output_buffer,
857  sizeof (output_buffer),
858  "%llu %s\n",
859  GNUNET_TIME_absolute_get ().abs_value_us,
860  line);
861  if (0 > size)
862  {
863  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
864  "Failed to write string to buffer (size: %i)\n",
865  size);
866  return;
867  } */
868 
869  size = strlen(line) * sizeof(char);
870 
871  size2 = GNUNET_DISK_file_write(f, line, size);
872  if (size != size2)
873  {
875  "Unable to write to file! (Size: %lu, size2: %lu)\n",
876  size,
877  size2);
879  {
881  "Unable to close file\n");
882  }
883  return;
884  }
885 
887  {
889  "Unable to close file\n");
890  }
891 }
892 
896 #define tofile(file_name, ...) do { \
897  char tmp_buf[512]; \
898  int size; \
899  size = GNUNET_snprintf(tmp_buf, sizeof(tmp_buf), __VA_ARGS__); \
900  if (0 > size) \
901  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \
902  "Failed to create tmp_buf\n"); \
903  else \
904  tofile_ (file_name, tmp_buf); \
905  } while (0);
906 
907 
912 /* static void
913  ids_to_file (char *file_name,
914  struct GNUNET_PeerIdentity *peer_ids,
915  unsigned int num_peer_ids)
916  {
917  unsigned int i;
918 
919  for (i=0 ; i < num_peer_ids ; i++)
920  {
921  to_file (file_name,
922  "%u\t%s",
923  i,
924  GNUNET_i2s_full (&peer_ids[i]));
925  }
926  } */
927 
931 static int
932 evaluate(void)
933 {
934  unsigned int i;
935  int tmp_ok;
936 
937  tmp_ok = 1;
938 
939  for (i = 0; i < num_peers; i++)
940  {
942  "%u. peer [%s] received %u of %u expected peer_ids: %i\n",
943  i,
944  GNUNET_i2s(rps_peers[i].peer_id),
945  rps_peers[i].num_recv_ids,
946  rps_peers[i].num_ids_to_request,
947  (rps_peers[i].num_ids_to_request == rps_peers[i].num_recv_ids));
948  tmp_ok &= (rps_peers[i].num_ids_to_request == rps_peers[i].num_recv_ids);
949  }
950  return tmp_ok ? 0 : 1;
951 }
952 
953 
957 static struct OpListEntry *
959 {
960  struct OpListEntry *entry;
961 
962  entry = GNUNET_new(struct OpListEntry);
963  GNUNET_CONTAINER_DLL_insert_tail(oplist_head, oplist_tail, entry);
964  return entry;
965 }
966 
967 
978  const struct RPSPeer *rps_peer)
979 {
982  rps_peer->stat_collected_flags))
983  {
984  return GNUNET_NO;
985  }
986  return GNUNET_YES;
987 }
996 {
997  uint32_t i;
998 
999  for (i = 0; i < num_peers; i++)
1000  {
1002  {
1004  "At least Peer %" PRIu32 " did not yet receive all statistics values\n",
1005  i);
1006  return GNUNET_NO;
1007  }
1008  }
1010  "All peers received their statistics values\n");
1011  return GNUNET_YES;
1012 }
1013 
1014 static void
1015 rps_disconnect_adapter(void *cls,
1016  void *op_result);
1017 
1018 static void
1020 {
1021  struct RPSPeer *rps_peer;
1022 
1023  rps_peer = pending_req->rps_peer;
1025  rps_peer->pending_req_tail,
1026  pending_req);
1027  rps_peer->num_pending_reqs--;
1029  "Cancelling pending rps get request\n");
1030  GNUNET_SCHEDULER_cancel(pending_req->request_task);
1031  GNUNET_free(pending_req);
1032 }
1033 
1034 static void
1035 cancel_request(struct PendingReply *pending_rep)
1036 {
1037  struct RPSPeer *rps_peer;
1038 
1039  rps_peer = pending_rep->rps_peer;
1041  rps_peer->pending_rep_tail,
1042  pending_rep);
1043  rps_peer->num_pending_reps--;
1045  "Cancelling rps get reply\n");
1046  GNUNET_assert(NULL != pending_rep->req_handle);
1048  pending_rep->req_handle = NULL;
1049  GNUNET_free(pending_rep);
1050  pending_rep = NULL;
1051 }
1052 
1053 void
1054 clean_peer(unsigned peer_index)
1055 {
1056  struct PendingRequest *pending_req;
1057 
1058  while (NULL != (pending_req = rps_peers[peer_index].pending_req_head))
1059  {
1060  cancel_pending_req(pending_req);
1061  }
1062  pending_req = rps_peers[peer_index].pending_req_head;
1063  rps_disconnect_adapter(&rps_peers[peer_index],
1064  &rps_peers[peer_index].rps_handle);
1065  for (unsigned stat_type = STAT_TYPE_ROUNDS;
1067  stat_type++)
1068  {
1069  if (NULL != rps_peers[peer_index].h_stat_get[stat_type])
1070  {
1072  "(%u) did not yet receive stat value for `%s'\n",
1073  rps_peers[peer_index].index,
1074  stat_type_strings[stat_type]);
1076  rps_peers[peer_index].h_stat_get[stat_type]);
1077  }
1078  }
1079  if (NULL != rps_peers[peer_index].op)
1080  {
1081  GNUNET_TESTBED_operation_done(rps_peers[peer_index].op);
1082  rps_peers[peer_index].op = NULL;
1083  }
1084 }
1085 
1089 static void
1090 shutdown_op(void *cls)
1091 {
1092  unsigned int i;
1093  struct OpListEntry *entry;
1094 
1095  (void)cls;
1096 
1098  "Shutdown task scheduled, going down.\n");
1100 
1101  if (NULL != shutdown_task)
1102  {
1103  GNUNET_SCHEDULER_cancel(shutdown_task);
1104  shutdown_task = NULL;
1105  }
1106  if (NULL != post_test_task)
1107  {
1108  GNUNET_SCHEDULER_cancel(post_test_task);
1109  post_test_task = NULL;
1110  }
1111  if (NULL != churn_task)
1112  {
1113  GNUNET_SCHEDULER_cancel(churn_task);
1114  churn_task = NULL;
1115  }
1116  entry = oplist_head;
1117  while (NULL != (entry = oplist_head))
1118  {
1120  "Operation still pending on shutdown (%u)\n",
1121  entry->index);
1123  GNUNET_CONTAINER_DLL_remove(oplist_head, oplist_tail, entry);
1124  GNUNET_free(entry);
1125  }
1126  for (i = 0; i < num_peers; i++)
1127  {
1128  clean_peer(i);
1129  }
1130  close_all_files();
1131 }
1132 
1133 static void
1135 {
1136  (void)cls;
1137 
1139  "Shutdown was triggerd by timeout, going down.\n");
1140  shutdown_task = NULL;
1142 }
1143 
1144 
1148 static void
1149 post_test_op(void *cls)
1150 {
1151  unsigned int i;
1152 
1153  (void)cls;
1154 
1155  post_test_task = NULL;
1158  "Executing post test op.\n");
1159  if (NULL != churn_task)
1160  {
1161  GNUNET_SCHEDULER_cancel(churn_task);
1162  churn_task = NULL;
1163  }
1164  for (i = 0; i < num_peers; i++)
1165  {
1167  "Executing post test op. (peer %" PRIu32 ")\n",
1168  rps_peers[i].index);
1169  if (NULL != rps_peers[i].op)
1170  {
1171  GNUNET_TESTBED_operation_done(rps_peers[i].op);
1172  rps_peers[i].op = NULL;
1174  "Cancelled testbed operation\n");
1175  }
1176  if (NULL != cur_test_run.post_test)
1177  {
1178  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Executing post_test for peer %u\n", i);
1179  cur_test_run.post_test(&rps_peers[i]);
1180  }
1181  }
1182  /* If we do not collect statistics, shut down directly */
1185  {
1186  GNUNET_SCHEDULER_cancel(shutdown_task);
1187  shutdown_task = NULL;
1189  }
1190 }
1191 
1192 
1196 static void
1197 seed_peers(void *cls)
1198 {
1199  struct RPSPeer *peer = cls;
1200  unsigned int amount;
1201  unsigned int i;
1202 
1203  // TODO if malicious don't seed mal peers
1204  amount = round(.5 * num_peers);
1205 
1206  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Seeding peers:\n");
1207  for (i = 0; i < amount; i++)
1208  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Seeding %u. peer: %s\n",
1209  i,
1210  GNUNET_i2s(&rps_peer_ids[i]));
1211 
1212  GNUNET_RPS_seed_ids(peer->rps_handle, amount, rps_peer_ids);
1213 }
1214 
1215 
1219 void
1220 info_cb(void *cb_cls,
1221  struct GNUNET_TESTBED_Operation *op,
1222  const struct GNUNET_TESTBED_PeerInformation *pinfo,
1223  const char *emsg)
1224 {
1225  struct OpListEntry *entry = (struct OpListEntry *)cb_cls;
1226 
1227  (void)op;
1228 
1230  {
1231  return;
1232  }
1233 
1234  if (NULL == pinfo || NULL != emsg)
1235  {
1236  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Got Error: %s\n", emsg);
1238  return;
1239  }
1240 
1242  "Peer %u is %s\n",
1243  entry->index,
1244  GNUNET_i2s(pinfo->result.id));
1245 
1246  rps_peer_ids[entry->index] = *(pinfo->result.id);
1247  rps_peers[entry->index].peer_id = &rps_peer_ids[entry->index];
1248 
1251  &rps_peer_ids[entry->index],
1252  &rps_peers[entry->index],
1254  tofile("/tmp/rps/peer_ids",
1255  "%u\t%s\n",
1256  entry->index,
1257  GNUNET_i2s_full(&rps_peer_ids[entry->index]));
1258 
1259  GNUNET_CONTAINER_DLL_remove(oplist_head, oplist_tail, entry);
1261  GNUNET_free(entry);
1262 }
1263 
1264 
1274 static void
1276  struct GNUNET_TESTBED_Operation *op,
1277  void *ca_result,
1278  const char *emsg)
1279 {
1280  struct RPSPeer *rps_peer = cls;
1281  struct GNUNET_RPS_Handle *rps = ca_result;
1282 
1284  {
1285  return;
1286  }
1287 
1288  rps_peer->rps_handle = rps;
1289  rps_peer->online = GNUNET_YES;
1290  num_peers_online++;
1291 
1292  GNUNET_assert(op == rps_peer->op);
1293  if (NULL != emsg)
1294  {
1296  "Failed to connect to RPS service: %s\n",
1297  emsg);
1298  ok = 1;
1300  return;
1301  }
1302 
1304  "Started client successfully (%u)\n",
1305  rps_peer->index);
1306 
1307  cur_test_run.main_test(rps_peer);
1308 }
1309 
1310 
1321 static void *
1323  const struct GNUNET_CONFIGURATION_Handle *cfg)
1324 {
1325  struct GNUNET_RPS_Handle *h;
1326 
1327  h = GNUNET_RPS_connect(cfg);
1328 
1329  if (NULL != cur_test_run.pre_test)
1330  cur_test_run.pre_test(cls, h);
1331 
1332  return h;
1333 }
1334 
1344 static void *
1346  const struct GNUNET_CONFIGURATION_Handle *cfg)
1347 {
1348  struct RPSPeer *peer = cls;
1349 
1350  peer->stats_h = GNUNET_STATISTICS_create("rps-profiler", cfg);
1351  return peer->stats_h;
1352 }
1353 
1360 static void
1362 {
1363  struct RPSPeer *peer = cls;
1364 
1365  //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1366  // (peer->stats_h, "core", "# peers connected",
1367  // stat_iterator, peer));
1368  //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1369  // (peer->stats_h, "nse", "# peers connected",
1370  // stat_iterator, peer));
1372  peer->stats_h = NULL;
1373 }
1374 
1385 static void
1387  struct GNUNET_TESTBED_Operation *op,
1388  void *ca_result,
1389  const char *emsg)
1390 {
1391  //struct GNUNET_STATISTICS_Handle *sh = ca_result;
1392  //struct RPSPeer *peer = (struct RPSPeer *) cls;
1393  (void)cls;
1394  (void)op;
1395  (void)ca_result;
1396 
1397  if (NULL != emsg)
1398  {
1399  GNUNET_break(0);
1400  return;
1401  }
1402  //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1403  // (sh, "core", "# peers connected",
1404  // stat_iterator, peer));
1405  //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1406  // (sh, "nse", "# peers connected",
1407  // stat_iterator, peer));
1408 }
1409 
1410 
1418 static void
1420  void *op_result)
1421 {
1422  struct RPSPeer *peer = cls;
1423  struct GNUNET_RPS_Handle *h = op_result;
1424  struct PendingReply *pending_rep;
1425 
1427  "disconnect_adapter (%u)\n",
1428  peer->index);
1429  GNUNET_assert(NULL != peer);
1430  if (NULL != peer->rps_handle)
1431  {
1432  while (NULL != (pending_rep = peer->pending_rep_head))
1433  {
1434  cancel_request(pending_rep);
1435  }
1436  GNUNET_assert(h == peer->rps_handle);
1437  if (NULL != h)
1438  {
1440  h = NULL;
1441  }
1442  peer->rps_handle = NULL;
1443  }
1444 }
1445 
1446 
1447 /***********************************************************************
1448 * Definition of tests
1449 ***********************************************************************/
1450 
1458 static void
1460  uint64_t n,
1461  const struct GNUNET_PeerIdentity *recv_peers)
1462 {
1463  struct RPSPeer *rps_peer;
1464  struct PendingReply *pending_rep = (struct PendingReply *)cls;
1465  unsigned int i;
1466 
1467  rps_peer = pending_rep->rps_peer;
1469  rps_peer->pending_rep_tail,
1470  pending_rep);
1471  rps_peer->num_pending_reps--;
1473  "[%s] got %" PRIu64 " peers:\n",
1474  GNUNET_i2s(rps_peer->peer_id),
1475  n);
1476 
1477  for (i = 0; i < n; i++)
1478  {
1480  "%u: %s\n",
1481  i,
1482  GNUNET_i2s(&recv_peers[i]));
1483 
1484  rps_peer->num_recv_ids++;
1485  }
1486 
1487  if (GNUNET_YES != post_test)
1488  return;
1490  return;
1491  if (0 == evaluate())
1492  {
1494  "Test succeeded before end of duration\n");
1495  if (NULL != post_test_task)
1496  GNUNET_SCHEDULER_cancel(post_test_task);
1497  post_test_task = GNUNET_SCHEDULER_add_now(&post_test_op, NULL);
1498  GNUNET_assert(NULL != post_test_task);
1499  }
1500 }
1501 
1502 
1503 static void
1504 profiler_reply_handle_info(void *cls,
1505  const struct GNUNET_PeerIdentity *recv_peer,
1506  double probability,
1507  uint32_t num_observed);
1508 
1512 static void
1513 request_peers(void *cls)
1514 {
1515  struct PendingRequest *pending_req = cls;
1516  struct RPSPeer *rps_peer;
1517  struct PendingReply *pending_rep;
1518 
1519  rps_peer = pending_req->rps_peer;
1520  GNUNET_assert(1 <= rps_peer->num_pending_reqs);
1522  rps_peer->pending_req_tail,
1523  pending_req);
1524  rps_peer->num_pending_reqs--;
1526  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  }
1698  else
1699  {
1701  "Not starting churn task\n");
1702  }
1703 
1704  schedule_missing_requests(rps_peer);
1705 }
1706 
1707 /***********************************
1708 * PROFILER
1709 ***********************************/
1710 
1718 static void
1719 churn_cb(void *cls,
1720  struct GNUNET_TESTBED_Operation *op,
1721  const char *emsg)
1722 {
1723  // FIXME
1724  struct OpListEntry *entry = cls;
1725 
1726  (void)op;
1727 
1729  {
1730  return;
1731  }
1732 
1734  if (NULL != emsg)
1735  {
1736  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to start/stop RPS at a peer\n");
1738  return;
1739  }
1740  GNUNET_assert(0 != entry->delta);
1741 
1742  num_peers_online += entry->delta;
1743 
1744  if (PEER_GO_OFFLINE == entry->delta)
1745  { /* Peer hopefully just went offline */
1746  if (GNUNET_YES != rps_peers[entry->index].online)
1747  {
1749  "peer %s was expected to go offline but is still marked as online\n",
1750  GNUNET_i2s(rps_peers[entry->index].peer_id));
1751  GNUNET_break(0);
1752  }
1753  else
1754  {
1756  "peer %s probably went offline as expected\n",
1757  GNUNET_i2s(rps_peers[entry->index].peer_id));
1758  }
1759  rps_peers[entry->index].online = GNUNET_NO;
1760  }
1761 
1762  else if (PEER_GO_ONLINE < entry->delta)
1763  { /* Peer hopefully just went online */
1764  if (GNUNET_NO != rps_peers[entry->index].online)
1765  {
1767  "peer %s was expected to go online but is still marked as offline\n",
1768  GNUNET_i2s(rps_peers[entry->index].peer_id));
1769  GNUNET_break(0);
1770  }
1771  else
1772  {
1774  "peer %s probably went online as expected\n",
1775  GNUNET_i2s(rps_peers[entry->index].peer_id));
1776  if (NULL != cur_test_run.pre_test)
1777  {
1778  cur_test_run.pre_test(&rps_peers[entry->index],
1779  rps_peers[entry->index].rps_handle);
1780  schedule_missing_requests(&rps_peers[entry->index]);
1781  }
1782  }
1783  rps_peers[entry->index].online = GNUNET_YES;
1784  }
1785  else
1786  {
1788  "Invalid value for delta: %i\n", entry->delta);
1789  GNUNET_break(0);
1790  }
1791 
1792  GNUNET_CONTAINER_DLL_remove(oplist_head, oplist_tail, entry);
1793  rps_peers[entry->index].entry_op_manage = NULL;
1794  GNUNET_free(entry);
1795  //if (num_peers_in_round[current_round] == peers_running)
1796  // run_round ();
1797 }
1798 
1807 static void
1808 manage_service_wrapper(unsigned int i, unsigned int j,
1809  enum PEER_ONLINE_DELTA delta,
1810  double prob_go_on_off)
1811 {
1812  struct OpListEntry *entry = NULL;
1813  uint32_t prob;
1814 
1815  /* make sure that management operation is not already scheduled */
1816  if (NULL != rps_peers[j].entry_op_manage)
1817  {
1818  return;
1819  }
1820 
1822  UINT32_MAX);
1824  "%u. selected peer (%u: %s) is %s.\n",
1825  i,
1826  j,
1827  GNUNET_i2s(rps_peers[j].peer_id),
1828  (PEER_GO_ONLINE == delta) ? "online" : "offline");
1829  if (prob < prob_go_on_off * UINT32_MAX)
1830  {
1832  "%s goes %s\n",
1833  GNUNET_i2s(rps_peers[j].peer_id),
1834  (PEER_GO_OFFLINE == delta) ? "offline" : "online");
1835 
1836  if (PEER_GO_OFFLINE == delta)
1837  cancel_pending_req_rep(&rps_peers[j]);
1838  entry = make_oplist_entry();
1839  entry->delta = delta;
1840  entry->index = j;
1841  entry->op = GNUNET_TESTBED_peer_manage_service(NULL,
1842  testbed_peers[j],
1843  "rps",
1844  &churn_cb,
1845  entry,
1846  (PEER_GO_OFFLINE == delta) ? 0 : 1);
1847  rps_peers[j].entry_op_manage = entry;
1848  }
1849 }
1850 
1851 
1852 static void
1853 churn(void *cls)
1854 {
1855  unsigned int i;
1856  unsigned int j;
1857  double portion_online;
1858  unsigned int *permut;
1859  double prob_go_offline;
1860  double portion_go_online;
1861  double portion_go_offline;
1862 
1863  (void)cls;
1864 
1866  {
1867  return;
1868  }
1870  "Churn function executing\n");
1871 
1872  churn_task = NULL; /* Should be invalid by now */
1873 
1874  /* Compute the probability for an online peer to go offline
1875  * this round */
1876  portion_online = num_peers_online * 1.0 / num_peers;
1878  "Portion online: %f\n",
1879  portion_online);
1880  portion_go_online = ((1 - portion_online) * .5 * .66);
1882  "Portion that should go online: %f\n",
1883  portion_go_online);
1884  portion_go_offline = (portion_online + portion_go_online) - .75;
1886  "Portion that probably goes offline: %f\n",
1887  portion_go_offline);
1888  prob_go_offline = portion_go_offline / (portion_online * .5);
1890  "Probability of a selected online peer to go offline: %f\n",
1891  prob_go_offline);
1892 
1894  (unsigned int)num_peers);
1895 
1896  /* Go over 50% randomly chosen peers */
1897  for (i = 0; i < .5 * num_peers; i++)
1898  {
1899  j = permut[i];
1900 
1901  /* If online, shut down with certain probability */
1902  if (GNUNET_YES == rps_peers[j].online)
1903  {
1904  manage_service_wrapper(i, j, -1, prob_go_offline);
1905  }
1906 
1907  /* If offline, restart with certain probability */
1908  else if (GNUNET_NO == rps_peers[j].online)
1909  {
1910  manage_service_wrapper(i, j, 1, 0.66);
1911  }
1912  }
1913 
1914  GNUNET_free(permut);
1915 
1916  churn_task = GNUNET_SCHEDULER_add_delayed(
1918  churn,
1919  NULL);
1920 }
1921 
1922 
1926 static void profiler_init_peer(struct RPSPeer *rps_peer)
1927 {
1929  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "peer shall request %i peers\n",
1930  rps_peer->num_ids_to_request);
1931 }
1932 
1933 
1941 static void
1943  uint64_t n,
1944  const struct GNUNET_PeerIdentity *recv_peers)
1945 {
1946  struct RPSPeer *rps_peer;
1947  struct RPSPeer *rcv_rps_peer;
1948  char file_name_buf[128];
1949  char file_name_dh_buf[128];
1950  char file_name_dhr_buf[128];
1951  char file_name_dhru_buf[128];
1952  char *file_name = file_name_buf;
1953  char *file_name_dh = file_name_dh_buf;
1954  char *file_name_dhr = file_name_dhr_buf;
1955  char *file_name_dhru = file_name_dhru_buf;
1956  unsigned int i;
1957  struct PendingReply *pending_rep = (struct PendingReply *)cls;
1958 
1959  pending_rep->req_handle = NULL;
1960  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
1961  rps_peer = pending_rep->rps_peer;
1962  (void)GNUNET_asprintf(&file_name,
1963  "/tmp/rps/received_ids-%u",
1964  rps_peer->index);
1965 
1966  (void)GNUNET_asprintf(&file_name_dh,
1967  "/tmp/rps/diehard_input-%u",
1968  rps_peer->index);
1969  (void)GNUNET_asprintf(&file_name_dhr,
1970  "/tmp/rps/diehard_input_raw-%u",
1971  rps_peer->index);
1972  (void)GNUNET_asprintf(&file_name_dhru,
1973  "/tmp/rps/diehard_input_raw_aligned-%u",
1974  rps_peer->index);
1976  "[%s] got %" PRIu64 " peers:\n",
1977  GNUNET_i2s(rps_peer->peer_id),
1978  n);
1979  for (i = 0; i < n; i++)
1980  {
1982  "%u: %s\n",
1983  i,
1984  GNUNET_i2s(&recv_peers[i]));
1985  tofile(file_name,
1986  "%s\n",
1987  GNUNET_i2s_full(&recv_peers[i]));
1988  rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get(peer_map, &recv_peers[i]);
1989  GNUNET_assert(NULL != rcv_rps_peer);
1990  tofile(file_name_dh,
1991  "%" PRIu32 "\n",
1992  (uint32_t)rcv_rps_peer->index);
1993 #ifdef TO_FILE
1994  to_file_raw(file_name_dhr,
1995  (char *)&rcv_rps_peer->index,
1996  sizeof(uint32_t));
1997  to_file_raw_unaligned(file_name_dhru,
1998  (char *)&rcv_rps_peer->index,
1999  sizeof(uint32_t),
2000  bits_needed);
2001 #endif /* TO_FILE */
2002  }
2003  default_reply_handle(cls, n, recv_peers);
2004 }
2005 
2006 
2014 static void
2016  const struct GNUNET_PeerIdentity *recv_peer,
2017  double probability,
2018  uint32_t num_observed)
2019 {
2020  struct RPSPeer *rps_peer;
2021  struct RPSPeer *rcv_rps_peer;
2022  char file_name_buf[128];
2023  char file_name_dh_buf[128];
2024  char file_name_dhr_buf[128];
2025  char file_name_dhru_buf[128];
2026  char *file_name = file_name_buf;
2027  char *file_name_dh = file_name_dh_buf;
2028  char *file_name_dhr = file_name_dhr_buf;
2029  char *file_name_dhru = file_name_dhru_buf;
2030  unsigned int i;
2031  struct PendingReply *pending_rep = (struct PendingReply *)cls;
2032 
2033  pending_rep->req_handle = NULL;
2034  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
2035  rps_peer = pending_rep->rps_peer;
2036  (void)GNUNET_asprintf(&file_name,
2037  "/tmp/rps/received_ids-%u",
2038  rps_peer->index);
2039 
2040  (void)GNUNET_asprintf(&file_name_dh,
2041  "/tmp/rps/diehard_input-%u",
2042  rps_peer->index);
2043  (void)GNUNET_asprintf(&file_name_dhr,
2044  "/tmp/rps/diehard_input_raw-%u",
2045  rps_peer->index);
2046  (void)GNUNET_asprintf(&file_name_dhru,
2047  "/tmp/rps/diehard_input_raw_aligned-%u",
2048  rps_peer->index);
2050  "[%s] got peer with info:\n",
2051  GNUNET_i2s(rps_peer->peer_id));
2053  " %s\n",
2054  GNUNET_i2s(recv_peer));
2055  tofile(file_name,
2056  "%s %d %" PRIu32 " \n",
2057  GNUNET_i2s_full(recv_peer),
2058  probability,
2059  num_observed);
2060  rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get(peer_map, recv_peer);
2061  GNUNET_assert(NULL != rcv_rps_peer);
2062  tofile(file_name_dh,
2063  "%" PRIu32 "\n",
2064  (uint32_t)rcv_rps_peer->index);
2065 #ifdef TO_FILE
2066  to_file_raw(file_name_dhr,
2067  (char *)&rcv_rps_peer->index,
2068  sizeof(uint32_t));
2069  to_file_raw_unaligned(file_name_dhru,
2070  (char *)&rcv_rps_peer->index,
2071  sizeof(uint32_t),
2072  bits_needed);
2073 #endif /* TO_FILE */
2074  default_reply_handle(cls, 1, recv_peer);
2075 }
2076 
2077 
2078 static void
2079 profiler_cb(struct RPSPeer *rps_peer)
2080 {
2082  {
2083  return;
2084  }
2085 
2086  /* Start churn */
2087  if (HAVE_CHURN == cur_test_run.have_churn && NULL == churn_task)
2088  {
2090  "Starting churn task\n");
2091  churn_task = GNUNET_SCHEDULER_add_delayed(
2093  churn,
2094  NULL);
2095  }
2096  else
2097  {
2099  "Not starting churn task\n");
2100  }
2101 
2102  /* Only request peer ids at one peer.
2103  * (It's the before-last because last one is target of the focussed attack.)
2104  */
2105  if (0 < rps_peer->num_ids_to_request)
2106  schedule_missing_requests(rps_peer);
2107 }
2108 
2118 static int
2119 file_name_cb(void *cls, const char *filename)
2120 {
2121  if (NULL != strstr(filename, "sampler_el"))
2122  {
2123  struct RPS_SamplerElement *s_elem;
2124  struct GNUNET_CRYPTO_AuthKey auth_key;
2125  const char *key_char;
2126  uint32_t i;
2127  (void)cls;
2128 
2129  key_char = filename + 20; /* Length of "/tmp/rps/sampler_el-" */
2130  tofile(filename, "--------------------------\n");
2131 
2132  auth_key = string_to_auth_key(key_char);
2133  s_elem = RPS_sampler_elem_create();
2134  RPS_sampler_elem_set(s_elem, auth_key);
2135 
2136  for (i = 0; i < num_peers; i++)
2137  {
2138  RPS_sampler_elem_next(s_elem, &rps_peer_ids[i]);
2139  }
2140  RPS_sampler_elem_destroy(s_elem);
2141  }
2142  return GNUNET_OK;
2143 }
2144 
2150 static int
2152 {
2153 #ifdef TO_FILE
2154  /* Compute perfect sample for each sampler element */
2155  if (-1 == GNUNET_DISK_directory_scan("/tmp/rps/", file_name_cb, NULL))
2156  {
2157  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Scan of directory failed\n");
2158  }
2159 #endif /* TO_FILE */
2160 
2161  return evaluate();
2162 }
2163 
2164 
2172 static int is_in_view(uint32_t a, uint32_t b)
2173 {
2174  uint32_t i;
2175 
2176  for (i = 0; i < rps_peers[a].cur_view_count; i++)
2177  {
2178  if (0 == memcmp(rps_peers[b].peer_id,
2179  &rps_peers[a].cur_view[i],
2180  sizeof(struct GNUNET_PeerIdentity)))
2181  {
2182  return GNUNET_YES;
2183  }
2184  }
2185  return GNUNET_NO;
2186 }
2187 
2188 static uint32_t get_idx_of_pid(const struct GNUNET_PeerIdentity *pid)
2189 {
2190  uint32_t i;
2191 
2192  for (i = 0; i < num_peers; i++)
2193  {
2194  if (0 == memcmp(pid,
2195  rps_peers[i].peer_id,
2196  sizeof(struct GNUNET_PeerIdentity)))
2197  {
2198  return i;
2199  }
2200  }
2201  //return 0; /* Should not happen - make compiler happy */
2203  "No known _PeerIdentity %s!\n",
2204  GNUNET_i2s_full(pid));
2205  GNUNET_assert(0);
2206 }
2207 
2216 static uint32_t count_containing_views(uint32_t a, uint32_t b)
2217 {
2218  uint32_t i;
2219  uint32_t peer_idx;
2220  uint32_t count = 0;
2221 
2222  for (i = 0; i < rps_peers[a].cur_view_count; i++)
2223  {
2224  peer_idx = get_idx_of_pid(&rps_peers[a].cur_view[i]);
2225  if (GNUNET_YES == is_in_view(peer_idx, b))
2226  {
2227  count++;
2228  }
2229  }
2230  return count;
2231 }
2232 
2239 static void compute_probabilities(uint32_t peer_idx)
2240 {
2241  //double probs[num_peers] = { 0 };
2242  double probs[num_peers];
2243  double probs_hist[num_peers]; /* Probability respecting the history */
2244  size_t probs_as_str_size = (num_peers * 10 + 2) * sizeof(char);
2245  char *probs_as_str = GNUNET_malloc(probs_as_str_size);
2246  char *probs_as_str_cpy;
2247  uint32_t i;
2248  double prob_push;
2249  double prob_pull;
2250  uint32_t view_size;
2251  uint32_t cont_views;
2252  uint32_t number_of_being_in_pull_events;
2253  int tmp;
2254  double sum_non_zero_prob = 0;
2255  double sum_non_zero_prob_hist = 0;
2256 
2258  "Computing probabilities for peer %" PRIu32 "\n", peer_idx);
2259  /* Firstly without knowledge of old views */
2260  for (i = 0; i < num_peers; i++)
2261  {
2263  "\tfor peer %" PRIu32 ":\n", i);
2264  view_size = rps_peers[i].cur_view_count;
2266  "\t\tview_size: %" PRIu32 "\n", view_size);
2267  /* For peer i the probability of being sampled is
2268  * evenly distributed among all possibly observed peers. */
2269  /* We could have observed a peer in three cases:
2270  * 1. peer sent a push
2271  * 2. peer was contained in a pull reply
2272  * 3. peer was in history (sampler) - ignored for now */
2273  /* 1. Probability of having received a push from peer i */
2274  if ((GNUNET_YES == is_in_view(i, peer_idx)) &&
2275  (1 <= (0.45 * view_size)))
2276  {
2277  if (0 == binom(view_size, 0.45 * view_size))
2278  prob_push = 0;
2279  else
2280  {
2281  prob_push = 1.0 * binom(0.45 * view_size, 1)
2282  /
2283  binom(view_size, 0.45 * view_size);
2284  }
2286  "\t\t%" PRIu32 " is in %" PRIu32 "'s view, prob: %f\n",
2287  peer_idx,
2288  i,
2289  prob_push);
2291  "\t\tposs choices from view: %" PRIu32 ", containing i: %" PRIu32 "\n",
2292  binom(view_size, 0.45 * view_size),
2293  binom(0.45 * view_size, 1));
2294  }
2295  else
2296  {
2297  prob_push = 0;
2299  "\t\t%" PRIu32 " is not in %" PRIu32 "'s view, prob: 0\n",
2300  peer_idx,
2301  i);
2302  }
2303  /* 2. Probability of peer i being contained in pulls */
2304  view_size = rps_peers[peer_idx].cur_view_count;
2305  cont_views = count_containing_views(peer_idx, i);
2306  number_of_being_in_pull_events =
2307  (binom(view_size, 0.45 * view_size) -
2308  binom(view_size - cont_views, 0.45 * view_size));
2309  if (0 != number_of_being_in_pull_events)
2310  {
2311  prob_pull = number_of_being_in_pull_events
2312  /
2313  (1.0 * binom(view_size, 0.45 * view_size));
2314  }
2315  else
2316  {
2317  prob_pull = 0;
2318  }
2319  probs[i] = prob_push + prob_pull - (prob_push * prob_pull);
2321  "\t\t%" PRIu32 " has %" PRIu32 " of %" PRIu32
2322  " peers in its view who know %" PRIu32 " prob: %f\n",
2323  peer_idx,
2324  cont_views,
2325  view_size,
2326  i,
2327  prob_pull);
2329  "\t\tnumber of possible pull combinations: %" PRIu32 "\n",
2330  binom(view_size, 0.45 * view_size));
2332  "\t\tnumber of possible pull combinations without %" PRIu32
2333  ": %" PRIu32 "\n",
2334  i,
2335  binom(view_size - cont_views, 0.45 * view_size));
2337  "\t\tnumber of possible pull combinations with %" PRIu32
2338  ": %" PRIu32 "\n",
2339  i,
2340  number_of_being_in_pull_events);
2341 
2342  probs_hist[i] = 0.9 * rps_peers[peer_idx].eval_probs_cache[i] + probs[i];
2343  rps_peers[peer_idx].eval_probs_cache[i] = probs_hist[i];
2344 
2345  sum_non_zero_prob += probs[i];
2346  sum_non_zero_prob_hist += probs_hist[i];
2347  }
2348  /* normalize */
2349  if (0 != sum_non_zero_prob)
2350  {
2351  for (i = 0; i < num_peers; i++)
2352  {
2353  probs[i] = probs[i] * (1.0 / sum_non_zero_prob);
2354  }
2355  }
2356  if (0 != sum_non_zero_prob_hist)
2357  {
2358  for (i = 0; i < num_peers; i++)
2359  {
2360  probs_hist[i] = probs_hist[i] * (1.0 / sum_non_zero_prob_hist);
2361  }
2362  }
2363 
2364  /* str repr */
2365  for (i = 0; i < num_peers; i++)
2366  {
2367  probs_as_str_cpy = GNUNET_strndup(probs_as_str, probs_as_str_size);
2368  tmp = GNUNET_snprintf(probs_as_str,
2369  probs_as_str_size,
2370  "%s %7.6f", probs_as_str_cpy, probs[i]);
2371  GNUNET_free(probs_as_str_cpy);
2372  GNUNET_assert(0 <= tmp);
2373  }
2374 
2375  to_file_w_len(rps_peers[peer_idx].file_name_probs,
2376  probs_as_str_size,
2377  probs_as_str);
2378 
2379  probs_as_str[0] = '\0';
2380  for (i = 0; i < num_peers; i++)
2381  {
2382  probs_as_str_cpy = GNUNET_strndup(probs_as_str, probs_as_str_size);
2383  tmp = GNUNET_snprintf(probs_as_str,
2384  probs_as_str_size,
2385  "%s %7.6f", probs_as_str_cpy, probs_hist[i]);
2386  GNUNET_free(probs_as_str_cpy);
2387  GNUNET_assert(0 <= tmp);
2388  }
2389 
2390  to_file_w_len(rps_peers[peer_idx].file_name_probs_hist,
2391  probs_as_str_size,
2392  probs_as_str);
2393  GNUNET_free(probs_as_str);
2394 }
2395 
2405 static uint32_t count_peer_in_views_2(uint32_t peer_idx)
2406 {
2407  uint32_t i, j;
2408  uint32_t count = 0;
2409 
2410  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2411  {
2412  for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2413  {
2414  if (0 == memcmp(rps_peers[peer_idx].peer_id,
2415  &rps_peers[i].cur_view[j],
2416  sizeof(struct GNUNET_PeerIdentity)))
2417  {
2418  count++;
2419  break;
2420  }
2421  }
2422  }
2423  rps_peers[peer_idx].count_in_views = count;
2424  return count;
2425 }
2426 
2427 static uint32_t cumulated_view_sizes()
2428 {
2429  uint32_t i;
2430 
2431  view_sizes = 0;
2432  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2433  {
2434  view_sizes += rps_peers[i].cur_view_count;
2435  }
2436  return view_sizes;
2437 }
2438 
2439 static void count_peer_in_views(uint32_t *count_peers)
2440 {
2441  uint32_t i, j;
2442 
2443  for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2444  {
2445  for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2446  {
2447  if (0 == memcmp(rps_peers[i].peer_id,
2448  &rps_peers[i].cur_view[j],
2449  sizeof(struct GNUNET_PeerIdentity)))
2450  {
2451  count_peers[i]++;
2452  }
2453  }
2454  }
2455 }
2456 
2458 {
2459  uint32_t i;
2460  /* ith entry represents the numer of occurrences in other peer's views */
2461  uint32_t *count_peers = GNUNET_new_array(num_peers, uint32_t);
2462  uint32_t views_total_size;
2463  double expected;
2464  /* deviation from expected number of peers */
2465  double *deviation = GNUNET_new_array(num_peers, double);
2466 
2467  views_total_size = 0;
2468  expected = 0;
2469 
2470  /* For each peer count its representation in other peer's views*/
2471  for (i = 0; i < num_peers; i++) /* Peer to count */
2472  {
2473  views_total_size += rps_peers[i].cur_view_count;
2474  count_peer_in_views(count_peers);
2476  "Counted representation of %" PRIu32 "th peer [%s]: %" PRIu32 "\n",
2477  i,
2478  GNUNET_i2s(rps_peers[i].peer_id),
2479  count_peers[i]);
2480  }
2481 
2483  "size of all views combined: %" PRIu32 "\n",
2484  views_total_size);
2485  expected = ((double)1 / num_peers) * views_total_size;
2487  "Expected number of occurrences of each peer in all views: %f\n",
2488  expected);
2489  for (i = 0; i < num_peers; i++) /* Peer to count */
2490  {
2491  deviation[i] = expected - count_peers[i];
2493  "Deviation from expectation: %f\n", deviation[i]);
2494  }
2495  GNUNET_free(count_peers);
2496  GNUNET_free(deviation);
2497 }
2498 
2500 {
2501  uint32_t i;
2502 
2503  for (i = 0; i < num_peers; i++) /* Peer to count */
2504  {
2506  "View size of %" PRIu32 ". [%s] is %" PRIu32 "\n",
2507  i,
2508  GNUNET_i2s(rps_peers[i].peer_id),
2509  rps_peers[i].cur_view_count);
2510  }
2511 }
2512 
2514 {
2516  print_view_sizes();
2517 }
2518 
2519 void view_update_cb(void *cls,
2520  uint64_t view_size,
2521  const struct GNUNET_PeerIdentity *peers)
2522 {
2524  "View was updated (%" PRIu64 ")\n", view_size);
2525  struct RPSPeer *rps_peer = (struct RPSPeer *)cls;
2526  to_file("/tmp/rps/view_sizes.txt",
2527  "%" PRIu64 " %" PRIu32 "",
2528  rps_peer->index,
2529  view_size);
2530  for (uint64_t i = 0; i < view_size; i++)
2531  {
2533  "\t%s\n", GNUNET_i2s(&peers[i]));
2534  }
2535  GNUNET_array_grow(rps_peer->cur_view,
2536  rps_peer->cur_view_count,
2537  view_size);
2538  //*rps_peer->cur_view = *peers;
2539  GNUNET_memcpy(rps_peer->cur_view,
2540  peers,
2541  view_size * sizeof(struct GNUNET_PeerIdentity));
2542  to_file("/tmp/rps/count_in_views.txt",
2543  "%" PRIu64 " %" PRIu32 "",
2544  rps_peer->index,
2545  count_peer_in_views_2(rps_peer->index));
2547  if (0 != view_size)
2548  {
2549  to_file("/tmp/rps/repr.txt",
2550  "%" PRIu64 /* index */
2551  " %" PRIu32 /* occurrence in views */
2552  " %" PRIu32 /* view sizes */
2553  " %f" /* fraction of repr in views */
2554  " %f" /* average view size */
2555  " %f" /* prob of occurrence in view slot */
2556  " %f" "", /* exp frac of repr in views */
2557  rps_peer->index,
2558  count_peer_in_views_2(rps_peer->index),
2559  view_sizes,
2560  count_peer_in_views_2(rps_peer->index) / (view_size * 1.0), /* fraction of representation in views */
2561  view_sizes / (view_size * 1.0), /* average view size */
2562  1.0 / view_size, /* prob of occurrence in view slot */
2563  (1.0 / view_size) * (view_sizes / view_size) /* expected fraction of repr in views */
2564  );
2565  }
2566  compute_probabilities(rps_peer->index);
2568 }
2569 
2570 static void
2571 pre_profiler(struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
2572 {
2573  rps_peer->file_name_probs =
2574  store_prefix_file_name(rps_peer->index, "probs");
2575  rps_peer->file_name_probs_hist =
2576  store_prefix_file_name(rps_peer->index, "probs_hist");
2577  GNUNET_RPS_view_request(h, 0, view_update_cb, rps_peer);
2578 }
2579 
2581 {
2582  uint64_t sums[STAT_TYPE_MAX] = { 0 };
2583 
2584  for (uint32_t i = 0; i < num_peers; i++)
2585  {
2586  to_file("/tmp/rps/final_stats.csv",
2587  "%" PRIu32 ", " /* index */
2588  "%s, %" /* id */
2589  PRIu64 ", %" /* rounds */
2590  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* blocking */
2591  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* issued */
2592  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* sent */
2593  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* recv */
2594  PRIu64 ", %" /* view size */
2595  PRIu64 ", %" /* known peers */
2596  PRIu64 ", %" /* valid peers */
2597  PRIu64 ", %" /* learned peers */
2598  PRIu64 ", %" /* pending online checks */
2599  PRIu64 ", %" /* unrequested pull replies */
2600  PRIu64 ", %" /* peers in push map */
2601  PRIu64 ", %" /* peers in pull map */
2602  PRIu64 ", %" /* peers in view */
2603  PRIu64 "\n" /* view size aim */,
2604  i,
2605  GNUNET_i2s(rps_peers[i].peer_id),
2606  rps_peers[i].stats[STAT_TYPE_ROUNDS],
2607  rps_peers[i].stats[STAT_TYPE_BLOCKS],
2608  rps_peers[i].stats[STAT_TYPE_BLOCKS_MANY_PUSH],
2609  rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PUSH],
2610  rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PULL],
2613  rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND],
2614  rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND_MH],
2615  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ],
2616  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ_MH],
2617  rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REP],
2618  rps_peers[i].stats[STAT_TYPE_SENT_PUSH_SEND],
2619  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ],
2620  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ_MH],
2621  rps_peers[i].stats[STAT_TYPE_SENT_PULL_REP],
2622  rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND],
2623  rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND_MH],
2624  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ],
2625  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ_MH],
2626  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP_MH],
2627  rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP],
2628  rps_peers[i].stats[STAT_TYPE_VIEW_SIZE],
2629  rps_peers[i].stats[STAT_TYPE_KNOWN_PEERS],
2630  rps_peers[i].stats[STAT_TYPE_VALID_PEERS],
2631  rps_peers[i].stats[STAT_TYPE_LEARND_PEERS],
2632  rps_peers[i].stats[STAT_TYPE_PENDING_ONLINE_CHECKS],
2634  rps_peers[i].stats[STAT_TYPE_PEERS_IN_PUSH_MAP],
2635  rps_peers[i].stats[STAT_TYPE_PEERS_IN_PULL_MAP],
2636  rps_peers[i].stats[STAT_TYPE_PEERS_IN_VIEW],
2637  rps_peers[i].stats[STAT_TYPE_VIEW_SIZE_AIM]);
2638  for (enum STAT_TYPE stat_type = STAT_TYPE_ROUNDS;
2640  stat_type++)
2641  {
2642  sums[stat_type] += rps_peers[i].stats[stat_type];
2643  }
2644  }
2645  to_file("/tmp/rps/final_stats.dat",
2646  "SUM %"
2647  PRIu64 " %" /* rounds */
2648  PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" /* blocking */
2649  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* issued */
2650  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* sent */
2651  PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* recv */
2652  PRIu64 ", %" /* view size */
2653  PRIu64 ", %" /* known peers */
2654  PRIu64 ", %" /* valid peers */
2655  PRIu64 ", %" /* learned peers */
2656  PRIu64 ", %" /* pending online checks */
2657  PRIu64 ", %" /* unrequested pull replies */
2658  PRIu64 ", %" /* peers in push map */
2659  PRIu64 ", %" /* peers in pull map */
2660  PRIu64 ", %" /* peers in view */
2661  PRIu64 "\n" /* view size aim */,
2662  sums[STAT_TYPE_ROUNDS],
2663  sums[STAT_TYPE_BLOCKS],
2684  sums[STAT_TYPE_VIEW_SIZE],
2685  sums[STAT_TYPE_KNOWN_PEERS],
2686  sums[STAT_TYPE_VALID_PEERS],
2687  sums[STAT_TYPE_LEARND_PEERS],
2693  sums[STAT_TYPE_VIEW_SIZE_AIM]);
2694 }
2695 
2707 void
2709  int success)
2710 {
2711  struct STATcls *stat_cls = (struct STATcls *)cls;
2712  struct RPSPeer *rps_peer = stat_cls->rps_peer;
2713 
2714  rps_peer->h_stat_get[stat_cls->stat_type] = NULL;
2715  if (GNUNET_OK == success)
2716  {
2717  /* set flag that we we got the value */
2718  rps_peer->stat_collected_flags |= BIT(stat_cls->stat_type);
2719  }
2720  else
2721  {
2723  "Peer %u did not receive statistics value\n",
2724  rps_peer->index);
2725  GNUNET_free(stat_cls);
2726  GNUNET_break(0);
2727  return;
2728  }
2729 
2730  if (NULL != rps_peer->stat_op &&
2732  {
2734  }
2735 
2738  {
2739  //write_final_stats ();
2740  GNUNET_free(stat_cls);
2742  "Shutting down\n");
2744  }
2745  else
2746  {
2747  GNUNET_free(stat_cls);
2748  }
2749 }
2750 
2761 int
2762 stat_iterator(void *cls,
2763  const char *subsystem,
2764  const char *name,
2765  uint64_t value,
2766  int is_persistent)
2767 {
2768  const struct STATcls *stat_cls = (const struct STATcls *)cls;
2769  struct RPSPeer *rps_peer = (struct RPSPeer *)stat_cls->rps_peer;
2770  enum STAT_TYPE stat_type;
2771 
2772  (void)subsystem;
2773  (void)is_persistent;
2774 
2776  "Got stat value: %s - %" PRIu64 " (%u)\n",
2777  name,
2778  value,
2779  rps_peer->index);
2780  to_file(rps_peer->file_name_stats,
2781  "%s: %" PRIu64 "\n",
2782  name,
2783  value);
2784  stat_type = stat_str_2_type(name);
2787  rps_peer->stats[stat_type] = value;
2788  return GNUNET_OK;
2789 }
2790 
2791 
2792 void
2793 post_profiler(struct RPSPeer *rps_peer)
2794 {
2796  {
2797  return;
2798  }
2799 
2801  "Going to request statistic values with mask 0x%" PRIx32 "\n",
2803 
2804  struct STATcls *stat_cls;
2805  uint32_t stat_type;
2806  for (stat_type = STAT_TYPE_ROUNDS;
2807  stat_type < STAT_TYPE_MAX;
2808  stat_type++)
2809  {
2810  if (BIT(stat_type) & cur_test_run.stat_collect_flags)
2811  {
2812  stat_cls = GNUNET_malloc(sizeof(struct STATcls));
2813  stat_cls->rps_peer = rps_peer;
2814  stat_cls->stat_type = stat_type;
2815  rps_peer->file_name_stats =
2816  store_prefix_file_name(rps_peer->peer_id, "stats");
2817  rps_peer->h_stat_get[stat_type] =
2818  GNUNET_STATISTICS_get(rps_peer->stats_h,
2819  "rps",
2820  stat_type_strings [stat_type],
2822  stat_iterator,
2823  (struct STATcls *)stat_cls);
2824  GNUNET_assert(NULL != rps_peer->h_stat_get);
2826  "Requested statistics for %s (peer %" PRIu32 ")\n",
2827  stat_type_strings [stat_type],
2828  rps_peer->index);
2829  }
2830  }
2831  GNUNET_free(rps_peer->eval_probs_cache);
2832 }
2833 
2834 
2835 /***********************************************************************
2836 * /Definition of tests
2837 ***********************************************************************/
2838 
2839 
2852 static void
2853 test_run(void *cls,
2854  struct GNUNET_TESTBED_RunHandle *h,
2855  unsigned int n_peers,
2856  struct GNUNET_TESTBED_Peer **peers,
2857  unsigned int links_succeeded,
2858  unsigned int links_failed)
2859 {
2860  unsigned int i;
2861  struct OpListEntry *entry;
2862 
2863  (void)cls;
2864  (void)h;
2865  (void)links_failed;
2866 
2867  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "RUN was called\n");
2868 
2869  /* Check whether we timed out */
2870  if (n_peers != num_peers ||
2871  NULL == peers ||
2872  0 == links_succeeded)
2873  {
2874  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Going down due to args (eg. timeout)\n");
2875  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "\tn_peers: %u\n", n_peers);
2876  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "\tnum_peers: %" PRIu32 "\n", num_peers);
2877  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "\tpeers: %p\n", peers);
2878  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "\tlinks_succeeded: %u\n", links_succeeded);
2879  ok = 1;
2881  return;
2882  }
2883 
2884 
2885  /* Initialize peers */
2886  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "going to initialise peers\n");
2887  testbed_peers = peers;
2888  num_peers_online = 0;
2889  for (i = 0; i < num_peers; i++)
2890  {
2891  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "initialising %u\n", i);
2892  entry = make_oplist_entry();
2893  entry->index = i;
2894  rps_peers[i].index = i;
2895  if (NULL != cur_test_run.init_peer)
2896  cur_test_run.init_peer(&rps_peers[i]);
2898  {
2899  rps_peers->cur_view_count = 0;
2900  rps_peers->cur_view = NULL;
2901  }
2902  entry->op = GNUNET_TESTBED_peer_get_information(peers[i],
2904  &info_cb,
2905  entry);
2906  }
2907 
2908  /* Bring peers up */
2909  GNUNET_assert(num_peers == n_peers);
2910  for (i = 0; i < n_peers; i++)
2911  {
2912  rps_peers[i].index = i;
2913  rps_peers[i].op =
2914  GNUNET_TESTBED_service_connect(&rps_peers[i],
2915  peers[i],
2916  "rps",
2918  &rps_peers[i],
2921  &rps_peers[i]);
2922  /* Connect all peers to statistics service */
2924  {
2926  "Connecting to statistics service\n");
2927  rps_peers[i].stat_op =
2929  peers[i],
2930  "statistics",
2932  &rps_peers[i],
2935  &rps_peers[i]);
2936  }
2937  }
2938 
2939  if (NULL != churn_task)
2940  GNUNET_SCHEDULER_cancel(churn_task);
2941  post_test_task = GNUNET_SCHEDULER_add_delayed(duration, &post_test_op, NULL);
2942  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "timeout for shutdown is %lu\n", timeout.rel_value_us / 1000000);
2943  shutdown_task = GNUNET_SCHEDULER_add_delayed(timeout,
2945  NULL);
2947 }
2948 
2949 
2956 static void
2957 run(void *cls,
2958  char *const *args,
2959  const char *cfgfile,
2960  const struct GNUNET_CONFIGURATION_Handle *cfg)
2961 {
2962  //int ret_value;
2963  (void)cls;
2964  (void)args;
2965  (void)cfgfile;
2966 
2967  /* Defaults for tests */
2968  churn_task = NULL;
2969 
2970  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n");
2971  cur_test_run.name = "test-rps-profiler";
2972  if (0 == num_peers)
2973  num_peers = 10;
2974  mal_type = 3;
2976  //cur_test_run.pre_test = mal_pre;
2983  if (0 == cur_test_run.num_requests)
2985  //cur_test_run.have_churn = HAVE_CHURN;
3022 
3023  /* 'Clean' directory */
3024  (void)GNUNET_DISK_directory_remove("/tmp/rps/");
3025  GNUNET_DISK_directory_create("/tmp/rps/");
3026  if (0 == duration.rel_value_us)
3027  {
3028  if (0 == timeout.rel_value_us)
3029  {
3032  (90 * 1.2) +
3033  (0.01 * num_peers));
3034  }
3035  else
3036  {
3038  (timeout.rel_value_us / 1000000)
3039  * 0.75);
3040  }
3041  }
3042  else
3043  {
3044  if (0 == timeout.rel_value_us)
3045  {
3047  ((duration.rel_value_us / 1000000)
3048  * 1.2) + (0.01 * num_peers));
3049  }
3050  }
3053  "duration is %lus\n",
3054  duration.rel_value_us / 1000000);
3056  "timeout is %lus\n",
3057  timeout.rel_value_us / 1000000);
3058 
3059  /* Compute number of bits for representing largest peer id */
3060  for (bits_needed = 1; (1 << bits_needed) < num_peers; bits_needed++)
3061  ;
3063  "Need %u bits to represent %" PRIu32 " peers\n",
3064  bits_needed,
3065  num_peers);
3066 
3067  rps_peers = GNUNET_new_array(num_peers, struct RPSPeer);
3069  rps_peer_ids = GNUNET_new_array(num_peers, struct GNUNET_PeerIdentity);
3070  if ((2 == mal_type) ||
3071  (3 == mal_type))
3072  target_peer = &rps_peer_ids[num_peers - 2];
3073 
3074  ok = 1;
3075  GNUNET_TESTBED_run(NULL,
3076  cfg,
3077  num_peers,
3078  0, /* event mask */
3079  NULL,
3080  NULL,
3081  &test_run,
3082  NULL);
3083 }
3084 
3092 int
3093 main(int argc, char *argv[])
3094 {
3095  int ret_value;
3096  struct GNUNET_GETOPT_CommandLineOption options[] = {
3098  "num-peers",
3099  "COUNT",
3100  gettext_noop("number of peers to start"),
3101  &num_peers),
3103  "duration",
3104  "DURATION",
3105  gettext_noop("duration of the profiling"),
3106  &duration),
3108  "timeout",
3109  "TIMEOUT",
3110  gettext_noop("timeout for the profiling"),
3111  &timeout),
3113  "num-requests",
3114  "COUNT",
3115  gettext_noop("number of PeerIDs to request"),
3118  };
3119 
3120  unsetenv("XDG_DATA_HOME");
3121  unsetenv("XDG_CONFIG_HOME");
3122  //if (GNUNET_OK !=
3123  // GNUNET_STRINGS_get_utf8_args (argc, argv,
3124  // &argc, &argv))
3125  // return 2;
3126  ret_value = 0;
3127  if (GNUNET_OK !=
3128  GNUNET_PROGRAM_run(argc,
3129  argv,
3130  "gnunet-rps-profiler",
3131  gettext_noop("Measure quality and performance of the RPS service."),
3132  options,
3133  &run,
3134  NULL))
3135  {
3136  ret_value = 1;
3137  }
3138  if (0 != ret_value)
3139  {
3141  "Test did not run successfully!\n");
3142  }
3143  else
3144  {
3145  ret_value = cur_test_run.eval_cb();
3147  {
3148  GNUNET_array_grow(rps_peers->cur_view,
3149  rps_peers->cur_view_count,
3150  0);
3151  }
3152  GNUNET_free(rps_peers);
3153  GNUNET_free(rps_peer_ids);
3155  }
3156  return ret_value;
3157 }
3158 
3159 /* 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:1339
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:1028
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:586
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:1284
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:456
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:243
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:909
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:1249
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:517
Handle for the service.
Handler to handle requests from a client.
Definition: rps_api.c:77
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:835
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:1237
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: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:817
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:1264
int GNUNET_DISK_directory_remove(const char *filename)
Remove all files in a directory (rm -rf).
Definition: disk.c:1026
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:440
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:987
void GNUNET_TESTBED_operation_done(struct GNUNET_TESTBED_Operation *operation)
This function is used to signal that the event information (struct GNUNET_TESTBED_EventInformation) f...
Definition: testbed_api.c:2037
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:209
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:66
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:83
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:131
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: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:1262
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:956