aboutsummaryrefslogtreecommitdiff
path: root/src/rps
diff options
context:
space:
mode:
Diffstat (limited to 'src/rps')
-rw-r--r--src/rps/Makefile.am24
-rw-r--r--src/rps/gnunet-rps-profiler.c2732
-rw-r--r--src/rps/gnunet-rps.c18
-rw-r--r--src/rps/gnunet-service-rps.c18
-rw-r--r--src/rps/gnunet-service-rps_custommap.c18
-rw-r--r--src/rps/gnunet-service-rps_custommap.h18
-rw-r--r--src/rps/gnunet-service-rps_sampler.c18
-rw-r--r--src/rps/gnunet-service-rps_sampler.h18
-rw-r--r--src/rps/gnunet-service-rps_sampler_elem.c18
-rw-r--r--src/rps/gnunet-service-rps_sampler_elem.h18
-rw-r--r--src/rps/gnunet-service-rps_view.c18
-rw-r--r--src/rps/gnunet-service-rps_view.h18
-rw-r--r--src/rps/rps-test_util.c174
-rw-r--r--src/rps/rps-test_util.h27
-rw-r--r--src/rps/rps.conf.in2
-rw-r--r--src/rps/rps.h18
-rw-r--r--src/rps/rps_api.c18
-rw-r--r--src/rps/test_rps.c126
-rw-r--r--src/rps/test_rps.conf2
-rw-r--r--src/rps/test_rps_api.c18
-rw-r--r--src/rps/test_service_rps_custommap.c18
-rw-r--r--src/rps/test_service_rps_sampler_elem.c18
-rw-r--r--src/rps/test_service_rps_view.c18
23 files changed, 3151 insertions, 224 deletions
diff --git a/src/rps/Makefile.am b/src/rps/Makefile.am
index b5f712268..d477ade92 100644
--- a/src/rps/Makefile.am
+++ b/src/rps/Makefile.am
@@ -83,17 +83,18 @@ check_PROGRAMS = \
83 test_rps_churn 83 test_rps_churn
84endif 84endif
85 85
86rps_test_src = \
87 test_rps.c \
88 rps-test_util.h rps-test_util.c \
89 gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c
90
86ld_rps_test_lib = \ 91ld_rps_test_lib = \
87 libgnunetrps.la \ 92 libgnunetrps.la \
88 $(top_builddir)/src/util/libgnunetutil.la \ 93 $(top_builddir)/src/util/libgnunetutil.la \
94 $(top_builddir)/src/statistics/libgnunetstatistics.la \
89 $(top_builddir)/src/testbed/libgnunettestbed.la \ 95 $(top_builddir)/src/testbed/libgnunettestbed.la \
90 -lm 96 -lm
91 97
92rps_test_src = \
93 test_rps.c \
94 rps-test_util.h rps-test_util.c \
95 gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c
96
97if ENABLE_TEST_RUN 98if ENABLE_TEST_RUN
98AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; 99AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
99TESTS = $(check_PROGRAMS) 100TESTS = $(check_PROGRAMS)
@@ -140,10 +141,19 @@ test_rps_seed_big_LDADD = $(ld_rps_test_lib)
140test_rps_churn_SOURCES = $(rps_test_src) 141test_rps_churn_SOURCES = $(rps_test_src)
141test_rps_churn_LDADD = $(ld_rps_test_lib) 142test_rps_churn_LDADD = $(ld_rps_test_lib)
142 143
143gnunet_rps_profiler_SOURCES = $(rps_test_src) 144gnunet_rps_profiler_SOURCES = \
145 gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \
146 rps-test_util.h rps-test_util.c \
147 gnunet-rps-profiler.c
148
149
144gnunet_rps_profiler_LDADD = \ 150gnunet_rps_profiler_LDADD = \
145 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 151 $(top_builddir)/src/statistics/libgnunetstatistics.la \
146 $(ld_rps_test_lib) 152 libgnunetrps.la \
153 $(top_builddir)/src/util/libgnunetutil.la \
154 $(top_builddir)/src/testbed/libgnunettestbed.la \
155 -lm
156
147 157
148EXTRA_DIST = \ 158EXTRA_DIST = \
149 test_rps.conf 159 test_rps.conf
diff --git a/src/rps/gnunet-rps-profiler.c b/src/rps/gnunet-rps-profiler.c
new file mode 100644
index 000000000..4a7a89b15
--- /dev/null
+++ b/src/rps/gnunet-rps-profiler.c
@@ -0,0 +1,2732 @@
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/**
19 * @file rps/test_rps.c
20 * @brief Testcase for the random peer sampling service. Starts
21 * a peergroup with a given number of peers, then waits to
22 * receive size pushes/pulls from each peer. Expects to wait
23 * for one message from each peer.
24 */
25#include "platform.h"
26//#include "rps_test_lib.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_testbed_service.h"
29
30#include "gnunet_rps_service.h"
31#include "rps-test_util.h"
32#include "gnunet-service-rps_sampler_elem.h"
33
34#include <inttypes.h>
35
36
37#define BIT(n) (1 << (n))
38
39/**
40 * How many peers do we start?
41 */
42static uint32_t num_peers;
43
44/**
45 * @brief numer of bits required to represent the largest peer id
46 */
47static unsigned bits_needed;
48
49/**
50 * How long do we run the test?
51 * In seconds.
52 */
53static uint32_t timeout_s;
54
55/**
56 * How long do we run the test?
57 */
58//#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
59static struct GNUNET_TIME_Relative timeout;
60
61
62/**
63 * Portion of malicious peers
64 */
65static double portion = .1;
66
67/**
68 * Type of malicious peer to test
69 */
70static unsigned int mal_type = 0;
71
72/**
73 * Handles to all of the running peers
74 */
75static struct GNUNET_TESTBED_Peer **testbed_peers;
76
77enum STAT_TYPE
78{
79 STAT_TYPE_ROUNDS, /* 0 */
80 STAT_TYPE_BLOCKS, /* 1 */
81 STAT_TYPE_BLOCKS_MANY_PUSH, /* 2 */
82 STAT_TYPE_BLOCKS_NO_PUSH, /* 3 */
83 STAT_TYPE_BLOCKS_NO_PULL, /* 4 */
84 STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL, /* 5 */
85 STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL, /* 6 */
86 STAT_TYPE_ISSUED_PUSH_SEND, /* 7 */
87 STAT_TYPE_ISSUED_PULL_REQ, /* 8 */
88 STAT_TYPE_ISSUED_PULL_REP, /* 9 */
89 STAT_TYPE_SENT_PUSH_SEND, /* 10 */
90 STAT_TYPE_SENT_PULL_REQ, /* 11 */
91 STAT_TYPE_SENT_PULL_REP, /* 12 */
92 STAT_TYPE_RECV_PUSH_SEND, /* 13 */
93 STAT_TYPE_RECV_PULL_REQ, /* 14 */
94 STAT_TYPE_RECV_PULL_REP, /* 15 */
95 STAT_TYPE_MAX, /* 16 */
96};
97
98struct STATcls
99{
100 struct RPSPeer *rps_peer;
101 enum STAT_TYPE stat_type;
102};
103
104
105/**
106 * @brief Converts string representation to the corresponding #STAT_TYPE enum.
107 *
108 * @param stat_str string representation of statistics specifier
109 *
110 * @return corresponding enum
111 */
112enum STAT_TYPE stat_str_2_type (const char *stat_str)
113{
114 if (0 == strncmp ("# rounds blocked - no pull replies", stat_str, strlen ("# rounds blocked - no pull replies")))
115 {
116 return STAT_TYPE_BLOCKS_NO_PULL;
117 }
118 else if (0 == strncmp ("# rounds blocked - too many pushes, no pull replies", stat_str, strlen ("# rounds blocked - too many pushes, no pull replies")))
119 {
120 return STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL;
121 }
122 else if (0 == strncmp ("# rounds blocked - too many pushes", stat_str, strlen ("# rounds blocked - too many pushes")))
123 {
124 return STAT_TYPE_BLOCKS_MANY_PUSH;
125 }
126 else if (0 == strncmp ("# rounds blocked - no pushes, no pull replies", stat_str, strlen ("# rounds blocked - no pushes, no pull replies")))
127 {
128 return STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL;
129 }
130 else if (0 == strncmp ("# rounds blocked - no pushes", stat_str, strlen ("# rounds blocked - no pushes")))
131 {
132 return STAT_TYPE_BLOCKS_NO_PUSH;
133 }
134 else if (0 == strncmp ("# rounds blocked", stat_str, strlen ("# rounds blocked")))
135 {
136 return STAT_TYPE_BLOCKS;
137 }
138 else if (0 == strncmp ("# rounds", stat_str, strlen ("# rounds")))
139 {
140 return STAT_TYPE_ROUNDS;
141 }
142 else if (0 == strncmp ("# push send issued", stat_str, strlen ("# push send issued")))
143 {
144 return STAT_TYPE_ISSUED_PUSH_SEND;
145 }
146 else if (0 == strncmp ("# pull request send issued", stat_str, strlen ("# pull request send issued")))
147 {
148 return STAT_TYPE_ISSUED_PULL_REQ;
149 }
150 else if (0 == strncmp ("# pull reply send issued", stat_str, strlen ("# pull reply send issued")))
151 {
152 return STAT_TYPE_ISSUED_PULL_REP;
153 }
154 else if (0 == strncmp ("# pushes sent", stat_str, strlen ("# pushes sent")))
155 {
156 return STAT_TYPE_SENT_PUSH_SEND;
157 }
158 else if (0 == strncmp ("# pull requests sent", stat_str, strlen ("# pull requests sent")))
159 {
160 return STAT_TYPE_SENT_PULL_REQ;
161 }
162 else if (0 == strncmp ("# pull replys sent", stat_str, strlen ("# pull replys sent")))
163 {
164 return STAT_TYPE_SENT_PULL_REP;
165 }
166 else if (0 == strncmp ("# push message received", stat_str, strlen ("# push message received")))
167 {
168 return STAT_TYPE_RECV_PUSH_SEND;
169 }
170 else if (0 == strncmp ("# pull request message received", stat_str, strlen ("# pull request message received")))
171 {
172 return STAT_TYPE_RECV_PULL_REQ;
173 }
174 else if (0 == strncmp ("# pull reply messages received", stat_str, strlen ("# pull reply messages received")))
175 {
176 return STAT_TYPE_RECV_PULL_REP;
177 }
178 return STAT_TYPE_MAX;
179}
180
181
182/**
183 * @brief Converts #STAT_TYPE enum to the equivalent string representation that
184 * is stored with the statistics service.
185 *
186 * @param stat_type #STAT_TYPE enum
187 *
188 * @return string representation that matches statistics value
189 */
190char* stat_type_2_str (enum STAT_TYPE stat_type)
191{
192 switch (stat_type)
193 {
194 case STAT_TYPE_ROUNDS:
195 return "# rounds";
196 case STAT_TYPE_BLOCKS:
197 return "# rounds blocked";
198 case STAT_TYPE_BLOCKS_MANY_PUSH:
199 return "# rounds blocked - too many pushes";
200 case STAT_TYPE_BLOCKS_NO_PUSH:
201 return "# rounds blocked - no pushes";
202 case STAT_TYPE_BLOCKS_NO_PULL:
203 return "# rounds blocked - no pull replies";
204 case STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL:
205 return "# rounds blocked - too many pushes, no pull replies";
206 case STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL:
207 return "# rounds blocked - no pushes, no pull replies";
208 case STAT_TYPE_ISSUED_PUSH_SEND:
209 return "# push send issued";
210 case STAT_TYPE_ISSUED_PULL_REQ:
211 return "# pull request send issued";
212 case STAT_TYPE_ISSUED_PULL_REP:
213 return "# pull reply send issued";
214 case STAT_TYPE_SENT_PUSH_SEND:
215 return "# pushes sent";
216 case STAT_TYPE_SENT_PULL_REQ:
217 return "# pull requests sent";
218 case STAT_TYPE_SENT_PULL_REP:
219 return "# pull replys sent";
220 case STAT_TYPE_RECV_PUSH_SEND:
221 return "# push message received";
222 case STAT_TYPE_RECV_PULL_REQ:
223 return "# pull request message received";
224 case STAT_TYPE_RECV_PULL_REP:
225 return "# pull reply messages received";
226 case STAT_TYPE_MAX:
227 default:
228 return "ERROR";
229 ;
230 }
231}
232
233
234/**
235 * @brief Indicates whether peer should go off- or online
236 */
237enum PEER_ONLINE_DELTA {
238 /**
239 * @brief Indicates peer going online
240 */
241 PEER_GO_ONLINE = 1,
242 /**
243 * @brief Indicates peer going offline
244 */
245 PEER_GO_OFFLINE = -1,
246};
247
248/**
249 * Operation map entry
250 */
251struct OpListEntry
252{
253 /**
254 * DLL next ptr
255 */
256 struct OpListEntry *next;
257
258 /**
259 * DLL prev ptr
260 */
261 struct OpListEntry *prev;
262
263 /**
264 * The testbed operation
265 */
266 struct GNUNET_TESTBED_Operation *op;
267
268 /**
269 * Depending on whether we start or stop RPS service at the peer, set this to
270 * #PEER_GO_ONLINE (1) or #PEER_GO_OFFLINE (-1)
271 */
272 enum PEER_ONLINE_DELTA delta;
273
274 /**
275 * Index of the regarding peer
276 */
277 unsigned int index;
278};
279
280/**
281 * OpList DLL head
282 */
283static struct OpListEntry *oplist_head;
284
285/**
286 * OpList DLL tail
287 */
288static struct OpListEntry *oplist_tail;
289
290
291/**
292 * A pending reply: A request was sent and the reply is pending.
293 */
294struct PendingReply
295{
296 /**
297 * DLL next,prev ptr
298 */
299 struct PendingReply *next;
300 struct PendingReply *prev;
301
302 /**
303 * Handle to the request we are waiting for
304 */
305 struct GNUNET_RPS_Request_Handle *req_handle;
306
307 /**
308 * The peer that requested
309 */
310 struct RPSPeer *rps_peer;
311};
312
313
314/**
315 * A pending request: A request was not made yet but is scheduled for later.
316 */
317struct PendingRequest
318{
319 /**
320 * DLL next,prev ptr
321 */
322 struct PendingRequest *next;
323 struct PendingRequest *prev;
324
325 /**
326 * Handle to the request we are waiting for
327 */
328 struct GNUNET_SCHEDULER_Task *request_task;
329
330 /**
331 * The peer that requested
332 */
333 struct RPSPeer *rps_peer;
334};
335
336
337/**
338 * Information we track for each peer.
339 */
340struct RPSPeer
341{
342 /**
343 * Index of the peer.
344 */
345 unsigned int index;
346
347 /**
348 * Handle for RPS connect operation.
349 */
350 struct GNUNET_TESTBED_Operation *op;
351
352 /**
353 * Handle to RPS service.
354 */
355 struct GNUNET_RPS_Handle *rps_handle;
356
357 /**
358 * ID of the peer.
359 */
360 struct GNUNET_PeerIdentity *peer_id;
361
362 /**
363 * A request handle to check for an request
364 */
365 //struct GNUNET_RPS_Request_Handle *req_handle;
366
367 /**
368 * Peer on- or offline?
369 */
370 int online;
371
372 /**
373 * Number of Peer IDs to request during the whole test
374 */
375 unsigned int num_ids_to_request;
376
377 /**
378 * Pending requests DLL
379 */
380 struct PendingRequest *pending_req_head;
381 struct PendingRequest *pending_req_tail;
382
383 /**
384 * Number of pending requests
385 */
386 unsigned int num_pending_reqs;
387
388 /**
389 * Pending replies DLL
390 */
391 struct PendingReply *pending_rep_head;
392 struct PendingReply *pending_rep_tail;
393
394 /**
395 * Number of pending replies
396 */
397 unsigned int num_pending_reps;
398
399 /**
400 * Number of received PeerIDs
401 */
402 unsigned int num_recv_ids;
403
404 /**
405 * Pending operation on that peer
406 */
407 const struct OpListEntry *entry_op_manage;
408
409 /**
410 * Testbed operation to connect to statistics service
411 */
412 struct GNUNET_TESTBED_Operation *stat_op;
413
414 /**
415 * Handle to the statistics service
416 */
417 struct GNUNET_STATISTICS_Handle *stats_h;
418
419 /**
420 * @brief flags to indicate which statistics values have been already
421 * collected from the statistics service.
422 * Used to check whether we are able to shutdown.
423 */
424 uint32_t stat_collected_flags;
425
426 /**
427 * @brief File name of the file the stats are finally written to
428 */
429 const char *file_name_stats;
430
431 /**
432 * @brief File name of the file the stats are finally written to
433 */
434 const char *file_name_probs;
435
436 /**
437 * @brief The current view
438 */
439 struct GNUNET_PeerIdentity *cur_view;
440
441 /**
442 * @brief Number of peers in the #cur_view.
443 */
444 uint32_t cur_view_count;
445
446 /**
447 * @brief Number of occurrences in other peer's view
448 */
449 uint32_t count_in_views;
450
451 /**
452 * @brief statistics values
453 */
454 uint64_t stats[STAT_TYPE_MAX];
455};
456
457/**
458 * Information for all the peers.
459 */
460static struct RPSPeer *rps_peers;
461
462/**
463 * Peermap to get the index of a given peer ID quick.
464 */
465static struct GNUNET_CONTAINER_MultiPeerMap *peer_map;
466
467/**
468 * IDs of the peers.
469 */
470static struct GNUNET_PeerIdentity *rps_peer_ids;
471
472/**
473 * ID of the targeted peer.
474 */
475static struct GNUNET_PeerIdentity *target_peer;
476
477/**
478 * ID of the peer that requests for the evaluation.
479 */
480static struct RPSPeer *eval_peer;
481
482/**
483 * Number of online peers.
484 */
485static unsigned int num_peers_online;
486
487/**
488 * @brief The added sizes of the peer's views
489 */
490static unsigned int view_sizes;
491
492/**
493 * Return value from 'main'.
494 */
495static int ok;
496
497/**
498 * Identifier for the churn task that runs periodically
499 */
500static struct GNUNET_SCHEDULER_Task *post_test_task;
501
502/**
503 * Identifier for the churn task that runs periodically
504 */
505static struct GNUNET_SCHEDULER_Task *shutdown_task;
506
507/**
508 * Identifier for the churn task that runs periodically
509 */
510static struct GNUNET_SCHEDULER_Task *churn_task;
511
512/**
513 * Called to initialise the given RPSPeer
514 */
515typedef void (*InitPeer) (struct RPSPeer *rps_peer);
516
517/**
518 * @brief Called directly after connecting to the service
519 *
520 * @param rps_peer Specific peer the function is called on
521 * @param h the handle to the rps service
522 */
523typedef void (*PreTest) (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h);
524
525/**
526 * @brief Executes functions to test the api/service for a given peer
527 *
528 * Called from within #rps_connect_complete_cb ()
529 * Implemented by #churn_test_cb, #profiler_cb, #mal_cb, #single_req_cb,
530 * #delay_req_cb, #seed_big_cb, #single_peer_seed_cb, #seed_cb, #req_cancel_cb
531 *
532 * @param rps_peer the peer the task runs on
533 */
534typedef void (*MainTest) (struct RPSPeer *rps_peer);
535
536/**
537 * Callback called once the requested random peers are available
538 */
539typedef void (*ReplyHandle) (void *cls,
540 uint64_t n,
541 const struct GNUNET_PeerIdentity *recv_peers);
542
543/**
544 * Called directly before disconnecting from the service
545 */
546typedef void (*PostTest) (struct RPSPeer *peer);
547
548/**
549 * Function called after disconnect to evaluate test success
550 */
551typedef int (*EvaluationCallback) (void);
552
553/**
554 * @brief Do we have Churn?
555 */
556enum OPTION_CHURN {
557 /**
558 * @brief If we have churn this is set
559 */
560 HAVE_CHURN,
561 /**
562 * @brief If we have no churn this is set
563 */
564 HAVE_NO_CHURN,
565};
566
567/**
568 * @brief Is it ok to quit the test before the timeout?
569 */
570enum OPTION_QUICK_QUIT {
571 /**
572 * @brief It is ok for the test to quit before the timeout triggers
573 */
574 HAVE_QUICK_QUIT,
575
576 /**
577 * @brief It is NOT ok for the test to quit before the timeout triggers
578 */
579 HAVE_NO_QUICK_QUIT,
580};
581
582/**
583 * @brief Do we collect statistics at the end?
584 */
585enum OPTION_COLLECT_STATISTICS {
586 /**
587 * @brief We collect statistics at the end
588 */
589 COLLECT_STATISTICS,
590
591 /**
592 * @brief We do not collect statistics at the end
593 */
594 NO_COLLECT_STATISTICS,
595};
596
597/**
598 * @brief Do we collect views during run?
599 */
600enum OPTION_COLLECT_VIEW {
601 /**
602 * @brief We collect view during run
603 */
604 COLLECT_VIEW,
605
606 /**
607 * @brief We do not collect the view during run
608 */
609 NO_COLLECT_VIEW,
610};
611
612/**
613 * Structure to define a single test
614 */
615struct SingleTestRun
616{
617 /**
618 * Name of the test
619 */
620 char *name;
621
622 /**
623 * Called with a single peer in order to initialise that peer
624 */
625 InitPeer init_peer;
626
627 /**
628 * Called directly after connecting to the service
629 */
630 PreTest pre_test;
631
632 /**
633 * Main function for each peer
634 */
635 MainTest main_test;
636
637 /**
638 * Callback called once the requested peers are available
639 */
640 ReplyHandle reply_handle;
641
642 /**
643 * Called directly before disconnecting from the service
644 */
645 PostTest post_test;
646
647 /**
648 * Function to evaluate the test results
649 */
650 EvaluationCallback eval_cb;
651
652 /**
653 * Request interval
654 */
655 uint32_t request_interval;
656
657 /**
658 * Number of Requests to make.
659 */
660 uint32_t num_requests;
661
662 /**
663 * Run with (-out) churn
664 */
665 enum OPTION_CHURN have_churn;
666
667 /**
668 * Quit test before timeout?
669 */
670 enum OPTION_QUICK_QUIT have_quick_quit;
671
672 /**
673 * Collect statistics at the end?
674 */
675 enum OPTION_COLLECT_STATISTICS have_collect_statistics;
676
677 /**
678 * Collect view during run?
679 */
680 enum OPTION_COLLECT_VIEW have_collect_view;
681
682 /**
683 * @brief Mark which values from the statistics service to collect at the end
684 * of the run
685 */
686 uint32_t stat_collect_flags;
687} cur_test_run;
688
689/**
690 * Did we finish the test?
691 */
692static int post_test;
693
694/**
695 * Are we shutting down?
696 */
697static int in_shutdown;
698
699/**
700 * Append arguments to file
701 */
702static void
703tofile_ (const char *file_name, const char *line)
704{
705 struct GNUNET_DISK_FileHandle *f;
706 /* char output_buffer[512]; */
707 size_t size;
708 /* int size; */
709 size_t size2;
710
711 if (NULL == (f = GNUNET_DISK_file_open (file_name,
712 GNUNET_DISK_OPEN_APPEND |
713 GNUNET_DISK_OPEN_WRITE |
714 GNUNET_DISK_OPEN_CREATE,
715 GNUNET_DISK_PERM_USER_READ |
716 GNUNET_DISK_PERM_USER_WRITE |
717 GNUNET_DISK_PERM_GROUP_READ |
718 GNUNET_DISK_PERM_OTHER_READ)))
719 {
720 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
721 "Not able to open file %s\n",
722 file_name);
723 return;
724 }
725 /* size = GNUNET_snprintf (output_buffer,
726 sizeof (output_buffer),
727 "%llu %s\n",
728 GNUNET_TIME_absolute_get ().abs_value_us,
729 line);
730 if (0 > size)
731 {
732 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
733 "Failed to write string to buffer (size: %i)\n",
734 size);
735 return;
736 } */
737
738 size = strlen (line) * sizeof (char);
739
740 size2 = GNUNET_DISK_file_write (f, line, size);
741 if (size != size2)
742 {
743 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
744 "Unable to write to file! (Size: %lu, size2: %lu)\n",
745 size,
746 size2);
747 if (GNUNET_YES != GNUNET_DISK_file_close (f))
748 {
749 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
750 "Unable to close file\n");
751 }
752 return;
753 }
754
755 if (GNUNET_YES != GNUNET_DISK_file_close (f))
756 {
757 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
758 "Unable to close file\n");
759 }
760}
761
762/**
763 * This function is used to facilitate writing important information to disk
764 */
765#define tofile(file_name, ...) do {\
766 char tmp_buf[512];\
767 int size;\
768 size = GNUNET_snprintf(tmp_buf,sizeof(tmp_buf),__VA_ARGS__);\
769 if (0 > size)\
770 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,\
771 "Failed to create tmp_buf\n");\
772 else\
773 tofile_(file_name,tmp_buf);\
774 } while (0);
775
776
777/**
778 * Write the ids and their according index in the given array to a file
779 * Unused
780 */
781/* static void
782ids_to_file (char *file_name,
783 struct GNUNET_PeerIdentity *peer_ids,
784 unsigned int num_peer_ids)
785{
786 unsigned int i;
787
788 for (i=0 ; i < num_peer_ids ; i++)
789 {
790 to_file (file_name,
791 "%u\t%s",
792 i,
793 GNUNET_i2s_full (&peer_ids[i]));
794 }
795} */
796
797/**
798 * Test the success of a single test
799 */
800static int
801evaluate (void)
802{
803 unsigned int i;
804 int tmp_ok;
805
806 tmp_ok = 1;
807
808 for (i = 0; i < num_peers; i++)
809 {
810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
811 "%u. peer [%s] received %u of %u expected peer_ids: %i\n",
812 i,
813 GNUNET_i2s (rps_peers[i].peer_id),
814 rps_peers[i].num_recv_ids,
815 rps_peers[i].num_ids_to_request,
816 (rps_peers[i].num_ids_to_request == rps_peers[i].num_recv_ids));
817 tmp_ok &= (rps_peers[i].num_ids_to_request == rps_peers[i].num_recv_ids);
818 }
819 return tmp_ok? 0 : 1;
820}
821
822
823/**
824 * Creates an oplist entry and adds it to the oplist DLL
825 */
826static struct OpListEntry *
827make_oplist_entry ()
828{
829 struct OpListEntry *entry;
830
831 entry = GNUNET_new (struct OpListEntry);
832 GNUNET_CONTAINER_DLL_insert_tail (oplist_head, oplist_tail, entry);
833 return entry;
834}
835
836
837/**
838 * @brief Checks if given peer already received its statistics value from the
839 * statistics service.
840 *
841 * @param rps_peer the peer to check for
842 *
843 * @return #GNUNET_YES if so
844 * #GNUNET_NO otherwise
845 */
846static int check_statistics_collect_completed_single_peer (
847 const struct RPSPeer *rps_peer)
848{
849 if (cur_test_run.stat_collect_flags !=
850 (cur_test_run.stat_collect_flags &
851 rps_peer->stat_collected_flags))
852 {
853 return GNUNET_NO;
854 }
855 return GNUNET_YES;
856}
857/**
858 * @brief Checks if all peers already received their statistics value from the
859 * statistics service.
860 *
861 * @return #GNUNET_YES if so
862 * #GNUNET_NO otherwise
863 */
864static int check_statistics_collect_completed ()
865{
866 uint32_t i;
867
868 for (i = 0; i < num_peers; i++)
869 {
870 if (GNUNET_NO == check_statistics_collect_completed_single_peer (&rps_peers[i]))
871 {
872 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
873 "At least Peer %" PRIu32 " did not yet receive all statistics values\n",
874 i);
875 return GNUNET_NO;
876 }
877 }
878 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
879 "All peers received their statistics values\n");
880 return GNUNET_YES;
881}
882
883/**
884 * Task run on timeout to shut everything down.
885 */
886static void
887shutdown_op (void *cls)
888{
889 unsigned int i;
890
891 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
892 "Shutdown task scheduled, going down.\n");
893 in_shutdown = GNUNET_YES;
894 if (NULL != post_test_task)
895 {
896 GNUNET_SCHEDULER_cancel (post_test_task);
897 }
898 if (NULL != churn_task)
899 {
900 GNUNET_SCHEDULER_cancel (churn_task);
901 churn_task = NULL;
902 }
903 for (i = 0; i < num_peers; i++)
904 {
905 if (NULL != rps_peers[i].rps_handle)
906 {
907 GNUNET_RPS_disconnect (rps_peers[i].rps_handle);
908 }
909 if (NULL != rps_peers[i].op)
910 {
911 GNUNET_TESTBED_operation_done (rps_peers[i].op);
912 }
913 }
914}
915
916
917/**
918 * Task run on timeout to collect statistics and potentially shut down.
919 */
920static void
921post_test_op (void *cls)
922{
923 unsigned int i;
924
925 post_test_task = NULL;
926 post_test = GNUNET_YES;
927 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
928 "Post test task scheduled, going down.\n");
929 if (NULL != churn_task)
930 {
931 GNUNET_SCHEDULER_cancel (churn_task);
932 churn_task = NULL;
933 }
934 for (i = 0; i < num_peers; i++)
935 {
936 if (NULL != rps_peers[i].op)
937 {
938 GNUNET_TESTBED_operation_done (rps_peers[i].op);
939 rps_peers[i].op = NULL;
940 }
941 if (NULL != cur_test_run.post_test)
942 {
943 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing post_test for peer %u\n", i);
944 cur_test_run.post_test (&rps_peers[i]);
945 }
946 }
947 /* If we do not collect statistics, shut down directly */
948 if (NO_COLLECT_STATISTICS == cur_test_run.have_collect_statistics ||
949 GNUNET_YES == check_statistics_collect_completed())
950 {
951 GNUNET_SCHEDULER_shutdown ();
952 }
953}
954
955
956/**
957 * Seed peers.
958 */
959static void
960seed_peers (void *cls)
961{
962 struct RPSPeer *peer = cls;
963 unsigned int amount;
964 unsigned int i;
965
966 // TODO if malicious don't seed mal peers
967 amount = round (.5 * num_peers);
968
969 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Seeding peers:\n");
970 for (i = 0 ; i < amount ; i++)
971 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Seeding %u. peer: %s\n",
972 i,
973 GNUNET_i2s (&rps_peer_ids[i]));
974
975 GNUNET_RPS_seed_ids (peer->rps_handle, amount, rps_peer_ids);
976}
977
978
979/**
980 * Get the id of peer i.
981 */
982 void
983info_cb (void *cb_cls,
984 struct GNUNET_TESTBED_Operation *op,
985 const struct GNUNET_TESTBED_PeerInformation *pinfo,
986 const char *emsg)
987{
988 struct OpListEntry *entry = (struct OpListEntry *) cb_cls;
989
990 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
991 {
992 return;
993 }
994
995 if (NULL == pinfo || NULL != emsg)
996 {
997 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got Error: %s\n", emsg);
998 GNUNET_TESTBED_operation_done (entry->op);
999 return;
1000 }
1001
1002 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1003 "Peer %u is %s\n",
1004 entry->index,
1005 GNUNET_i2s (pinfo->result.id));
1006
1007 rps_peer_ids[entry->index] = *(pinfo->result.id);
1008 rps_peers[entry->index].peer_id = &rps_peer_ids[entry->index];
1009
1010 GNUNET_assert (GNUNET_OK ==
1011 GNUNET_CONTAINER_multipeermap_put (peer_map,
1012 &rps_peer_ids[entry->index],
1013 &rps_peers[entry->index],
1014 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1015 tofile ("/tmp/rps/peer_ids",
1016 "%u\t%s\n",
1017 entry->index,
1018 GNUNET_i2s_full (&rps_peer_ids[entry->index]));
1019
1020 GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1021 GNUNET_TESTBED_operation_done (entry->op);
1022 GNUNET_free (entry);
1023}
1024
1025
1026/**
1027 * Callback to be called when RPS service connect operation is completed
1028 *
1029 * @param cls the callback closure from functions generating an operation
1030 * @param op the operation that has been finished
1031 * @param ca_result the RPS service handle returned from rps_connect_adapter
1032 * @param emsg error message in case the operation has failed; will be NULL if
1033 * operation has executed successfully.
1034 */
1035static void
1036rps_connect_complete_cb (void *cls,
1037 struct GNUNET_TESTBED_Operation *op,
1038 void *ca_result,
1039 const char *emsg)
1040{
1041 struct RPSPeer *rps_peer = cls;
1042 struct GNUNET_RPS_Handle *rps = ca_result;
1043
1044 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1045 {
1046 return;
1047 }
1048
1049 rps_peer->rps_handle = rps;
1050 rps_peer->online = GNUNET_YES;
1051 num_peers_online++;
1052
1053 GNUNET_assert (op == rps_peer->op);
1054 if (NULL != emsg)
1055 {
1056 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1057 "Failed to connect to RPS service: %s\n",
1058 emsg);
1059 ok = 1;
1060 GNUNET_SCHEDULER_shutdown ();
1061 return;
1062 }
1063
1064 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started client successfully\n");
1065
1066 cur_test_run.main_test (rps_peer);
1067}
1068
1069
1070/**
1071 * Adapter function called to establish a connection to
1072 * the RPS service.
1073 *
1074 * @param cls closure
1075 * @param cfg configuration of the peer to connect to; will be available until
1076 * GNUNET_TESTBED_operation_done() is called on the operation returned
1077 * from GNUNET_TESTBED_service_connect()
1078 * @return service handle to return in 'op_result', NULL on error
1079 */
1080static void *
1081rps_connect_adapter (void *cls,
1082 const struct GNUNET_CONFIGURATION_Handle *cfg)
1083{
1084 struct GNUNET_RPS_Handle *h;
1085
1086 h = GNUNET_RPS_connect (cfg);
1087
1088 if (NULL != cur_test_run.pre_test)
1089 cur_test_run.pre_test (cls, h);
1090
1091 return h;
1092}
1093
1094/**
1095 * Called to open a connection to the peer's statistics
1096 *
1097 * @param cls peer context
1098 * @param cfg configuration of the peer to connect to; will be available until
1099 * GNUNET_TESTBED_operation_done() is called on the operation returned
1100 * from GNUNET_TESTBED_service_connect()
1101 * @return service handle to return in 'op_result', NULL on error
1102 */
1103static void *
1104stat_connect_adapter (void *cls,
1105 const struct GNUNET_CONFIGURATION_Handle *cfg)
1106{
1107 struct RPSPeer *peer = cls;
1108
1109 peer->stats_h = GNUNET_STATISTICS_create ("rps-profiler", cfg);
1110 return peer->stats_h;
1111}
1112
1113/**
1114 * Called to disconnect from peer's statistics service
1115 *
1116 * @param cls peer context
1117 * @param op_result service handle returned from the connect adapter
1118 */
1119static void
1120stat_disconnect_adapter (void *cls, void *op_result)
1121{
1122 struct RPSPeer *peer = cls;
1123
1124 //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1125 // (peer->stats_h, "core", "# peers connected",
1126 // stat_iterator, peer));
1127 //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1128 // (peer->stats_h, "nse", "# peers connected",
1129 // stat_iterator, peer));
1130 GNUNET_STATISTICS_destroy (op_result, GNUNET_NO);
1131 peer->stats_h = NULL;
1132}
1133
1134/**
1135 * Called after successfully opening a connection to a peer's statistics
1136 * service; we register statistics monitoring for CORE and NSE here.
1137 *
1138 * @param cls the callback closure from functions generating an operation
1139 * @param op the operation that has been finished
1140 * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
1141 * @param emsg error message in case the operation has failed; will be NULL if
1142 * operation has executed successfully.
1143 */
1144static void
1145stat_complete_cb (void *cls, struct GNUNET_TESTBED_Operation *op,
1146 void *ca_result, const char *emsg )
1147{
1148 //struct GNUNET_STATISTICS_Handle *sh = ca_result;
1149 //struct RPSPeer *peer = (struct RPSPeer *) cls;
1150
1151 if (NULL != emsg)
1152 {
1153 GNUNET_break (0);
1154 return;
1155 }
1156 //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1157 // (sh, "core", "# peers connected",
1158 // stat_iterator, peer));
1159 //GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1160 // (sh, "nse", "# peers connected",
1161 // stat_iterator, peer));
1162}
1163
1164
1165/**
1166 * Adapter function called to destroy connection to
1167 * RPS service.
1168 *
1169 * @param cls closure
1170 * @param op_result service handle returned from the connect adapter
1171 */
1172static void
1173rps_disconnect_adapter (void *cls,
1174 void *op_result)
1175{
1176 struct RPSPeer *peer = cls;
1177 struct GNUNET_RPS_Handle *h = op_result;
1178
1179 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "disconnect_adapter()\n");
1180 GNUNET_assert (NULL != peer);
1181 GNUNET_RPS_disconnect (h);
1182 peer->rps_handle = NULL;
1183}
1184
1185
1186/***********************************************************************
1187 * Definition of tests
1188***********************************************************************/
1189
1190/**
1191 * Callback to call on receipt of a reply
1192 *
1193 * @param cls closure
1194 * @param n number of peers
1195 * @param recv_peers the received peers
1196 */
1197static void
1198default_reply_handle (void *cls,
1199 uint64_t n,
1200 const struct GNUNET_PeerIdentity *recv_peers)
1201{
1202 struct RPSPeer *rps_peer;
1203 struct PendingReply *pending_rep = (struct PendingReply *) cls;
1204 unsigned int i;
1205
1206 rps_peer = pending_rep->rps_peer;
1207 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_rep_head,
1208 rps_peer->pending_rep_tail,
1209 pending_rep);
1210 rps_peer->num_pending_reps--;
1211 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1212 "[%s] got %" PRIu64 " peers:\n",
1213 GNUNET_i2s (rps_peer->peer_id),
1214 n);
1215
1216 for (i = 0; i < n; i++)
1217 {
1218 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1219 "%u: %s\n",
1220 i,
1221 GNUNET_i2s (&recv_peers[i]));
1222
1223 rps_peer->num_recv_ids++;
1224 }
1225
1226 if (0 == evaluate () && HAVE_QUICK_QUIT == cur_test_run.have_quick_quit)
1227 {
1228 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test succeeded before timeout\n");
1229 GNUNET_assert (NULL != post_test_task);
1230 GNUNET_SCHEDULER_cancel (post_test_task);
1231 post_test_task = GNUNET_SCHEDULER_add_now (&post_test_op, NULL);
1232 GNUNET_assert (NULL!= post_test_task);
1233 }
1234}
1235
1236/**
1237 * Request random peers.
1238 */
1239static void
1240request_peers (void *cls)
1241{
1242 struct PendingRequest *pending_req = cls;
1243 struct RPSPeer *rps_peer;
1244 struct PendingReply *pending_rep;
1245
1246 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1247 return;
1248 rps_peer = pending_req->rps_peer;
1249 GNUNET_assert (1 <= rps_peer->num_pending_reqs);
1250 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_req_head,
1251 rps_peer->pending_req_tail,
1252 pending_req);
1253 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1254 "Requesting one peer\n");
1255 pending_rep = GNUNET_new (struct PendingReply);
1256 pending_rep->rps_peer = rps_peer;
1257 pending_rep->req_handle = GNUNET_RPS_request_peers (rps_peer->rps_handle,
1258 1,
1259 cur_test_run.reply_handle,
1260 pending_rep);
1261 GNUNET_CONTAINER_DLL_insert_tail (rps_peer->pending_rep_head,
1262 rps_peer->pending_rep_tail,
1263 pending_rep);
1264 rps_peer->num_pending_reps++;
1265 rps_peer->num_pending_reqs--;
1266}
1267
1268static void
1269cancel_pending_req (struct PendingRequest *pending_req)
1270{
1271 struct RPSPeer *rps_peer;
1272
1273 rps_peer = pending_req->rps_peer;
1274 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_req_head,
1275 rps_peer->pending_req_tail,
1276 pending_req);
1277 rps_peer->num_pending_reqs--;
1278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1279 "Cancelling pending request\n");
1280 GNUNET_SCHEDULER_cancel (pending_req->request_task);
1281 GNUNET_free (pending_req);
1282}
1283
1284static void
1285cancel_request (struct PendingReply *pending_rep)
1286{
1287 struct RPSPeer *rps_peer;
1288
1289 rps_peer = pending_rep->rps_peer;
1290 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_rep_head,
1291 rps_peer->pending_rep_tail,
1292 pending_rep);
1293 rps_peer->num_pending_reps--;
1294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1295 "Cancelling request\n");
1296 GNUNET_RPS_request_cancel (pending_rep->req_handle);
1297 GNUNET_free (pending_rep);
1298}
1299
1300
1301/**
1302 * Schedule requests for peer @a rps_peer that have neither been scheduled, nor
1303 * issued, nor replied
1304 */
1305void
1306schedule_missing_requests (struct RPSPeer *rps_peer)
1307{
1308 unsigned int i;
1309 struct PendingRequest *pending_req;
1310
1311 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1312 "Scheduling %u - %u missing requests\n",
1313 rps_peer->num_ids_to_request,
1314 rps_peer->num_pending_reqs + rps_peer->num_pending_reps);
1315 GNUNET_assert (rps_peer->num_pending_reqs + rps_peer->num_pending_reps <=
1316 rps_peer->num_ids_to_request);
1317 for (i = rps_peer->num_pending_reqs + rps_peer->num_pending_reps;
1318 i < rps_peer->num_ids_to_request; i++)
1319 {
1320 pending_req = GNUNET_new (struct PendingRequest);
1321 pending_req->rps_peer = rps_peer;
1322 pending_req->request_task = GNUNET_SCHEDULER_add_delayed (
1323 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
1324 cur_test_run.request_interval * i),
1325 request_peers,
1326 pending_req);
1327 GNUNET_CONTAINER_DLL_insert_tail (rps_peer->pending_req_head,
1328 rps_peer->pending_req_tail,
1329 pending_req);
1330 rps_peer->num_pending_reqs++;
1331 }
1332}
1333
1334void
1335cancel_pending_req_rep (struct RPSPeer *rps_peer)
1336{
1337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1338 "Cancelling all (pending) requests.\n");
1339 while (NULL != rps_peer->pending_req_head)
1340 cancel_pending_req (rps_peer->pending_req_head);
1341 GNUNET_assert (0 == rps_peer->num_pending_reqs);
1342 while (NULL != rps_peer->pending_rep_head)
1343 cancel_request (rps_peer->pending_rep_head);
1344 GNUNET_assert (0 == rps_peer->num_pending_reps);
1345}
1346
1347/***********************************
1348 * MALICIOUS
1349***********************************/
1350
1351/**
1352 * Initialise only non-mal RPSPeers
1353 */
1354static void mal_init_peer (struct RPSPeer *rps_peer)
1355{
1356 if (rps_peer->index >= round (portion * num_peers))
1357 rps_peer->num_ids_to_request = 1;
1358}
1359
1360
1361/**
1362 * @brief Set peers to (non-)malicious before execution
1363 *
1364 * Of signature #PreTest
1365 *
1366 * @param rps_peer the peer to set (non-) malicious
1367 * @param h the handle to the service
1368 */
1369static void
1370mal_pre (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
1371{
1372 #ifdef ENABLE_MALICIOUS
1373 uint32_t num_mal_peers;
1374
1375 GNUNET_assert ( (1 >= portion) &&
1376 (0 < portion) );
1377 num_mal_peers = round (portion * num_peers);
1378
1379 if (rps_peer->index < num_mal_peers)
1380 {
1381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1382 "%u. peer [%s] of %" PRIu32 " malicious peers turning malicious\n",
1383 rps_peer->index,
1384 GNUNET_i2s (rps_peer->peer_id),
1385 num_mal_peers);
1386
1387 GNUNET_RPS_act_malicious (h, mal_type, num_mal_peers,
1388 rps_peer_ids, target_peer);
1389 }
1390 #endif /* ENABLE_MALICIOUS */
1391}
1392
1393static void
1394mal_cb (struct RPSPeer *rps_peer)
1395{
1396 uint32_t num_mal_peers;
1397
1398 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1399 {
1400 return;
1401 }
1402
1403 #ifdef ENABLE_MALICIOUS
1404 GNUNET_assert ( (1 >= portion) &&
1405 (0 < portion) );
1406 num_mal_peers = round (portion * num_peers);
1407
1408 if (rps_peer->index >= num_mal_peers)
1409 { /* It's useless to ask a malicious peer about a random sample -
1410 it's not sampling */
1411 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2),
1412 seed_peers, rps_peer);
1413 schedule_missing_requests (rps_peer);
1414 }
1415 #endif /* ENABLE_MALICIOUS */
1416}
1417
1418/***********************************
1419 * CHURN
1420***********************************/
1421
1422static void
1423churn (void *cls);
1424
1425/**
1426 * @brief Starts churn
1427 *
1428 * Has signature of #MainTest
1429 *
1430 * This is not implemented too nicely as this is called for each peer, but we
1431 * only need to call it once. (Yes we check that we only schedule the task
1432 * once.)
1433 *
1434 * @param rps_peer The peer it's called for
1435 */
1436static void
1437churn_test_cb (struct RPSPeer *rps_peer)
1438{
1439 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1440 {
1441 return;
1442 }
1443
1444 /* Start churn */
1445 if (HAVE_CHURN == cur_test_run.have_churn && NULL == churn_task)
1446 {
1447 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1448 "Starting churn task\n");
1449 churn_task = GNUNET_SCHEDULER_add_delayed (
1450 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
1451 churn,
1452 NULL);
1453 } else {
1454 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1455 "Not starting churn task\n");
1456 }
1457
1458 schedule_missing_requests (rps_peer);
1459}
1460
1461/***********************************
1462 * PROFILER
1463***********************************/
1464
1465/**
1466 * Callback to be called when RPS service is started or stopped at peers
1467 *
1468 * @param cls NULL
1469 * @param op the operation handle
1470 * @param emsg NULL on success; otherwise an error description
1471 */
1472static void
1473churn_cb (void *cls,
1474 struct GNUNET_TESTBED_Operation *op,
1475 const char *emsg)
1476{
1477 // FIXME
1478 struct OpListEntry *entry = cls;
1479
1480 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1481 {
1482 return;
1483 }
1484
1485 GNUNET_TESTBED_operation_done (entry->op);
1486 if (NULL != emsg)
1487 {
1488 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to start/stop RPS at a peer\n");
1489 GNUNET_SCHEDULER_shutdown ();
1490 return;
1491 }
1492 GNUNET_assert (0 != entry->delta);
1493
1494 num_peers_online += entry->delta;
1495
1496 if (PEER_GO_OFFLINE == entry->delta)
1497 { /* Peer hopefully just went offline */
1498 if (GNUNET_YES != rps_peers[entry->index].online)
1499 {
1500 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1501 "peer %s was expected to go offline but is still marked as online\n",
1502 GNUNET_i2s (rps_peers[entry->index].peer_id));
1503 GNUNET_break (0);
1504 }
1505 else
1506 {
1507 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1508 "peer %s probably went offline as expected\n",
1509 GNUNET_i2s (rps_peers[entry->index].peer_id));
1510 }
1511 rps_peers[entry->index].online = GNUNET_NO;
1512 }
1513
1514 else if (PEER_GO_ONLINE < entry->delta)
1515 { /* Peer hopefully just went online */
1516 if (GNUNET_NO != rps_peers[entry->index].online)
1517 {
1518 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1519 "peer %s was expected to go online but is still marked as offline\n",
1520 GNUNET_i2s (rps_peers[entry->index].peer_id));
1521 GNUNET_break (0);
1522 }
1523 else
1524 {
1525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1526 "peer %s probably went online as expected\n",
1527 GNUNET_i2s (rps_peers[entry->index].peer_id));
1528 if (NULL != cur_test_run.pre_test)
1529 {
1530 cur_test_run.pre_test (&rps_peers[entry->index],
1531 rps_peers[entry->index].rps_handle);
1532 schedule_missing_requests (&rps_peers[entry->index]);
1533 }
1534 }
1535 rps_peers[entry->index].online = GNUNET_YES;
1536 }
1537 else
1538 {
1539 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1540 "Invalid value for delta: %i\n", entry->delta);
1541 GNUNET_break (0);
1542 }
1543
1544 GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1545 rps_peers[entry->index].entry_op_manage = NULL;
1546 GNUNET_free (entry);
1547 //if (num_peers_in_round[current_round] == peers_running)
1548 // run_round ();
1549}
1550
1551/**
1552 * @brief Set the rps-service up or down for a specific peer
1553 *
1554 * @param i index of action
1555 * @param j index of peer
1556 * @param delta (#PEER_ONLINE_DELTA) down (-1) or up (1)
1557 * @param prob_go_on_off the probability of the action
1558 */
1559static void
1560manage_service_wrapper (unsigned int i, unsigned int j,
1561 enum PEER_ONLINE_DELTA delta,
1562 double prob_go_on_off)
1563{
1564 struct OpListEntry *entry = NULL;
1565 uint32_t prob;
1566
1567 /* make sure that management operation is not already scheduled */
1568 if (NULL != rps_peers[j].entry_op_manage)
1569 {
1570 return;
1571 }
1572
1573 prob = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1574 UINT32_MAX);
1575 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1576 "%u. selected peer (%u: %s) is %s.\n",
1577 i,
1578 j,
1579 GNUNET_i2s (rps_peers[j].peer_id),
1580 (PEER_GO_ONLINE == delta) ? "online" : "offline");
1581 if (prob < prob_go_on_off * UINT32_MAX)
1582 {
1583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1584 "%s goes %s\n",
1585 GNUNET_i2s (rps_peers[j].peer_id),
1586 (PEER_GO_OFFLINE == delta) ? "offline" : "online");
1587
1588 if (PEER_GO_OFFLINE == delta)
1589 cancel_pending_req_rep (&rps_peers[j]);
1590 entry = make_oplist_entry ();
1591 entry->delta = delta;
1592 entry->index = j;
1593 entry->op = GNUNET_TESTBED_peer_manage_service (NULL,
1594 testbed_peers[j],
1595 "rps",
1596 &churn_cb,
1597 entry,
1598 (PEER_GO_OFFLINE == delta) ? 0 : 1);
1599 rps_peers[j].entry_op_manage = entry;
1600 }
1601}
1602
1603
1604static void
1605churn (void *cls)
1606{
1607 unsigned int i;
1608 unsigned int j;
1609 double portion_online;
1610 unsigned int *permut;
1611 double prob_go_offline;
1612 double portion_go_online;
1613 double portion_go_offline;
1614
1615 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1616 {
1617 return;
1618 }
1619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1620 "Churn function executing\n");
1621
1622 churn_task = NULL; /* Should be invalid by now */
1623
1624 /* Compute the probability for an online peer to go offline
1625 * this round */
1626 portion_online = num_peers_online * 1.0 / num_peers;
1627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1628 "Portion online: %f\n",
1629 portion_online);
1630 portion_go_online = ((1 - portion_online) * .5 * .66);
1631 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1632 "Portion that should go online: %f\n",
1633 portion_go_online);
1634 portion_go_offline = (portion_online + portion_go_online) - .75;
1635 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1636 "Portion that probably goes offline: %f\n",
1637 portion_go_offline);
1638 prob_go_offline = portion_go_offline / (portion_online * .5);
1639 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1640 "Probability of a selected online peer to go offline: %f\n",
1641 prob_go_offline);
1642
1643 permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK,
1644 (unsigned int) num_peers);
1645
1646 /* Go over 50% randomly chosen peers */
1647 for (i = 0; i < .5 * num_peers; i++)
1648 {
1649 j = permut[i];
1650
1651 /* If online, shut down with certain probability */
1652 if (GNUNET_YES == rps_peers[j].online)
1653 {
1654 manage_service_wrapper (i, j, -1, prob_go_offline);
1655 }
1656
1657 /* If offline, restart with certain probability */
1658 else if (GNUNET_NO == rps_peers[j].online)
1659 {
1660 manage_service_wrapper (i, j, 1, 0.66);
1661 }
1662 }
1663
1664 GNUNET_free (permut);
1665
1666 churn_task = GNUNET_SCHEDULER_add_delayed (
1667 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2),
1668 churn,
1669 NULL);
1670}
1671
1672
1673/**
1674 * Initialise given RPSPeer
1675 */
1676static void profiler_init_peer (struct RPSPeer *rps_peer)
1677{
1678 if (num_peers - 1 == rps_peer->index)
1679 {
1680 rps_peer->num_ids_to_request = cur_test_run.num_requests;
1681 } else {
1682 rps_peer->num_ids_to_request = 0;
1683 }
1684 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer shall request %i peers\n",
1685 rps_peer->num_ids_to_request);
1686}
1687
1688
1689/**
1690 * Callback to call on receipt of a reply
1691 *
1692 * @param cls closure
1693 * @param n number of peers
1694 * @param recv_peers the received peers
1695 */
1696static void
1697profiler_reply_handle (void *cls,
1698 uint64_t n,
1699 const struct GNUNET_PeerIdentity *recv_peers)
1700{
1701 struct RPSPeer *rps_peer;
1702 struct RPSPeer *rcv_rps_peer;
1703 char *file_name;
1704 char *file_name_dh;
1705 char *file_name_dhr;
1706 char *file_name_dhru;
1707 unsigned int i;
1708 struct PendingReply *pending_rep = (struct PendingReply *) cls;
1709
1710 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
1711 rps_peer = pending_rep->rps_peer;
1712 file_name = "/tmp/rps/received_ids";
1713 file_name_dh = "/tmp/rps/diehard_input";
1714 file_name_dhr = "/tmp/rps/diehard_input_raw";
1715 file_name_dhru = "/tmp/rps/diehard_input_raw_aligned";
1716 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1717 "[%s] got %" PRIu64 " peers:\n",
1718 GNUNET_i2s (rps_peer->peer_id),
1719 n);
1720 for (i = 0; i < n; i++)
1721 {
1722 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1723 "%u: %s\n",
1724 i,
1725 GNUNET_i2s (&recv_peers[i]));
1726 tofile (file_name,
1727 "%s\n",
1728 GNUNET_i2s_full (&recv_peers[i]));
1729 rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get (peer_map, &recv_peers[i]);
1730 GNUNET_assert (NULL != rcv_rps_peer);
1731 tofile (file_name_dh,
1732 "%" PRIu32 "\n",
1733 (uint32_t) rcv_rps_peer->index);
1734 to_file_raw (file_name_dhr,
1735 (char *) &rcv_rps_peer->index,
1736 sizeof (uint32_t));
1737 to_file_raw_unaligned (file_name_dhru,
1738 (char *) &rcv_rps_peer->index,
1739 sizeof (uint32_t),
1740 bits_needed);
1741 }
1742 default_reply_handle (cls, n, recv_peers);
1743}
1744
1745
1746static void
1747profiler_cb (struct RPSPeer *rps_peer)
1748{
1749 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1750 {
1751 return;
1752 }
1753
1754 /* Start churn */
1755 if (HAVE_CHURN == cur_test_run.have_churn && NULL == churn_task)
1756 {
1757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1758 "Starting churn task\n");
1759 churn_task = GNUNET_SCHEDULER_add_delayed (
1760 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
1761 churn,
1762 NULL);
1763 } else {
1764 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1765 "Not starting churn task\n");
1766 }
1767
1768 /* Only request peer ids at one peer.
1769 * (It's the before-last because last one is target of the focussed attack.)
1770 */
1771 if (eval_peer == rps_peer)
1772 schedule_missing_requests (rps_peer);
1773}
1774
1775/**
1776 * Function called from #profiler_eval with a filename.
1777 *
1778 * @param cls closure
1779 * @param filename complete filename (absolute path)
1780 * @return #GNUNET_OK to continue to iterate,
1781 * #GNUNET_NO to stop iteration with no error,
1782 * #GNUNET_SYSERR to abort iteration with error!
1783 */
1784int
1785file_name_cb (void *cls, const char *filename)
1786{
1787 if (NULL != strstr (filename, "sampler_el"))
1788 {
1789 struct RPS_SamplerElement *s_elem;
1790 struct GNUNET_CRYPTO_AuthKey auth_key;
1791 const char *key_char;
1792 uint32_t i;
1793
1794 key_char = filename + 20; /* Length of "/tmp/rps/sampler_el-" */
1795 tofile (filename, "--------------------------\n");
1796
1797 auth_key = string_to_auth_key (key_char);
1798 s_elem = RPS_sampler_elem_create ();
1799 RPS_sampler_elem_set (s_elem, auth_key);
1800
1801 for (i = 0; i < num_peers; i++)
1802 {
1803 RPS_sampler_elem_next (s_elem, &rps_peer_ids[i]);
1804 }
1805 RPS_sampler_elem_destroy (s_elem);
1806 }
1807 return GNUNET_OK;
1808}
1809
1810/**
1811 * This is run after the test finished.
1812 *
1813 * Compute all perfect samples.
1814 */
1815int
1816profiler_eval (void)
1817{
1818 /* Compute perfect sample for each sampler element */
1819 if (-1 == GNUNET_DISK_directory_scan ("/tmp/rps/", file_name_cb, NULL))
1820 {
1821 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Scan of directory failed\n");
1822 }
1823
1824 return evaluate ();
1825}
1826
1827static uint32_t fac (uint32_t x)
1828{
1829 if (1 >= x)
1830 {
1831 return x;
1832 }
1833 return x * fac (x - 1);
1834}
1835
1836static uint32_t binom (uint32_t n, uint32_t k)
1837{
1838 //GNUNET_assert (n >= k);
1839 if (k > n) return 0;
1840 if (0 > n) return 0;
1841 if (0 > k) return 0;
1842 if (0 == k) return 1;
1843 return fac (n)
1844 /
1845 fac(k) * fac(n - k);
1846}
1847
1848/**
1849 * @brief is b in view of a?
1850 *
1851 * @param a
1852 * @param b
1853 *
1854 * @return
1855 */
1856static int is_in_view (uint32_t a, uint32_t b)
1857{
1858 uint32_t i;
1859 for (i = 0; i < rps_peers[a].cur_view_count; i++)
1860 {
1861 if (0 == memcmp (rps_peers[b].peer_id,
1862 &rps_peers[a].cur_view[i],
1863 sizeof (struct GNUNET_PeerIdentity)))
1864 {
1865 return GNUNET_YES;
1866 }
1867 }
1868 return GNUNET_NO;
1869}
1870
1871static uint32_t get_idx_of_pid (const struct GNUNET_PeerIdentity *pid)
1872{
1873 uint32_t i;
1874
1875 for (i = 0; i < num_peers; i++)
1876 {
1877 if (0 == memcmp (pid,
1878 rps_peers[i].peer_id,
1879 sizeof (struct GNUNET_PeerIdentity)))
1880 {
1881 return i;
1882 }
1883 }
1884 //return 0; /* Should not happen - make compiler happy */
1885 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1886 "No known _PeerIdentity %s!\n",
1887 GNUNET_i2s_full (pid));
1888 GNUNET_assert (0);
1889}
1890
1891/**
1892 * @brief Counts number of peers in view of a that have b in their view
1893 *
1894 * @param a
1895 * @param uint32_tb
1896 *
1897 * @return
1898 */
1899static uint32_t count_containing_views (uint32_t a, uint32_t b)
1900{
1901 uint32_t i;
1902 uint32_t peer_idx;
1903 uint32_t count = 0;
1904
1905 for (i = 0; i < rps_peers[a].cur_view_count; i++)
1906 {
1907 peer_idx = get_idx_of_pid (&rps_peers[a].cur_view[i]);
1908 if (GNUNET_YES == is_in_view (peer_idx, b))
1909 {
1910 count++;
1911 }
1912 }
1913 return count;
1914}
1915
1916/**
1917 * @brief Computes the probability for each other peer to be selected by the
1918 * sampling process based on the views of all peers
1919 *
1920 * @param peer_idx index of the peer that is about to sample
1921 */
1922static void compute_probabilities (uint32_t peer_idx)
1923{
1924 //double probs[num_peers] = { 0 };
1925 double probs[num_peers];
1926 size_t probs_as_str_size = (num_peers * 10 + 1) * sizeof (char);
1927 char *probs_as_str = GNUNET_malloc (probs_as_str_size);
1928 char *probs_as_str_cpy;
1929 uint32_t i;
1930 double prob_push;
1931 double prob_pull;
1932 uint32_t view_size;
1933 uint32_t cont_views;
1934 uint32_t number_of_being_in_pull_events;
1935 int tmp;
1936 uint32_t count_non_zero_prob = 0;
1937
1938 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1939 "Computing probabilities for peer %" PRIu32 "\n", peer_idx);
1940 /* Firstly without knowledge of old views */
1941 for (i = 0; i < num_peers; i++)
1942 {
1943 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1944 "\tfor peer %" PRIu32 ":\n", i);
1945 view_size = rps_peers[i].cur_view_count;
1946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1947 "\t\tview_size: %" PRIu32 "\n", view_size);
1948 /* For peer i the probability of being sampled is
1949 * evenly distributed among all possibly observed peers. */
1950 /* We could have observed a peer in three cases:
1951 * 1. peer sent a push
1952 * 2. peer was contained in a pull reply
1953 * 3. peer was in history (sampler) - ignored for now */
1954 /* 1. Probability of having received a push from peer i */
1955 if ((GNUNET_YES == is_in_view (i, peer_idx)) &&
1956 (1 <= (0.45 * view_size)))
1957 {
1958 prob_push = 1.0 * binom (0.45 * view_size, 1)
1959 /
1960 binom (view_size, 0.45 * view_size);
1961 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1962 "\t\t%" PRIu32 " is in %" PRIu32 "'s view, prob: %f\n",
1963 peer_idx,
1964 i,
1965 prob_push);
1966 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1967 "\t\tposs choices from view: %" PRIu32 ", containing i: %" PRIu32 "\n",
1968 binom (view_size, 0.45 * view_size),
1969 binom (0.45 * view_size, 1));
1970 } else {
1971 prob_push = 0;
1972 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1973 "\t\t%" PRIu32 " is not in %" PRIu32 "'s view, prob: 0\n",
1974 peer_idx,
1975 i);
1976 }
1977 /* 2. Probability of peer i being contained in pulls */
1978 view_size = rps_peers[peer_idx].cur_view_count;
1979 cont_views = count_containing_views (peer_idx, i);
1980 number_of_being_in_pull_events =
1981 (binom (view_size, 0.45 * view_size) -
1982 binom (view_size - cont_views, 0.45 * view_size));
1983 if (0 != number_of_being_in_pull_events)
1984 {
1985 prob_pull = number_of_being_in_pull_events
1986 /
1987 (1.0 * binom (view_size, 0.45 * view_size));
1988 } else
1989 {
1990 prob_pull = 0;
1991 }
1992 probs[i] = prob_push + prob_pull - (prob_push * prob_pull);
1993 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1994 "\t\t%" PRIu32 " has %" PRIu32 " of %" PRIu32
1995 " peers in its view who know %" PRIu32 " prob: %f\n",
1996 peer_idx,
1997 cont_views,
1998 view_size,
1999 i,
2000 prob_pull);
2001 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2002 "\t\tnumber of possible pull combinations: %" PRIu32 "\n",
2003 binom (view_size, 0.45 * view_size));
2004 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2005 "\t\tnumber of possible pull combinations without %" PRIu32
2006 ": %" PRIu32 "\n",
2007 i,
2008 binom (view_size - cont_views, 0.45 * view_size));
2009 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2010 "\t\tnumber of possible pull combinations with %" PRIu32
2011 ": %" PRIu32 "\n",
2012 i,
2013 number_of_being_in_pull_events);
2014
2015 if (0 != probs[i]) count_non_zero_prob++;
2016 }
2017 /* normalize */
2018 if (0 != count_non_zero_prob)
2019 {
2020 for (i = 0; i < num_peers; i++)
2021 {
2022 probs[i] = probs[i] * (1.0 / count_non_zero_prob);
2023 }
2024 } else {
2025 for (i = 0; i < num_peers; i++)
2026 {
2027 probs[i] = 0;
2028 }
2029 }
2030 /* str repr */
2031 for (i = 0; i < num_peers; i++)
2032 {
2033 probs_as_str_cpy = GNUNET_strndup (probs_as_str, probs_as_str_size);
2034 tmp = GNUNET_snprintf (probs_as_str,
2035 probs_as_str_size,
2036 "%s %7.6f", probs_as_str_cpy, probs[i]);
2037 GNUNET_free (probs_as_str_cpy);
2038 GNUNET_assert (0 <= tmp);
2039 }
2040
2041 to_file_w_len (rps_peers[peer_idx].file_name_probs,
2042 probs_as_str_size,
2043 probs_as_str);
2044 GNUNET_free (probs_as_str);
2045}
2046
2047/**
2048 * @brief This counts the number of peers in which views a given peer occurs.
2049 *
2050 * It also stores this value in the rps peer.
2051 *
2052 * @param peer_idx the index of the peer to count the representation
2053 *
2054 * @return the number of occurrences
2055 */
2056static uint32_t count_peer_in_views_2 (uint32_t peer_idx)
2057{
2058 uint32_t i, j;
2059 uint32_t count = 0;
2060
2061 for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2062 {
2063 for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2064 {
2065 if (0 == memcmp (rps_peers[peer_idx].peer_id,
2066 &rps_peers[i].cur_view[j],
2067 sizeof (struct GNUNET_PeerIdentity)))
2068 {
2069 count++;
2070 break;
2071 }
2072 }
2073 }
2074 rps_peers[peer_idx].count_in_views = count;
2075 return count;
2076}
2077
2078static uint32_t cumulated_view_sizes ()
2079{
2080 uint32_t i;
2081
2082 view_sizes = 0;
2083 for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2084 {
2085 view_sizes += rps_peers[i].cur_view_count;
2086 }
2087 return view_sizes;
2088}
2089
2090static void count_peer_in_views (uint32_t *count_peers)
2091{
2092 uint32_t i, j;
2093
2094 for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2095 {
2096 for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2097 {
2098 if (0 == memcmp (rps_peers[i].peer_id,
2099 &rps_peers[i].cur_view[j],
2100 sizeof (struct GNUNET_PeerIdentity)))
2101 {
2102 count_peers[i]++;
2103 }
2104 }
2105 }
2106}
2107
2108void compute_diversity ()
2109{
2110 uint32_t i;
2111 /* ith entry represents the numer of occurrences in other peer's views */
2112 uint32_t *count_peers = GNUNET_new_array (num_peers, uint32_t);
2113 uint32_t views_total_size;
2114 double expected;
2115 /* deviation from expected number of peers */
2116 double *deviation = GNUNET_new_array (num_peers, double);
2117
2118 views_total_size = 0;
2119 expected = 0;
2120
2121 /* For each peer count its representation in other peer's views*/
2122 for (i = 0; i < num_peers; i++) /* Peer to count */
2123 {
2124 views_total_size += rps_peers[i].cur_view_count;
2125 count_peer_in_views (count_peers);
2126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2127 "Counted representation of %" PRIu32 "th peer [%s]: %" PRIu32"\n",
2128 i,
2129 GNUNET_i2s (rps_peers[i].peer_id),
2130 count_peers[i]);
2131 }
2132
2133 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2134 "size of all views combined: %" PRIu32 "\n",
2135 views_total_size);
2136 expected = ((double) 1/num_peers) * views_total_size;
2137 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2138 "Expected number of occurrences of each peer in all views: %f\n",
2139 expected);
2140 for (i = 0; i < num_peers; i++) /* Peer to count */
2141 {
2142 deviation[i] = expected - count_peers[i];
2143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2144 "Deviation from expectation: %f\n", deviation[i]);
2145 }
2146 GNUNET_free (count_peers);
2147 GNUNET_free (deviation);
2148}
2149
2150void print_view_sizes()
2151{
2152 uint32_t i;
2153
2154 for (i = 0; i < num_peers; i++) /* Peer to count */
2155 {
2156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2157 "View size of %" PRIu32 ". [%s] is %" PRIu32 "\n",
2158 i,
2159 GNUNET_i2s (rps_peers[i].peer_id),
2160 rps_peers[i].cur_view_count);
2161 }
2162}
2163
2164void all_views_updated_cb()
2165{
2166 compute_diversity();
2167 print_view_sizes();
2168}
2169
2170void view_update_cb (void *cls,
2171 uint64_t view_size,
2172 const struct GNUNET_PeerIdentity *peers)
2173{
2174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2175 "View was updated (%" PRIu64 ")\n", view_size);
2176 struct RPSPeer *rps_peer = (struct RPSPeer *) cls;
2177 to_file ("/tmp/rps/view_sizes.txt",
2178 "%" PRIu64 " %" PRIu32 "",
2179 rps_peer->index,
2180 view_size);
2181 for (int i = 0; i < view_size; i++)
2182 {
2183 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2184 "\t%s\n", GNUNET_i2s (&peers[i]));
2185 }
2186 GNUNET_array_grow (rps_peer->cur_view,
2187 rps_peer->cur_view_count,
2188 view_size);
2189 //*rps_peer->cur_view = *peers;
2190 GNUNET_memcpy (rps_peer->cur_view,
2191 peers,
2192 view_size * sizeof (struct GNUNET_PeerIdentity));
2193 to_file ("/tmp/rps/count_in_views.txt",
2194 "%" PRIu64 " %" PRIu32 "",
2195 rps_peer->index,
2196 count_peer_in_views_2 (rps_peer->index));
2197 cumulated_view_sizes();
2198 if (0 != view_size)
2199 {
2200 to_file ("/tmp/rps/repr.txt",
2201 "%" PRIu64 /* index */
2202 " %" PRIu32 /* occurrence in views */
2203 " %" PRIu32 /* view sizes */
2204 " %f" /* fraction of repr in views */
2205 " %f" /* average view size */
2206 " %f" /* prob of occurrence in view slot */
2207 " %f" "", /* exp frac of repr in views */
2208 rps_peer->index,
2209 count_peer_in_views_2 (rps_peer->index),
2210 view_sizes,
2211 count_peer_in_views_2 (rps_peer->index) / (view_size * 1.0), /* fraction of representation in views */
2212 view_sizes / (view_size * 1.0), /* average view size */
2213 1.0 /view_size, /* prob of occurrence in view slot */
2214 (1.0/view_size) * (view_sizes/view_size) /* expected fraction of repr in views */
2215 );
2216 }
2217 compute_probabilities (rps_peer->index);
2218 all_views_updated_cb();
2219}
2220
2221static void
2222pre_profiler (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
2223{
2224 rps_peer->file_name_probs =
2225 store_prefix_file_name (rps_peer->peer_id, "probs");
2226 GNUNET_RPS_view_request (h, 0, view_update_cb, rps_peer);
2227}
2228
2229void write_final_stats (void){
2230 uint64_t sums[STAT_TYPE_MAX] = { 0 };
2231
2232 for (uint32_t i = 0; i < num_peers; i++)
2233 {
2234 to_file ("/tmp/rps/final_stats.dat",
2235 "%" PRIu32 " " /* index */
2236 "%s %" /* id */
2237 PRIu64 " %" /* rounds */
2238 PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" /* blocking */
2239 PRIu64 " %" PRIu64 " %" PRIu64 " %" /* issued */
2240 PRIu64 " %" PRIu64 " %" PRIu64 " %" /* sent */
2241 PRIu64 " %" PRIu64 " %" PRIu64 /* recv */,
2242 i,
2243 GNUNET_i2s (rps_peers[i].peer_id),
2244 rps_peers[i].stats[STAT_TYPE_ROUNDS],
2245 rps_peers[i].stats[STAT_TYPE_BLOCKS],
2246 rps_peers[i].stats[STAT_TYPE_BLOCKS_MANY_PUSH],
2247 rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PUSH],
2248 rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PULL],
2249 rps_peers[i].stats[STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL],
2250 rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL],
2251 rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND],
2252 rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ],
2253 rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REP],
2254 rps_peers[i].stats[STAT_TYPE_SENT_PUSH_SEND],
2255 rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ],
2256 rps_peers[i].stats[STAT_TYPE_SENT_PULL_REP],
2257 rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND],
2258 rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ],
2259 rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP]);
2260 for (uint32_t stat_type = STAT_TYPE_ROUNDS;
2261 stat_type < STAT_TYPE_MAX;
2262 stat_type++)
2263 {
2264 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2265 "Add to sum (%" PRIu64 ") %" PRIu64 " of stat type %u - %s\n",
2266 sums[stat_type],
2267 rps_peers[i].stats[stat_type],
2268 stat_type,
2269 stat_type_2_str (stat_type));
2270 sums[stat_type] += rps_peers[i].stats[stat_type];
2271 }
2272 }
2273 to_file ("/tmp/rps/final_stats.dat",
2274 "SUM %"
2275 PRIu64 " %" /* rounds */
2276 PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" /* blocking */
2277 PRIu64 " %" PRIu64 " %" PRIu64 " %" /* issued */
2278 PRIu64 " %" PRIu64 " %" PRIu64 " %" /* sent */
2279 PRIu64 " %" PRIu64 " %" PRIu64 /* recv */,
2280 sums[STAT_TYPE_ROUNDS],
2281 sums[STAT_TYPE_BLOCKS],
2282 sums[STAT_TYPE_BLOCKS_MANY_PUSH],
2283 sums[STAT_TYPE_BLOCKS_NO_PUSH],
2284 sums[STAT_TYPE_BLOCKS_NO_PULL],
2285 sums[STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL],
2286 sums[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL],
2287 sums[STAT_TYPE_ISSUED_PUSH_SEND],
2288 sums[STAT_TYPE_ISSUED_PULL_REQ],
2289 sums[STAT_TYPE_ISSUED_PULL_REP],
2290 sums[STAT_TYPE_SENT_PUSH_SEND],
2291 sums[STAT_TYPE_SENT_PULL_REQ],
2292 sums[STAT_TYPE_SENT_PULL_REP],
2293 sums[STAT_TYPE_RECV_PUSH_SEND],
2294 sums[STAT_TYPE_RECV_PULL_REQ],
2295 sums[STAT_TYPE_RECV_PULL_REP]);
2296}
2297
2298/**
2299 * Continuation called by #GNUNET_STATISTICS_get() functions.
2300 *
2301 * Remembers that this specific statistics value was received for this peer.
2302 * Checks whether all peers received their statistics yet.
2303 * Issues the shutdown.
2304 *
2305 * @param cls closure
2306 * @param success #GNUNET_OK if statistics were
2307 * successfully obtained, #GNUNET_SYSERR if not.
2308 */
2309void
2310post_test_shutdown_ready_cb (void *cls,
2311 int success)
2312{
2313 struct STATcls *stat_cls = (struct STATcls *) cls;
2314 struct RPSPeer *rps_peer = stat_cls->rps_peer;
2315 if (GNUNET_OK == success)
2316 {
2317 /* set flag that we we got the value */
2318 rps_peer->stat_collected_flags |= BIT(stat_cls->stat_type);
2319 } else {
2320 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2321 "Peer %u did not receive statistics value\n",
2322 rps_peer->index);
2323 GNUNET_free (stat_cls);
2324 GNUNET_break (0);
2325 }
2326
2327 if (NULL != rps_peer->stat_op &&
2328 GNUNET_YES == check_statistics_collect_completed_single_peer (rps_peer))
2329 {
2330 GNUNET_TESTBED_operation_done (rps_peer->stat_op);
2331 }
2332
2333 write_final_stats ();
2334 if (GNUNET_YES == check_statistics_collect_completed())
2335 {
2336 //write_final_stats ();
2337 GNUNET_free (stat_cls);
2338 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2339 "Shutting down\n");
2340 GNUNET_SCHEDULER_shutdown ();
2341 } else {
2342 GNUNET_free (stat_cls);
2343 }
2344}
2345
2346/**
2347 * Callback function to process statistic values.
2348 *
2349 * @param cls closure
2350 * @param subsystem name of subsystem that created the statistic
2351 * @param name the name of the datum
2352 * @param value the current value
2353 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
2354 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
2355 */
2356int
2357stat_iterator (void *cls,
2358 const char *subsystem,
2359 const char *name,
2360 uint64_t value,
2361 int is_persistent)
2362{
2363 const struct STATcls *stat_cls = (const struct STATcls *) cls;
2364 struct RPSPeer *rps_peer = (struct RPSPeer *) stat_cls->rps_peer;
2365 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got stat value: %s - %" PRIu64 "\n",
2366 //stat_type_2_str (stat_cls->stat_type),
2367 name,
2368 value);
2369 to_file (rps_peer->file_name_stats,
2370 "%s: %" PRIu64 "\n",
2371 name,
2372 value);
2373 switch (stat_str_2_type (name))
2374 {
2375 case STAT_TYPE_ROUNDS:
2376 rps_peer->stats[STAT_TYPE_ROUNDS] = value;
2377 break;
2378 case STAT_TYPE_BLOCKS:
2379 rps_peer->stats[STAT_TYPE_BLOCKS] = value;
2380 break;
2381 case STAT_TYPE_BLOCKS_MANY_PUSH:
2382 rps_peer->stats[STAT_TYPE_BLOCKS_MANY_PUSH] = value;
2383 break;
2384 case STAT_TYPE_BLOCKS_NO_PUSH:
2385 rps_peer->stats[STAT_TYPE_BLOCKS_NO_PUSH] = value;
2386 break;
2387 case STAT_TYPE_BLOCKS_NO_PULL:
2388 rps_peer->stats[STAT_TYPE_BLOCKS_NO_PULL] = value;
2389 break;
2390 case STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL:
2391 rps_peer->stats[STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL] = value;
2392 break;
2393 case STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL:
2394 rps_peer->stats[STAT_TYPE_BLOCKS] = value;
2395 break;
2396 case STAT_TYPE_ISSUED_PUSH_SEND:
2397 rps_peer->stats[STAT_TYPE_ISSUED_PUSH_SEND] = value;
2398 break;
2399 case STAT_TYPE_ISSUED_PULL_REQ:
2400 rps_peer->stats[STAT_TYPE_ISSUED_PULL_REQ] = value;
2401 break;
2402 case STAT_TYPE_ISSUED_PULL_REP:
2403 rps_peer->stats[STAT_TYPE_ISSUED_PULL_REP] = value;
2404 break;
2405 case STAT_TYPE_SENT_PUSH_SEND:
2406 rps_peer->stats[STAT_TYPE_SENT_PUSH_SEND] = value;
2407 break;
2408 case STAT_TYPE_SENT_PULL_REQ:
2409 rps_peer->stats[STAT_TYPE_SENT_PULL_REQ] = value;
2410 break;
2411 case STAT_TYPE_SENT_PULL_REP:
2412 rps_peer->stats[STAT_TYPE_SENT_PULL_REP] = value;
2413 break;
2414 case STAT_TYPE_RECV_PUSH_SEND:
2415 rps_peer->stats[STAT_TYPE_RECV_PUSH_SEND] = value;
2416 break;
2417 case STAT_TYPE_RECV_PULL_REQ:
2418 rps_peer->stats[STAT_TYPE_RECV_PULL_REQ] = value;
2419 break;
2420 case STAT_TYPE_RECV_PULL_REP:
2421 rps_peer->stats[STAT_TYPE_RECV_PULL_REP] = value;
2422 break;
2423 case STAT_TYPE_MAX:
2424 default:
2425 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2426 "Unknown statistics string: %s\n",
2427 name);
2428 break;
2429 }
2430 return GNUNET_OK;
2431}
2432
2433void post_profiler (struct RPSPeer *rps_peer)
2434{
2435 if (COLLECT_STATISTICS != cur_test_run.have_collect_statistics)
2436 {
2437 return;
2438 }
2439
2440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2441 "Going to request statistic values with mask 0x%" PRIx32 "\n",
2442 cur_test_run.stat_collect_flags);
2443
2444 struct STATcls *stat_cls;
2445 uint32_t stat_type;
2446 for (stat_type = STAT_TYPE_ROUNDS;
2447 stat_type < STAT_TYPE_MAX;
2448 stat_type++)
2449 {
2450 if (BIT(stat_type) & cur_test_run.stat_collect_flags)
2451 {
2452 stat_cls = GNUNET_malloc (sizeof (struct STATcls));
2453 stat_cls->rps_peer = rps_peer;
2454 stat_cls->stat_type = stat_type;
2455 rps_peer->file_name_stats =
2456 store_prefix_file_name (rps_peer->peer_id, "stats");
2457 GNUNET_STATISTICS_get (rps_peer->stats_h,
2458 "rps",
2459 stat_type_2_str (stat_type),
2460 post_test_shutdown_ready_cb,
2461 stat_iterator,
2462 (struct STATcls *) stat_cls);
2463 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2464 "Requested statistics for %s (peer %" PRIu32 ")\n",
2465 stat_type_2_str (stat_type),
2466 rps_peer->index);
2467 }
2468 }
2469}
2470
2471
2472/***********************************************************************
2473 * /Definition of tests
2474***********************************************************************/
2475
2476
2477/**
2478 * Actual "main" function for the testcase.
2479 *
2480 * @param cls closure
2481 * @param h the run handle
2482 * @param n_peers number of peers in 'peers'
2483 * @param peers handle to peers run in the testbed
2484 * @param links_succeeded the number of overlay link connection attempts that
2485 * succeeded
2486 * @param links_failed the number of overlay link connection attempts that
2487 * failed
2488 */
2489static void
2490test_run (void *cls,
2491 struct GNUNET_TESTBED_RunHandle *h,
2492 unsigned int n_peers,
2493 struct GNUNET_TESTBED_Peer **peers,
2494 unsigned int links_succeeded,
2495 unsigned int links_failed)
2496{
2497 unsigned int i;
2498 struct OpListEntry *entry;
2499
2500 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RUN was called\n");
2501 printf ("test 1\n");
2502
2503 /* Check whether we timed out */
2504 if (n_peers != num_peers ||
2505 NULL == peers ||
2506 0 == links_succeeded)
2507 {
2508 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Going down due to args (eg. timeout)\n");
2509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tn_peers: %u\n", n_peers);
2510 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tnum_peers: %" PRIu32 "\n", num_peers);
2511 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tpeers: %p\n", peers);
2512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tlinks_succeeded: %u\n", links_succeeded);
2513 GNUNET_SCHEDULER_shutdown ();
2514 return;
2515 }
2516
2517
2518 /* Initialize peers */
2519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "going to initialise peers\n");
2520 testbed_peers = peers;
2521 num_peers_online = 0;
2522 for (i = 0; i < num_peers; i++)
2523 {
2524 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "initialising %u\n", i);
2525 entry = make_oplist_entry ();
2526 entry->index = i;
2527 rps_peers[i].index = i;
2528 if (NULL != cur_test_run.init_peer)
2529 cur_test_run.init_peer (&rps_peers[i]);
2530 if (NO_COLLECT_VIEW == cur_test_run.have_collect_view)
2531 {
2532 rps_peers->cur_view_count = 0;
2533 rps_peers->cur_view = NULL;
2534 }
2535 entry->op = GNUNET_TESTBED_peer_get_information (peers[i],
2536 GNUNET_TESTBED_PIT_IDENTITY,
2537 &info_cb,
2538 entry);
2539 }
2540
2541 /* Bring peers up */
2542 GNUNET_assert (num_peers == n_peers);
2543 for (i = 0; i < n_peers; i++)
2544 {
2545 rps_peers[i].index = i;
2546 rps_peers[i].op =
2547 GNUNET_TESTBED_service_connect (&rps_peers[i],
2548 peers[i],
2549 "rps",
2550 &rps_connect_complete_cb,
2551 &rps_peers[i],
2552 &rps_connect_adapter,
2553 &rps_disconnect_adapter,
2554 &rps_peers[i]);
2555 /* Connect all peers to statistics service */
2556 if (COLLECT_STATISTICS == cur_test_run.have_collect_statistics)
2557 {
2558 rps_peers[i].stat_op =
2559 GNUNET_TESTBED_service_connect (NULL,
2560 peers[i],
2561 "statistics",
2562 stat_complete_cb,
2563 &rps_peers[i],
2564 &stat_connect_adapter,
2565 &stat_disconnect_adapter,
2566 &rps_peers[i]);
2567 }
2568 }
2569
2570 if (NULL != churn_task)
2571 GNUNET_SCHEDULER_cancel (churn_task);
2572 post_test_task = GNUNET_SCHEDULER_add_delayed (timeout, &post_test_op, NULL);
2573 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
2574 (timeout_s * 1.2) + 0.1 * num_peers);
2575 shutdown_task = GNUNET_SCHEDULER_add_delayed (timeout, &shutdown_op, NULL);
2576 shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_op, NULL);
2577
2578}
2579
2580
2581/**
2582 * Entry point for the testcase, sets up the testbed.
2583 *
2584 * @param argc unused
2585 * @param argv unused
2586 * @return 0 on success
2587 */
2588static void
2589run (void *cls,
2590 char *const *args,
2591 const char *cfgfile,
2592 const struct GNUNET_CONFIGURATION_Handle *cfg)
2593{
2594 //int ret_value;
2595
2596 /* Defaults for tests */
2597 churn_task = NULL;
2598
2599 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n");
2600 cur_test_run.name = "test-rps-profiler";
2601 num_peers = 10;
2602 mal_type = 3;
2603 cur_test_run.init_peer = profiler_init_peer;
2604 //cur_test_run.pre_test = mal_pre;
2605 cur_test_run.pre_test = pre_profiler;
2606 cur_test_run.main_test = profiler_cb;
2607 cur_test_run.reply_handle = profiler_reply_handle;
2608 cur_test_run.eval_cb = profiler_eval;
2609 cur_test_run.post_test = post_profiler;
2610 cur_test_run.request_interval = 2;
2611 cur_test_run.num_requests = 5;
2612 //cur_test_run.have_churn = HAVE_CHURN;
2613 cur_test_run.have_churn = HAVE_NO_CHURN;
2614 cur_test_run.have_quick_quit = HAVE_NO_QUICK_QUIT;
2615 cur_test_run.have_collect_statistics = COLLECT_STATISTICS;
2616 cur_test_run.stat_collect_flags = BIT(STAT_TYPE_ROUNDS) |
2617 BIT(STAT_TYPE_BLOCKS) |
2618 BIT(STAT_TYPE_BLOCKS_MANY_PUSH) |
2619 BIT(STAT_TYPE_BLOCKS_NO_PUSH) |
2620 BIT(STAT_TYPE_BLOCKS_NO_PULL) |
2621 BIT(STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL) |
2622 BIT(STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL) |
2623 BIT(STAT_TYPE_ISSUED_PUSH_SEND) |
2624 BIT(STAT_TYPE_ISSUED_PULL_REQ) |
2625 BIT(STAT_TYPE_ISSUED_PULL_REP) |
2626 BIT(STAT_TYPE_SENT_PUSH_SEND) |
2627 BIT(STAT_TYPE_SENT_PULL_REQ) |
2628 BIT(STAT_TYPE_SENT_PULL_REP) |
2629 BIT(STAT_TYPE_RECV_PUSH_SEND) |
2630 BIT(STAT_TYPE_RECV_PULL_REQ) |
2631 BIT(STAT_TYPE_RECV_PULL_REP);
2632 cur_test_run.have_collect_view = COLLECT_VIEW;
2633 timeout_s = 300;
2634
2635 /* 'Clean' directory */
2636 (void) GNUNET_DISK_directory_remove ("/tmp/rps/");
2637 GNUNET_DISK_directory_create ("/tmp/rps/");
2638 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, timeout_s);
2639
2640 /* Compute number of bits for representing largest peer id */
2641 for (bits_needed = 1; (bits_needed << 1) < num_peers - 1; bits_needed++)
2642 ;
2643 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2644 "Need %u bits to represent largest peer id %" PRIu32 "\n",
2645 bits_needed,
2646 num_peers - 1);
2647
2648 rps_peers = GNUNET_new_array (num_peers, struct RPSPeer);
2649 peer_map = GNUNET_CONTAINER_multipeermap_create (num_peers, GNUNET_NO);
2650 rps_peer_ids = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
2651 if ( (2 == mal_type) ||
2652 (3 == mal_type))
2653 target_peer = &rps_peer_ids[num_peers - 2];
2654 if (profiler_eval == cur_test_run.eval_cb)
2655 eval_peer = &rps_peers[num_peers - 1]; /* FIXME: eval_peer could be a
2656 malicious peer if not careful
2657 with the malicious portion */
2658
2659 ok = 1;
2660 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2661 "before _run()\n");
2662 GNUNET_TESTBED_run (NULL,
2663 cfg,
2664 num_peers,
2665 0, /* event mask */
2666 NULL,
2667 NULL,
2668 &test_run,
2669 NULL);
2670 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2671 "after _run()\n");
2672 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2673 "gnunet-rps-profiler returned.\n");
2674}
2675
2676/**
2677 * Entry point for the testcase, sets up the testbed.
2678 *
2679 * @param argc unused
2680 * @param argv unused
2681 * @return 0 on success
2682 */
2683int
2684main (int argc, char *argv[])
2685{
2686 int ret_value;
2687 struct GNUNET_GETOPT_CommandLineOption options[] = {
2688 GNUNET_GETOPT_option_uint ('n',
2689 "peers",
2690 "COUNT",
2691 gettext_noop ("number of peers to start"),
2692 &num_peers),
2693 GNUNET_GETOPT_OPTION_END
2694 };
2695
2696 //if (GNUNET_OK !=
2697 // GNUNET_STRINGS_get_utf8_args (argc, argv,
2698 // &argc, &argv))
2699 // return 2;
2700 ret_value = 0;
2701 if (GNUNET_OK !=
2702 GNUNET_PROGRAM_run (argc,
2703 argv,
2704 "gnunet-rps-profiler",
2705 gettext_noop ("Measure quality and performance of the RPS service."),
2706 options,
2707 &run,
2708 NULL))
2709 {
2710 ret_value = 1;
2711 }
2712 if (GNUNET_OK != ret_value)
2713 {
2714 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2715 "Test did not run successfully!\n");
2716 }
2717
2718 ret_value = cur_test_run.eval_cb();
2719 if (NO_COLLECT_VIEW == cur_test_run.have_collect_view)
2720 {
2721 GNUNET_array_grow (rps_peers->cur_view,
2722 rps_peers->cur_view_count,
2723 0);
2724 }
2725 GNUNET_free (rps_peers);
2726 GNUNET_free (rps_peer_ids);
2727 GNUNET_CONTAINER_multipeermap_destroy (peer_map);
2728 printf ("test -1\n");
2729 return ret_value;
2730}
2731
2732/* end of test_rps.c */
diff --git a/src/rps/gnunet-rps.c b/src/rps/gnunet-rps.c
index 8de588568..e09277589 100644
--- a/src/rps/gnunet-rps.c
+++ b/src/rps/gnunet-rps.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index eb47903e0..9e81330bd 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013-2015 GNUnet e.V. 3 Copyright (C) 2013-2015 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/gnunet-service-rps_custommap.c b/src/rps/gnunet-service-rps_custommap.c
index aef081a00..90177cb94 100644
--- a/src/rps/gnunet-service-rps_custommap.c
+++ b/src/rps/gnunet-service-rps_custommap.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/gnunet-service-rps_custommap.h b/src/rps/gnunet-service-rps_custommap.h
index f339b841d..b42ae9efa 100644
--- a/src/rps/gnunet-service-rps_custommap.h
+++ b/src/rps/gnunet-service-rps_custommap.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/gnunet-service-rps_sampler.c b/src/rps/gnunet-service-rps_sampler.c
index cfc5ce77b..711d5be63 100644
--- a/src/rps/gnunet-service-rps_sampler.c
+++ b/src/rps/gnunet-service-rps_sampler.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/gnunet-service-rps_sampler.h b/src/rps/gnunet-service-rps_sampler.h
index f33e7430c..c44844f96 100644
--- a/src/rps/gnunet-service-rps_sampler.h
+++ b/src/rps/gnunet-service-rps_sampler.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/gnunet-service-rps_sampler_elem.c b/src/rps/gnunet-service-rps_sampler_elem.c
index 007f818e2..7569801a6 100644
--- a/src/rps/gnunet-service-rps_sampler_elem.c
+++ b/src/rps/gnunet-service-rps_sampler_elem.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/gnunet-service-rps_sampler_elem.h b/src/rps/gnunet-service-rps_sampler_elem.h
index bbf2c147b..1dbdcbadd 100644
--- a/src/rps/gnunet-service-rps_sampler_elem.h
+++ b/src/rps/gnunet-service-rps_sampler_elem.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/gnunet-service-rps_view.c b/src/rps/gnunet-service-rps_view.c
index b7a0ba287..1fa75fc53 100644
--- a/src/rps/gnunet-service-rps_view.c
+++ b/src/rps/gnunet-service-rps_view.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/gnunet-service-rps_view.h b/src/rps/gnunet-service-rps_view.h
index 6a85a2134..127b49faf 100644
--- a/src/rps/gnunet-service-rps_view.h
+++ b/src/rps/gnunet-service-rps_view.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/rps-test_util.c b/src/rps/rps-test_util.c
index 869170a8a..9a1dfe0d8 100644
--- a/src/rps/rps-test_util.c
+++ b/src/rps/rps-test_util.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -31,13 +29,26 @@
31 29
32#include <inttypes.h> 30#include <inttypes.h>
33 31
34#define LOG(kind, ...) GNUNET_log_from(kind,"rps-sampler",__VA_ARGS__) 32#define LOG(kind, ...) GNUNET_log_from(kind,"rps-test_util",__VA_ARGS__)
35 33
36#ifndef TO_FILE 34#ifndef TO_FILE
37#define TO_FILE 35#define TO_FILE
38#endif /* TO_FILE */ 36#endif /* TO_FILE */
39 37
40#ifdef TO_FILE 38#ifdef TO_FILE
39
40#define min(x,y) ((x) > (y) ? (y) : (x))
41
42/**
43 * @brief buffer for storing the unaligned bits for the next write
44 */
45static char buf_unaligned;
46
47/**
48 * @brief number of bits in unaligned buffer
49 */
50static unsigned num_bits_buf_unaligned;
51
41void 52void
42to_file_ (const char *file_name, char *line) 53to_file_ (const char *file_name, char *line)
43{ 54{
@@ -109,6 +120,147 @@ to_file_ (const char *file_name, char *line)
109 "Unable to close file\n"); 120 "Unable to close file\n");
110} 121}
111 122
123void
124to_file_raw (const char *file_name, const char *buf, size_t size_buf)
125{
126 struct GNUNET_DISK_FileHandle *f;
127 size_t size_written;
128
129 if (NULL == (f = GNUNET_DISK_file_open (file_name,
130 GNUNET_DISK_OPEN_APPEND |
131 GNUNET_DISK_OPEN_WRITE |
132 GNUNET_DISK_OPEN_CREATE,
133 GNUNET_DISK_PERM_USER_READ |
134 GNUNET_DISK_PERM_USER_WRITE |
135 GNUNET_DISK_PERM_GROUP_READ |
136 GNUNET_DISK_PERM_OTHER_READ)))
137 {
138 LOG (GNUNET_ERROR_TYPE_WARNING,
139 "Not able to open file %s\n",
140 file_name);
141 return;
142 }
143
144 size_written = GNUNET_DISK_file_write (f, buf, size_buf);
145 if (size_buf != size_written)
146 {
147 LOG (GNUNET_ERROR_TYPE_WARNING,
148 "Unable to write to file! (Size: %u, size_written: %u)\n",
149 size_buf,
150 size_written);
151
152 if (GNUNET_YES != GNUNET_DISK_file_close (f))
153 LOG (GNUNET_ERROR_TYPE_WARNING,
154 "Unable to close file\n");
155
156 return;
157 }
158}
159
160void
161to_file_raw_unaligned (const char *file_name,
162 const char *buf,
163 size_t size_buf,
164 unsigned bits_needed)
165{
166 // TODO endianness!
167 GNUNET_assert (size_buf >= (bits_needed/8));
168 //if (0 == num_bits_buf_unaligned)
169 //{
170 // if (0 == (bits_needed % 8))
171 // {
172 // to_file_raw (file_name, buf, size_buf);
173 // return;
174 // }
175 // to_file_raw (file_name, buf, size_buf - 1);
176 // buf_unaligned = buf[size_buf - 1];
177 // num_bits_buf_unaligned = bits_needed % 8;
178 // return;
179 //}
180
181 char buf_write[size_buf + 1];
182 const unsigned bytes_iter = (0 != bits_needed % 8?
183 (bits_needed/8)+1:
184 bits_needed/8);
185 // TODO what if no iteration happens?
186 unsigned size_buf_write = 0;
187 buf_write[0] = buf_unaligned;
188 /* Iterate over input bytes */
189 for (unsigned i = 0; i < bytes_iter; i++)
190 {
191 /* Number of bits needed in this iteration - 8 for all except last iter */
192 unsigned num_bits_needed_iter;
193 /* Mask for bits to actually use */
194 unsigned mask_bits_needed_iter;
195 char byte_input;
196 /* Number of bits needed to align unaligned byte */
197 unsigned num_bits_to_align;
198 /* Number of bits that are to be moved */
199 unsigned num_bits_to_move;
200 /* Mask for bytes to be moved */
201 char mask_input_to_move;
202 /* Masked bits to be moved */
203 char bits_to_move;
204 /* The amount of bits needed to fit the bits to shift to the nearest spot */
205 unsigned distance_shift_bits;
206 /* Shifted bits on the move */
207 char bits_moving;
208 /* (unaligned) byte being filled with bits */
209 char byte_to_fill;
210 /* mask for needed bits of the input byte that have not been moved */
211 char mask_input_leftover;
212 /* needed bits of the input byte that have not been moved */
213 char byte_input_leftover;
214 unsigned num_bits_leftover;
215 unsigned num_bits_discard;
216 char byte_unaligned_new;
217
218 if ( (bits_needed - (i * 8)) <= 8)
219 {
220 /* last iteration */
221 num_bits_needed_iter = bits_needed - (i * 8);
222 }
223 else
224 {
225 num_bits_needed_iter = 8;
226 }
227 mask_bits_needed_iter = ((char) 1 << num_bits_needed_iter) - 1;
228 byte_input = buf[i];
229 byte_input &= mask_bits_needed_iter;
230 num_bits_to_align = 8 - num_bits_buf_unaligned;
231 num_bits_to_move = min (num_bits_to_align, num_bits_needed_iter);
232 mask_input_to_move = ((char) 1 << num_bits_to_move) - 1;
233 bits_to_move = byte_input & mask_input_to_move;
234 distance_shift_bits = num_bits_buf_unaligned;
235 bits_moving = bits_to_move << distance_shift_bits;
236 byte_to_fill = buf_unaligned | bits_moving;
237 if (num_bits_buf_unaligned + num_bits_needed_iter > 8)
238 {
239 /* buf_unaligned was aligned by filling
240 * -> can be written to storage */
241 buf_write[i] = byte_to_fill;
242 size_buf_write++;
243
244 /* store the leftover, unaligned bits in buffer */
245 mask_input_leftover = mask_bits_needed_iter & (~ mask_input_to_move);
246 byte_input_leftover = byte_input & mask_input_leftover;
247 num_bits_leftover = num_bits_needed_iter - num_bits_to_move;
248 num_bits_discard = 8 - num_bits_needed_iter;
249 byte_unaligned_new = byte_input_leftover >> num_bits_to_move;
250 buf_unaligned = byte_unaligned_new;
251 num_bits_buf_unaligned = num_bits_leftover % 8;
252 }
253 else
254 {
255 /* unaligned buffer still unaligned but 'fuller' */
256 buf_unaligned = byte_to_fill;
257 num_bits_buf_unaligned = (num_bits_buf_unaligned + bits_needed) % 8;
258 }
259 }
260 to_file_raw (file_name, buf_write, size_buf_write);
261 LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
262}
263
112char * 264char *
113auth_key_to_string (struct GNUNET_CRYPTO_AuthKey auth_key) 265auth_key_to_string (struct GNUNET_CRYPTO_AuthKey auth_key)
114{ 266{
diff --git a/src/rps/rps-test_util.h b/src/rps/rps-test_util.h
index 59f062331..577a2b0a7 100644
--- a/src/rps/rps-test_util.h
+++ b/src/rps/rps-test_util.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -76,5 +74,14 @@ const char *
76store_prefix_file_name (const struct GNUNET_PeerIdentity *peer, 74store_prefix_file_name (const struct GNUNET_PeerIdentity *peer,
77 const char *prefix); 75 const char *prefix);
78 76
77void
78to_file_raw (const char *file_name, const char *buf, size_t size_buf);
79
80void
81to_file_raw_unaligned (const char *file_name,
82 const char *buf,
83 size_t size_buf,
84 unsigned bits_needed);
85
79#endif /* RPS_TEST_UTIL_H */ 86#endif /* RPS_TEST_UTIL_H */
80/* end of gnunet-service-rps.c */ 87/* end of gnunet-service-rps.c */
diff --git a/src/rps/rps.conf.in b/src/rps/rps.conf.in
index b5feb1bd2..733b72601 100644
--- a/src/rps/rps.conf.in
+++ b/src/rps/rps.conf.in
@@ -24,4 +24,4 @@ FILENAME_VALID_PEERS = $GNUNET_DATA_HOME/rps/valid_peers.txt
24# until we receive the first estimate from NSE. 24# until we receive the first estimate from NSE.
25# Keep in mind, that (networksize)^(1/3) should be enough. 25# Keep in mind, that (networksize)^(1/3) should be enough.
26# So, 50 is enough for a network of size 50^3 = 125000 26# So, 50 is enough for a network of size 50^3 = 125000
27INITSIZE = 10 27MINSIZE = 10
diff --git a/src/rps/rps.h b/src/rps/rps.h
index 6a7fa3e14..6bf2273b4 100644
--- a/src/rps/rps.h
+++ b/src/rps/rps.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2012-2013 GNUnet e.V. 3 Copyright (C) 2012-2013 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */ 17 */
20/** 18/**
21 * @file rps/rps.h 19 * @file rps/rps.h
diff --git a/src/rps/rps_api.c b/src/rps/rps_api.c
index 0da3bd4a4..ca80e25e8 100644
--- a/src/rps/rps_api.c
+++ b/src/rps/rps_api.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/rps/test_rps.c b/src/rps/test_rps.c
index bae28428f..3ef1e6611 100644
--- a/src/rps/test_rps.c
+++ b/src/rps/test_rps.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009, 2012 GNUnet e.V. 3 Copyright (C) 2009, 2012 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file rps/test_rps.c 19 * @file rps/test_rps.c
@@ -42,6 +40,12 @@ static uint32_t num_peers;
42 40
43/** 41/**
44 * How long do we run the test? 42 * How long do we run the test?
43 * In seconds.
44 */
45static uint32_t timeout_s;
46
47/**
48 * How long do we run the test?
45 */ 49 */
46//#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) 50//#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
47static struct GNUNET_TIME_Relative timeout; 51static struct GNUNET_TIME_Relative timeout;
@@ -371,6 +375,11 @@ static int ok;
371/** 375/**
372 * Identifier for the churn task that runs periodically 376 * Identifier for the churn task that runs periodically
373 */ 377 */
378static struct GNUNET_SCHEDULER_Task *post_test_task;
379
380/**
381 * Identifier for the churn task that runs periodically
382 */
374static struct GNUNET_SCHEDULER_Task *shutdown_task; 383static struct GNUNET_SCHEDULER_Task *shutdown_task;
375 384
376/** 385/**
@@ -556,6 +565,11 @@ struct SingleTestRun
556} cur_test_run; 565} cur_test_run;
557 566
558/** 567/**
568 * Did we finish the test?
569 */
570static int post_test;
571
572/**
559 * Are we shutting down? 573 * Are we shutting down?
560 */ 574 */
561static int in_shutdown; 575static int in_shutdown;
@@ -755,6 +769,10 @@ shutdown_op (void *cls)
755 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 769 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
756 "Shutdown task scheduled, going down.\n"); 770 "Shutdown task scheduled, going down.\n");
757 in_shutdown = GNUNET_YES; 771 in_shutdown = GNUNET_YES;
772 if (NULL != post_test_task)
773 {
774 GNUNET_SCHEDULER_cancel (post_test_task);
775 }
758 if (NULL != churn_task) 776 if (NULL != churn_task)
759 { 777 {
760 GNUNET_SCHEDULER_cancel (churn_task); 778 GNUNET_SCHEDULER_cancel (churn_task);
@@ -762,8 +780,42 @@ shutdown_op (void *cls)
762 } 780 }
763 for (i = 0; i < num_peers; i++) 781 for (i = 0; i < num_peers; i++)
764 { 782 {
783 if (NULL != rps_peers[i].rps_handle)
784 {
785 GNUNET_RPS_disconnect (rps_peers[i].rps_handle);
786 }
765 if (NULL != rps_peers[i].op) 787 if (NULL != rps_peers[i].op)
788 {
766 GNUNET_TESTBED_operation_done (rps_peers[i].op); 789 GNUNET_TESTBED_operation_done (rps_peers[i].op);
790 }
791 }
792}
793
794
795/**
796 * Task run on timeout to collect statistics and potentially shut down.
797 */
798static void
799post_test_op (void *cls)
800{
801 unsigned int i;
802
803 post_test_task = NULL;
804 post_test = GNUNET_YES;
805 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
806 "Post test task scheduled, going down.\n");
807 if (NULL != churn_task)
808 {
809 GNUNET_SCHEDULER_cancel (churn_task);
810 churn_task = NULL;
811 }
812 for (i = 0; i < num_peers; i++)
813 {
814 if (NULL != rps_peers[i].op)
815 {
816 GNUNET_TESTBED_operation_done (rps_peers[i].op);
817 rps_peers[i].op = NULL;
818 }
767 if (NULL != cur_test_run.post_test) 819 if (NULL != cur_test_run.post_test)
768 { 820 {
769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing post_test for peer %u\n", i); 821 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing post_test for peer %u\n", i);
@@ -847,7 +899,7 @@ info_cb (void *cb_cls,
847{ 899{
848 struct OpListEntry *entry = (struct OpListEntry *) cb_cls; 900 struct OpListEntry *entry = (struct OpListEntry *) cb_cls;
849 901
850 if (GNUNET_YES == in_shutdown) 902 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
851 { 903 {
852 return; 904 return;
853 } 905 }
@@ -901,7 +953,7 @@ rps_connect_complete_cb (void *cls,
901 struct RPSPeer *rps_peer = cls; 953 struct RPSPeer *rps_peer = cls;
902 struct GNUNET_RPS_Handle *rps = ca_result; 954 struct GNUNET_RPS_Handle *rps = ca_result;
903 955
904 if (GNUNET_YES == in_shutdown) 956 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
905 { 957 {
906 return; 958 return;
907 } 959 }
@@ -1105,10 +1157,10 @@ default_reply_handle (void *cls,
1105 if (0 == evaluate () && HAVE_QUICK_QUIT == cur_test_run.have_quick_quit) 1157 if (0 == evaluate () && HAVE_QUICK_QUIT == cur_test_run.have_quick_quit)
1106 { 1158 {
1107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test succeeded before timeout\n"); 1159 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test succeeded before timeout\n");
1108 GNUNET_assert (NULL != shutdown_task); 1160 GNUNET_assert (NULL != post_test_task);
1109 GNUNET_SCHEDULER_cancel (shutdown_task); 1161 GNUNET_SCHEDULER_cancel (post_test_task);
1110 shutdown_task = GNUNET_SCHEDULER_add_now (&shutdown_op, NULL); 1162 post_test_task = GNUNET_SCHEDULER_add_now (&post_test_op, NULL);
1111 GNUNET_assert (NULL!= shutdown_task); 1163 GNUNET_assert (NULL!= post_test_task);
1112 } 1164 }
1113} 1165}
1114 1166
@@ -1122,7 +1174,7 @@ request_peers (void *cls)
1122 struct RPSPeer *rps_peer; 1174 struct RPSPeer *rps_peer;
1123 struct PendingReply *pending_rep; 1175 struct PendingReply *pending_rep;
1124 1176
1125 if (GNUNET_YES == in_shutdown) 1177 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1126 return; 1178 return;
1127 rps_peer = pending_req->rps_peer; 1179 rps_peer = pending_req->rps_peer;
1128 GNUNET_assert (1 <= rps_peer->num_pending_reqs); 1180 GNUNET_assert (1 <= rps_peer->num_pending_reqs);
@@ -1185,7 +1237,7 @@ cancel_request_cb (void *cls)
1185 struct RPSPeer *rps_peer = cls; 1237 struct RPSPeer *rps_peer = cls;
1186 struct PendingReply *pending_rep; 1238 struct PendingReply *pending_rep;
1187 1239
1188 if (GNUNET_YES == in_shutdown) 1240 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1189 return; 1241 return;
1190 pending_rep = rps_peer->pending_rep_head; 1242 pending_rep = rps_peer->pending_rep_head;
1191 GNUNET_assert (1 <= rps_peer->num_pending_reps); 1243 GNUNET_assert (1 <= rps_peer->num_pending_reps);
@@ -1290,7 +1342,7 @@ mal_cb (struct RPSPeer *rps_peer)
1290{ 1342{
1291 uint32_t num_mal_peers; 1343 uint32_t num_mal_peers;
1292 1344
1293 if (GNUNET_YES == in_shutdown) 1345 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1294 { 1346 {
1295 return; 1347 return;
1296 } 1348 }
@@ -1317,7 +1369,7 @@ mal_cb (struct RPSPeer *rps_peer)
1317static void 1369static void
1318single_req_cb (struct RPSPeer *rps_peer) 1370single_req_cb (struct RPSPeer *rps_peer)
1319{ 1371{
1320 if (GNUNET_YES == in_shutdown) 1372 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1321 { 1373 {
1322 return; 1374 return;
1323 } 1375 }
@@ -1331,7 +1383,7 @@ single_req_cb (struct RPSPeer *rps_peer)
1331static void 1383static void
1332delay_req_cb (struct RPSPeer *rps_peer) 1384delay_req_cb (struct RPSPeer *rps_peer)
1333{ 1385{
1334 if (GNUNET_YES == in_shutdown) 1386 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1335 { 1387 {
1336 return; 1388 return;
1337 } 1389 }
@@ -1345,7 +1397,7 @@ delay_req_cb (struct RPSPeer *rps_peer)
1345static void 1397static void
1346seed_cb (struct RPSPeer *rps_peer) 1398seed_cb (struct RPSPeer *rps_peer)
1347{ 1399{
1348 if (GNUNET_YES == in_shutdown) 1400 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1349 { 1401 {
1350 return; 1402 return;
1351 } 1403 }
@@ -1361,7 +1413,7 @@ seed_cb (struct RPSPeer *rps_peer)
1361static void 1413static void
1362seed_big_cb (struct RPSPeer *rps_peer) 1414seed_big_cb (struct RPSPeer *rps_peer)
1363{ 1415{
1364 if (GNUNET_YES == in_shutdown) 1416 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1365 { 1417 {
1366 return; 1418 return;
1367 } 1419 }
@@ -1387,7 +1439,7 @@ single_peer_seed_cb (struct RPSPeer *rps_peer)
1387static void 1439static void
1388seed_req_cb (struct RPSPeer *rps_peer) 1440seed_req_cb (struct RPSPeer *rps_peer)
1389{ 1441{
1390 if (GNUNET_YES == in_shutdown) 1442 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1391 { 1443 {
1392 return; 1444 return;
1393 } 1445 }
@@ -1406,7 +1458,7 @@ seed_req_cb (struct RPSPeer *rps_peer)
1406static void 1458static void
1407req_cancel_cb (struct RPSPeer *rps_peer) 1459req_cancel_cb (struct RPSPeer *rps_peer)
1408{ 1460{
1409 if (GNUNET_YES == in_shutdown) 1461 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1410 { 1462 {
1411 return; 1463 return;
1412 } 1464 }
@@ -1439,7 +1491,7 @@ churn (void *cls);
1439static void 1491static void
1440churn_test_cb (struct RPSPeer *rps_peer) 1492churn_test_cb (struct RPSPeer *rps_peer)
1441{ 1493{
1442 if (GNUNET_YES == in_shutdown) 1494 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1443 { 1495 {
1444 return; 1496 return;
1445 } 1497 }
@@ -1480,7 +1532,7 @@ churn_cb (void *cls,
1480 // FIXME 1532 // FIXME
1481 struct OpListEntry *entry = cls; 1533 struct OpListEntry *entry = cls;
1482 1534
1483 if (GNUNET_YES == in_shutdown) 1535 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1484 { 1536 {
1485 return; 1537 return;
1486 } 1538 }
@@ -1615,7 +1667,7 @@ churn (void *cls)
1615 double portion_go_online; 1667 double portion_go_online;
1616 double portion_go_offline; 1668 double portion_go_offline;
1617 1669
1618 if (GNUNET_YES == in_shutdown) 1670 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1619 { 1671 {
1620 return; 1672 return;
1621 } 1673 }
@@ -1731,7 +1783,7 @@ profiler_reply_handle (void *cls,
1731static void 1783static void
1732profiler_cb (struct RPSPeer *rps_peer) 1784profiler_cb (struct RPSPeer *rps_peer)
1733{ 1785{
1734 if (GNUNET_YES == in_shutdown) 1786 if (GNUNET_YES == in_shutdown || GNUNET_YES == post_test)
1735 { 1787 {
1736 return; 1788 return;
1737 } 1789 }
@@ -2644,7 +2696,12 @@ run (void *cls,
2644 2696
2645 if (NULL != churn_task) 2697 if (NULL != churn_task)
2646 GNUNET_SCHEDULER_cancel (churn_task); 2698 GNUNET_SCHEDULER_cancel (churn_task);
2699 post_test_task = GNUNET_SCHEDULER_add_delayed (timeout, &post_test_op, NULL);
2700 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
2701 (timeout_s * 1.2) + 0.1 * num_peers);
2647 shutdown_task = GNUNET_SCHEDULER_add_delayed (timeout, &shutdown_op, NULL); 2702 shutdown_task = GNUNET_SCHEDULER_add_delayed (timeout, &shutdown_op, NULL);
2703 shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_op, NULL);
2704
2648} 2705}
2649 2706
2650 2707
@@ -2673,7 +2730,7 @@ main (int argc, char *argv[])
2673 cur_test_run.stat_collect_flags = 0; 2730 cur_test_run.stat_collect_flags = 0;
2674 cur_test_run.have_collect_view = NO_COLLECT_VIEW; 2731 cur_test_run.have_collect_view = NO_COLLECT_VIEW;
2675 churn_task = NULL; 2732 churn_task = NULL;
2676 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30); 2733 timeout_s = 30;
2677 2734
2678 if (strstr (argv[0], "malicious") != NULL) 2735 if (strstr (argv[0], "malicious") != NULL)
2679 { 2736 {
@@ -2725,7 +2782,7 @@ main (int argc, char *argv[])
2725 cur_test_run.main_test = seed_big_cb; 2782 cur_test_run.main_test = seed_big_cb;
2726 cur_test_run.eval_cb = no_eval; 2783 cur_test_run.eval_cb = no_eval;
2727 cur_test_run.have_churn = HAVE_NO_CHURN; 2784 cur_test_run.have_churn = HAVE_NO_CHURN;
2728 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); 2785 timeout_s = 10;
2729 } 2786 }
2730 2787
2731 else if (strstr (argv[0], "_single_peer_seed") != NULL) 2788 else if (strstr (argv[0], "_single_peer_seed") != NULL)
@@ -2761,7 +2818,7 @@ main (int argc, char *argv[])
2761 cur_test_run.main_test = req_cancel_cb; 2818 cur_test_run.main_test = req_cancel_cb;
2762 cur_test_run.eval_cb = no_eval; 2819 cur_test_run.eval_cb = no_eval;
2763 cur_test_run.have_churn = HAVE_NO_CHURN; 2820 cur_test_run.have_churn = HAVE_NO_CHURN;
2764 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); 2821 timeout_s = 10;
2765 } 2822 }
2766 2823
2767 else if (strstr (argv[0], "_churn") != NULL) 2824 else if (strstr (argv[0], "_churn") != NULL)
@@ -2775,7 +2832,7 @@ main (int argc, char *argv[])
2775 cur_test_run.eval_cb = default_eval_cb; 2832 cur_test_run.eval_cb = default_eval_cb;
2776 cur_test_run.have_churn = HAVE_NO_CHURN; 2833 cur_test_run.have_churn = HAVE_NO_CHURN;
2777 cur_test_run.have_quick_quit = HAVE_NO_QUICK_QUIT; 2834 cur_test_run.have_quick_quit = HAVE_NO_QUICK_QUIT;
2778 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10); 2835 timeout_s = 10;
2779 } 2836 }
2780 2837
2781 else if (strstr (argv[0], "profiler") != NULL) 2838 else if (strstr (argv[0], "profiler") != NULL)
@@ -2814,12 +2871,13 @@ main (int argc, char *argv[])
2814 STAT_TYPE_RECV_PULL_REQ | 2871 STAT_TYPE_RECV_PULL_REQ |
2815 STAT_TYPE_RECV_PULL_REP; 2872 STAT_TYPE_RECV_PULL_REP;
2816 cur_test_run.have_collect_view = COLLECT_VIEW; 2873 cur_test_run.have_collect_view = COLLECT_VIEW;
2817 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300); 2874 timeout_s = 150;
2818 2875
2819 /* 'Clean' directory */ 2876 /* 'Clean' directory */
2820 (void) GNUNET_DISK_directory_remove ("/tmp/rps/"); 2877 (void) GNUNET_DISK_directory_remove ("/tmp/rps/");
2821 GNUNET_DISK_directory_create ("/tmp/rps/"); 2878 GNUNET_DISK_directory_create ("/tmp/rps/");
2822 } 2879 }
2880 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, timeout_s);
2823 2881
2824 rps_peers = GNUNET_new_array (num_peers, struct RPSPeer); 2882 rps_peers = GNUNET_new_array (num_peers, struct RPSPeer);
2825 peer_map = GNUNET_CONTAINER_multipeermap_create (num_peers, GNUNET_NO); 2883 peer_map = GNUNET_CONTAINER_multipeermap_create (num_peers, GNUNET_NO);
diff --git a/src/rps/test_rps.conf b/src/rps/test_rps.conf
index cf6b3150c..e4ed111e2 100644
--- a/src/rps/test_rps.conf
+++ b/src/rps/test_rps.conf
@@ -33,7 +33,7 @@ OVERLAY_TOPOLOGY = CLIQUE
33 33
34# OVERLAY_RANDOM_LINKS = 25 34# OVERLAY_RANDOM_LINKS = 25
35 35
36# SETUP_TIMEOUT = 2 m 36SETUP_TIMEOUT = 2 m
37 37
38[nse] 38[nse]
39WORKBITS = 0 39WORKBITS = 0
diff --git a/src/rps/test_rps_api.c b/src/rps/test_rps_api.c
index 546d8f285..85a0ccdd0 100644
--- a/src/rps/test_rps_api.c
+++ b/src/rps/test_rps_api.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file rps/test_rps_api.c 19 * @file rps/test_rps_api.c
diff --git a/src/rps/test_service_rps_custommap.c b/src/rps/test_service_rps_custommap.c
index f88842b79..8ce03070e 100644
--- a/src/rps/test_service_rps_custommap.c
+++ b/src/rps/test_service_rps_custommap.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file rps/test_service_rps_custommap.c 19 * @file rps/test_service_rps_custommap.c
diff --git a/src/rps/test_service_rps_sampler_elem.c b/src/rps/test_service_rps_sampler_elem.c
index 6f515d2c2..43efc8691 100644
--- a/src/rps/test_service_rps_sampler_elem.c
+++ b/src/rps/test_service_rps_sampler_elem.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file rps/test_service_rps_sampler_elem.c 19 * @file rps/test_service_rps_sampler_elem.c
diff --git a/src/rps/test_service_rps_view.c b/src/rps/test_service_rps_view.c
index 68d1b11d4..16cf4b832 100644
--- a/src/rps/test_service_rps_view.c
+++ b/src/rps/test_service_rps_view.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 3 Copyright (C)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file rps/test_service_rps_view.c 19 * @file rps/test_service_rps_view.c