aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2023-12-28 14:21:53 +0100
committerMartin Schanzenbach <schanzen@gnunet.org>2023-12-28 14:21:53 +0100
commite3d27ecd2e1a8d6089f523fee1cce04d0a015236 (patch)
tree7053704626c09c46f9a81d71ac280d29f1df74f4 /src
parente6902dd5c0e4722f31e2a3717f5e5ed336ae0647 (diff)
downloadgnunet-e3d27ecd2e1a8d6089f523fee1cce04d0a015236.tar.gz
gnunet-e3d27ecd2e1a8d6089f523fee1cce04d0a015236.zip
build: more post-tng unused source cleanup
Diffstat (limited to 'src')
-rw-r--r--src/contrib/service/rps/Makefile.am18
-rw-r--r--src/contrib/service/rps/gnunet-rps-profiler.c3199
-rw-r--r--src/contrib/service/secretsharing/Makefile.am13
-rw-r--r--src/contrib/service/secretsharing/gnunet-secretsharing-profiler.c662
-rw-r--r--src/service/cadet/cadet_test_lib.c376
-rw-r--r--src/service/cadet/cadet_test_lib.h106
-rw-r--r--src/service/dht/dht_test_lib.c202
-rw-r--r--src/service/dht/dht_test_lib.h95
-rw-r--r--src/service/dht/test_dht_monitor.c439
-rw-r--r--src/service/dht/test_dht_monitor.conf39
-rw-r--r--src/service/dht/test_dht_topo.c637
-rw-r--r--src/service/fs/Makefile.am9
-rw-r--r--src/service/fs/fs_test_lib.c630
-rw-r--r--src/service/fs/fs_test_lib.h102
-rw-r--r--src/service/fs/fs_test_lib_data.conf17
-rw-r--r--src/service/nse/Makefile.am14
-rw-r--r--src/service/nse/gnunet-nse-profiler.c921
-rw-r--r--src/service/regex/Makefile.am16
-rw-r--r--src/service/regex/gnunet-regex-simulation-profiler.c727
-rw-r--r--src/service/regex/regex_simulation_profiler_test.conf7
20 files changed, 0 insertions, 8229 deletions
diff --git a/src/contrib/service/rps/Makefile.am b/src/contrib/service/rps/Makefile.am
index 28aa3e050..1a3c9fa3a 100644
--- a/src/contrib/service/rps/Makefile.am
+++ b/src/contrib/service/rps/Makefile.am
@@ -45,10 +45,6 @@ libgnunetrps_la_CFLAGS = $(AM_CFLAGS)
45libexec_PROGRAMS = \ 45libexec_PROGRAMS = \
46 gnunet-service-rps 46 gnunet-service-rps
47 47
48#noinst_PROGRAMS = \
49# gnunet-rps-profiler
50
51
52gnunet_service_rps_SOURCES = \ 48gnunet_service_rps_SOURCES = \
53 gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \ 49 gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \
54 rps-sampler_common.h rps-sampler_common.c \ 50 rps-sampler_common.h rps-sampler_common.c \
@@ -149,19 +145,5 @@ test_service_rps_sampler_elem_LDADD = $(top_builddir)/src/lib/util/libgnunetutil
149#test_rps_malicious_3_SOURCES = $(rps_test_src) 145#test_rps_malicious_3_SOURCES = $(rps_test_src)
150#test_rps_malicious_3_LDADD = $(ld_rps_test_lib) 146#test_rps_malicious_3_LDADD = $(ld_rps_test_lib)
151 147
152#gnunet_rps_profiler_SOURCES = \
153# gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \
154# rps-sampler_common.h rps-sampler_common.c \
155# gnunet-service-rps_sampler.h gnunet-service-rps_sampler.c \
156# rps-test_util.h rps-test_util.c \
157# gnunet-rps-profiler.c
158#gnunet_rps_profiler_LDADD = \
159# $(top_builddir)/src/service/statistics/libgnunetstatistics.la \
160# libgnunetrps.la \
161# $(top_builddir)/src/lib/util/libgnunetutil.la \
162# $(top_builddir)/src/testbed/libgnunettestbed.la \
163# -lm
164
165
166EXTRA_DIST = \ 148EXTRA_DIST = \
167 test_rps.conf 149 test_rps.conf
diff --git a/src/contrib/service/rps/gnunet-rps-profiler.c b/src/contrib/service/rps/gnunet-rps-profiler.c
deleted file mode 100644
index df10ad5da..000000000
--- a/src/contrib/service/rps/gnunet-rps-profiler.c
+++ /dev/null
@@ -1,3199 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file rps/test_rps.c
22 * @brief Testcase for the random peer sampling service. Starts
23 * a peergroup with a given number of peers, then waits to
24 * receive size pushes/pulls from each peer. Expects to wait
25 * for one message from each peer.
26 */
27#include "platform.h"
28// #include "rps_test_lib.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_testbed_service.h"
31
32#include "gnunet_rps_service.h"
33#include "rps-test_util.h"
34#include "gnunet-service-rps_sampler_elem.h"
35
36#include <inttypes.h>
37
38
39#define BIT(n) (1 << (n))
40
41/**
42 * How many peers do we start?
43 */
44static uint32_t num_peers;
45
46/**
47 * @brief number of bits required to represent the largest peer id
48 */
49static unsigned bits_needed;
50
51/**
52 * How long do we run the test?
53 */
54static struct GNUNET_TIME_Relative duration;
55
56/**
57 * When do we do a hard shutdown?
58 */
59static struct GNUNET_TIME_Relative timeout;
60
61
62// /**
63// * Portion of malicious peers
64// */
65// static 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_PUSH_SEND_MH, /* 8 */
88 STAT_TYPE_ISSUED_PULL_REQ, /* 9 */
89 STAT_TYPE_ISSUED_PULL_REQ_MH, /* 10 */
90 STAT_TYPE_ISSUED_PULL_REP, /* 11 */
91 STAT_TYPE_SENT_PUSH_SEND, /* 12 */
92 STAT_TYPE_SENT_PULL_REQ, /* 13 */
93 STAT_TYPE_SENT_PULL_REQ_MH, /* 14 */
94 STAT_TYPE_SENT_PULL_REP, /* 15 */
95 STAT_TYPE_RECV_PUSH_SEND, /* 16 */
96 STAT_TYPE_RECV_PUSH_SEND_MH, /* 17 */
97 STAT_TYPE_RECV_PULL_REQ, /* 18 */
98 STAT_TYPE_RECV_PULL_REQ_MH, /* 19 */
99 STAT_TYPE_RECV_PULL_REP, /* 20 */
100 STAT_TYPE_RECV_PULL_REP_MH, /* 21 */
101 STAT_TYPE_VIEW_SIZE, /* 22 */
102 STAT_TYPE_KNOWN_PEERS, /* 23 */
103 STAT_TYPE_VALID_PEERS, /* 24 */
104 STAT_TYPE_LEARND_PEERS, /* 25 */
105 STAT_TYPE_PENDING_ONLINE_CHECKS, /* 26 */
106 STAT_TYPE_UNREQUESTED_PULL_REPLIES, /* 27 */
107 STAT_TYPE_PEERS_IN_PUSH_MAP, /* 28 */
108 STAT_TYPE_PEERS_IN_PULL_MAP, /* 29 */
109 STAT_TYPE_PEERS_IN_VIEW, /* 30 */
110 STAT_TYPE_VIEW_SIZE_AIM, /* 31 */
111 STAT_TYPE_MAX, /* 32 */
112};
113
114static char*stat_type_strings[] = {
115 "# rounds",
116 "# rounds blocked",
117 "# rounds blocked - too many pushes",
118 "# rounds blocked - no pushes",
119 "# rounds blocked - no pull replies",
120 "# rounds blocked - too many pushes, no pull replies",
121 "# rounds blocked - no pushes, no pull replies",
122 "# push send issued",
123 "# push send issued (multi-hop peer)",
124 "# pull request send issued",
125 "# pull request send issued (multi-hop peer)",
126 "# pull reply send issued",
127 "# pushes sent",
128 "# pull requests sent",
129 "# pull requests sent (multi-hop peer)",
130 "# pull replies sent",
131 "# push message received",
132 "# push message received (multi-hop peer)",
133 "# pull request message received",
134 "# pull request message received (multi-hop peer)",
135 "# pull reply messages received",
136 "# pull reply messages received (multi-hop peer)",
137 "view size",
138 "# known peers",
139 "# valid peers",
140 "# learnd peers",
141 "# pending online checks",
142 "# unrequested pull replies",
143 "# peers in push map at end of round",
144 "# peers in pull map at end of round",
145 "# peers in view at end of round",
146 "view size aim",
147};
148
149struct STATcls
150{
151 struct RPSPeer *rps_peer;
152 enum STAT_TYPE stat_type;
153};
154
155
156/**
157 * @brief Converts string representation to the corresponding #STAT_TYPE enum.
158 *
159 * @param stat_str string representation of statistics specifier
160 *
161 * @return corresponding enum
162 */
163enum STAT_TYPE
164stat_str_2_type (const char *stat_str)
165{
166 if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_NO_PULL],
167 stat_str,
168 strlen (stat_type_strings[STAT_TYPE_BLOCKS_NO_PULL])))
169 {
170 return STAT_TYPE_BLOCKS_NO_PULL;
171 }
172 else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL],
173 stat_str,
174 strlen (
175 stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL])))
176 {
177 return STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL;
178 }
179 else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH],
180 stat_str,
181 strlen (
182 stat_type_strings[STAT_TYPE_BLOCKS_MANY_PUSH])))
183 {
184 return STAT_TYPE_BLOCKS_MANY_PUSH;
185 }
186 else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL],
187 stat_str,
188 strlen (
189 stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL])))
190 {
191 return STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL;
192 }
193 else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH],
194 stat_str,
195 strlen (stat_type_strings[STAT_TYPE_BLOCKS_NO_PUSH])))
196 {
197 return STAT_TYPE_BLOCKS_NO_PUSH;
198 }
199 else if (0 == strncmp (stat_type_strings[STAT_TYPE_BLOCKS],
200 stat_str,
201 strlen (stat_type_strings[STAT_TYPE_BLOCKS])))
202 {
203 return STAT_TYPE_BLOCKS;
204 }
205 else if (0 == strncmp (stat_type_strings[STAT_TYPE_ROUNDS],
206 stat_str,
207 strlen (stat_type_strings[STAT_TYPE_ROUNDS])))
208 {
209 return STAT_TYPE_ROUNDS;
210 }
211 else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND],
212 stat_str,
213 strlen (
214 stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND])))
215 {
216 return STAT_TYPE_ISSUED_PUSH_SEND;
217 }
218 else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND_MH],
219 stat_str,
220 strlen (
221 stat_type_strings[STAT_TYPE_ISSUED_PUSH_SEND_MH])))
222 {
223 return STAT_TYPE_ISSUED_PUSH_SEND_MH;
224 }
225 else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ],
226 stat_str,
227 strlen (stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ])))
228 {
229 return STAT_TYPE_ISSUED_PULL_REQ;
230 }
231 else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ_MH],
232 stat_str,
233 strlen (
234 stat_type_strings[STAT_TYPE_ISSUED_PULL_REQ_MH])))
235 {
236 return STAT_TYPE_ISSUED_PULL_REQ_MH;
237 }
238 else if (0 == strncmp (stat_type_strings[STAT_TYPE_ISSUED_PULL_REP],
239 stat_str,
240 strlen (stat_type_strings[STAT_TYPE_ISSUED_PULL_REP])))
241 {
242 return STAT_TYPE_ISSUED_PULL_REP;
243 }
244 else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PUSH_SEND],
245 stat_str,
246 strlen (stat_type_strings[STAT_TYPE_SENT_PUSH_SEND])))
247 {
248 return STAT_TYPE_SENT_PUSH_SEND;
249 }
250 else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PULL_REQ],
251 stat_str,
252 strlen (stat_type_strings[STAT_TYPE_SENT_PULL_REQ])))
253 {
254 return STAT_TYPE_SENT_PULL_REQ;
255 }
256 else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PULL_REQ_MH],
257 stat_str,
258 strlen (
259 stat_type_strings[STAT_TYPE_SENT_PULL_REQ_MH])))
260 {
261 return STAT_TYPE_SENT_PULL_REQ_MH;
262 }
263 else if (0 == strncmp (stat_type_strings[STAT_TYPE_SENT_PULL_REP],
264 stat_str,
265 strlen (stat_type_strings[STAT_TYPE_SENT_PULL_REP])))
266 {
267 return STAT_TYPE_SENT_PULL_REP;
268 }
269 else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PUSH_SEND],
270 stat_str,
271 strlen (stat_type_strings[STAT_TYPE_RECV_PUSH_SEND])))
272 {
273 return STAT_TYPE_RECV_PUSH_SEND;
274 }
275 else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PUSH_SEND_MH],
276 stat_str,
277 strlen (
278 stat_type_strings[STAT_TYPE_RECV_PUSH_SEND_MH])))
279 {
280 return STAT_TYPE_RECV_PUSH_SEND_MH;
281 }
282 else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REQ],
283 stat_str,
284 strlen (stat_type_strings[STAT_TYPE_RECV_PULL_REQ])))
285 {
286 return STAT_TYPE_RECV_PULL_REQ;
287 }
288 else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REQ_MH],
289 stat_str,
290 strlen (
291 stat_type_strings[STAT_TYPE_RECV_PULL_REQ_MH])))
292 {
293 return STAT_TYPE_RECV_PULL_REQ_MH;
294 }
295 else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REP],
296 stat_str,
297 strlen (stat_type_strings[STAT_TYPE_RECV_PULL_REP])))
298 {
299 return STAT_TYPE_RECV_PULL_REP;
300 }
301 else if (0 == strncmp (stat_type_strings[STAT_TYPE_RECV_PULL_REP_MH],
302 stat_str,
303 strlen (
304 stat_type_strings[STAT_TYPE_RECV_PULL_REP_MH])))
305 {
306 return STAT_TYPE_RECV_PULL_REP_MH;
307 }
308 else if (0 == strncmp (stat_type_strings[STAT_TYPE_VIEW_SIZE],
309 stat_str,
310 strlen (stat_type_strings[STAT_TYPE_VIEW_SIZE])))
311 {
312 return STAT_TYPE_VIEW_SIZE;
313 }
314 else if (0 == strncmp (stat_type_strings[STAT_TYPE_KNOWN_PEERS],
315 stat_str,
316 strlen (stat_type_strings[STAT_TYPE_KNOWN_PEERS])))
317 {
318 return STAT_TYPE_KNOWN_PEERS;
319 }
320 else if (0 == strncmp (stat_type_strings[STAT_TYPE_VALID_PEERS],
321 stat_str,
322 strlen (stat_type_strings[STAT_TYPE_VALID_PEERS])))
323 {
324 return STAT_TYPE_VALID_PEERS;
325 }
326 else if (0 == strncmp (stat_type_strings[STAT_TYPE_LEARND_PEERS],
327 stat_str,
328 strlen (stat_type_strings[STAT_TYPE_LEARND_PEERS])))
329 {
330 return STAT_TYPE_LEARND_PEERS;
331 }
332 else if (0 == strncmp (stat_type_strings[STAT_TYPE_PENDING_ONLINE_CHECKS],
333 stat_str,
334 strlen (
335 stat_type_strings[STAT_TYPE_PENDING_ONLINE_CHECKS])))
336 {
337 return STAT_TYPE_PENDING_ONLINE_CHECKS;
338 }
339 else if (0 == strncmp (stat_type_strings[STAT_TYPE_UNREQUESTED_PULL_REPLIES],
340 stat_str,
341 strlen (
342 stat_type_strings[STAT_TYPE_UNREQUESTED_PULL_REPLIES])))
343 {
344 return STAT_TYPE_UNREQUESTED_PULL_REPLIES;
345 }
346 else if (0 == strncmp (stat_type_strings[STAT_TYPE_PEERS_IN_PUSH_MAP],
347 stat_str,
348 strlen (
349 stat_type_strings[STAT_TYPE_PEERS_IN_PUSH_MAP])))
350 {
351 return STAT_TYPE_PEERS_IN_PUSH_MAP;
352 }
353 else if (0 == strncmp (stat_type_strings[STAT_TYPE_PEERS_IN_PULL_MAP],
354 stat_str,
355 strlen (
356 stat_type_strings[STAT_TYPE_PEERS_IN_PULL_MAP])))
357 {
358 return STAT_TYPE_PEERS_IN_PULL_MAP;
359 }
360 else if (0 == strncmp (stat_type_strings[STAT_TYPE_PEERS_IN_VIEW],
361 stat_str,
362 strlen (stat_type_strings[STAT_TYPE_PEERS_IN_VIEW])))
363 {
364 return STAT_TYPE_PEERS_IN_VIEW;
365 }
366 else if (0 == strncmp (stat_type_strings[STAT_TYPE_VIEW_SIZE_AIM],
367 stat_str,
368 strlen (stat_type_strings[STAT_TYPE_VIEW_SIZE_AIM])))
369 {
370 return STAT_TYPE_VIEW_SIZE_AIM;
371 }
372 return STAT_TYPE_MAX;
373}
374
375
376/**
377 * @brief Indicates whether peer should go off- or online
378 */
379enum PEER_ONLINE_DELTA
380{
381 /**
382 * @brief Indicates peer going online
383 */
384 PEER_GO_ONLINE = 1,
385 /**
386 * @brief Indicates peer going offline
387 */
388 PEER_GO_OFFLINE = -1,
389};
390
391/**
392 * Operation map entry
393 */
394struct OpListEntry
395{
396 /**
397 * DLL next ptr
398 */
399 struct OpListEntry *next;
400
401 /**
402 * DLL prev ptr
403 */
404 struct OpListEntry *prev;
405
406 /**
407 * The testbed operation
408 */
409 struct GNUNET_TESTBED_Operation *op;
410
411 /**
412 * Depending on whether we start or stop RPS service at the peer, set this to
413 * #PEER_GO_ONLINE (1) or #PEER_GO_OFFLINE (-1)
414 */
415 enum PEER_ONLINE_DELTA delta;
416
417 /**
418 * Index of the regarding peer
419 */
420 unsigned int index;
421};
422
423/**
424 * OpList DLL head
425 */
426static struct OpListEntry *oplist_head;
427
428/**
429 * OpList DLL tail
430 */
431static struct OpListEntry *oplist_tail;
432
433
434/**
435 * A pending reply: A request was sent and the reply is pending.
436 */
437struct PendingReply
438{
439 /**
440 * DLL next,prev ptr
441 */
442 struct PendingReply *next;
443 struct PendingReply *prev;
444
445 /**
446 * Handle to the request we are waiting for
447 */
448 struct GNUNET_RPS_Request_Handle_Single_Info *req_handle;
449
450 /**
451 * The peer that requested
452 */
453 struct RPSPeer *rps_peer;
454};
455
456
457/**
458 * A pending request: A request was not made yet but is scheduled for later.
459 */
460struct PendingRequest
461{
462 /**
463 * DLL next,prev ptr
464 */
465 struct PendingRequest *next;
466 struct PendingRequest *prev;
467
468 /**
469 * Handle to the request we are waiting for
470 */
471 struct GNUNET_SCHEDULER_Task *request_task;
472
473 /**
474 * The peer that requested
475 */
476 struct RPSPeer *rps_peer;
477};
478
479
480/**
481 * Information we track for each peer.
482 */
483struct RPSPeer
484{
485 /**
486 * Index of the peer.
487 */
488 uint32_t index;
489
490 /**
491 * Handle for RPS connect operation.
492 */
493 struct GNUNET_TESTBED_Operation *op;
494
495 /**
496 * Handle to RPS service.
497 */
498 struct GNUNET_RPS_Handle *rps_handle;
499
500 /**
501 * ID of the peer.
502 */
503 struct GNUNET_PeerIdentity *peer_id;
504
505 /**
506 * A request handle to check for an request
507 */
508 // struct GNUNET_RPS_Request_Handle *req_handle;
509
510 /**
511 * Peer on- or offline?
512 */
513 int online;
514
515 /**
516 * Number of Peer IDs to request during the whole test
517 */
518 unsigned int num_ids_to_request;
519
520 /**
521 * Pending requests DLL
522 */
523 struct PendingRequest *pending_req_head;
524 struct PendingRequest *pending_req_tail;
525
526 /**
527 * Number of pending requests
528 */
529 unsigned int num_pending_reqs;
530
531 /**
532 * Pending replies DLL
533 */
534 struct PendingReply *pending_rep_head;
535 struct PendingReply *pending_rep_tail;
536
537 /**
538 * Number of pending replies
539 */
540 unsigned int num_pending_reps;
541
542 /**
543 * Number of received PeerIDs
544 */
545 unsigned int num_recv_ids;
546
547 /**
548 * Pending operation on that peer
549 */
550 const struct OpListEntry *entry_op_manage;
551
552 /**
553 * Testbed operation to connect to statistics service
554 */
555 struct GNUNET_TESTBED_Operation *stat_op;
556
557 /**
558 * Handle to the statistics service
559 */
560 struct GNUNET_STATISTICS_Handle *stats_h;
561
562 /**
563 * @brief flags to indicate which statistics values have been already
564 * collected from the statistics service.
565 * Used to check whether we are able to shutdown.
566 */
567 uint32_t stat_collected_flags;
568
569 /**
570 * @brief File name of the file the stats are finally written to
571 */
572 const char *file_name_stats;
573
574 /**
575 * @brief File name of the file the stats are finally written to
576 */
577 const char *file_name_probs;
578
579 /**
580 * @brief File name of the file the stats are finally written to
581 */
582 const char *file_name_probs_hist;
583
584 /**
585 * @brief The current view
586 */
587 struct GNUNET_PeerIdentity *cur_view;
588
589 /**
590 * @brief Number of peers in the #cur_view.
591 */
592 uint32_t cur_view_count;
593
594 /**
595 * @brief Number of occurrences in other peer's view
596 */
597 uint32_t count_in_views;
598
599 /**
600 * @brief statistics values
601 */
602 uint64_t stats[STAT_TYPE_MAX];
603 /**
604 * @brief Handle for the statistics get request
605 */
606 struct GNUNET_STATISTICS_GetHandle *h_stat_get[STAT_TYPE_MAX];
607
608 /**
609 * @brief Keep the probabilities in cache for computing the probabilities
610 * with respect to history.
611 */
612 double *eval_probs_cache;
613};
614
615/**
616 * Information for all the peers.
617 */
618static struct RPSPeer *rps_peers;
619
620/**
621 * Peermap to get the index of a given peer ID quick.
622 */
623static struct GNUNET_CONTAINER_MultiPeerMap *peer_map;
624
625/**
626 * IDs of the peers.
627 */
628static struct GNUNET_PeerIdentity *rps_peer_ids;
629
630/**
631 * ID of the targeted peer.
632 */
633static struct GNUNET_PeerIdentity *target_peer;
634
635/**
636 * Number of online peers.
637 */
638static unsigned int num_peers_online;
639
640/**
641 * @brief The added sizes of the peer's views
642 */
643static unsigned int view_sizes;
644
645/**
646 * Return value from 'main'.
647 */
648static int ok;
649
650/**
651 * Identifier for the task that runs after the test to collect results
652 */
653static struct GNUNET_SCHEDULER_Task *post_test_task;
654
655/**
656 * Identifier for the shutdown task
657 */
658static struct GNUNET_SCHEDULER_Task *shutdown_task;
659
660
661/**
662 * Identifier for the churn task that runs periodically
663 */
664static struct GNUNET_SCHEDULER_Task *churn_task;
665
666/**
667 * Called to initialise the given RPSPeer
668 */
669typedef void (*InitPeer) (struct RPSPeer *rps_peer);
670
671/**
672 * @brief Called directly after connecting to the service
673 *
674 * @param rps_peer Specific peer the function is called on
675 * @param h the handle to the rps service
676 */
677typedef void (*PreTest) (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h);
678
679/**
680 * @brief Executes functions to test the api/service for a given peer
681 *
682 * Called from within #rps_connect_complete_cb ()
683 * Implemented by #churn_test_cb, #profiler_cb, #mal_cb, #single_req_cb,
684 * #delay_req_cb, #seed_big_cb, #single_peer_seed_cb, #seed_cb, #req_cancel_cb
685 *
686 * @param rps_peer the peer the task runs on
687 */
688typedef void (*MainTest) (struct RPSPeer *rps_peer);
689
690/**
691 * Callback called once the requested random peers are available
692 */
693typedef void (*ReplyHandle) (void *cls,
694 uint64_t n,
695 const struct GNUNET_PeerIdentity *recv_peers);
696
697/**
698 * Called directly before disconnecting from the service
699 */
700typedef void (*PostTest) (struct RPSPeer *peer);
701
702/**
703 * Function called after disconnect to evaluate test success
704 */
705typedef int (*EvaluationCallback) (void);
706
707/**
708 * @brief Do we have Churn?
709 */
710enum OPTION_CHURN
711{
712 /**
713 * @brief If we have churn this is set
714 */
715 HAVE_CHURN,
716 /**
717 * @brief If we have no churn this is set
718 */
719 HAVE_NO_CHURN,
720};
721
722/**
723 * @brief Is it ok to quit the test before the timeout?
724 */
725enum OPTION_QUICK_QUIT
726{
727 /**
728 * @brief It is ok for the test to quit before the timeout triggers
729 */
730 HAVE_QUICK_QUIT,
731
732 /**
733 * @brief It is NOT ok for the test to quit before the timeout triggers
734 */
735 HAVE_NO_QUICK_QUIT,
736};
737
738/**
739 * @brief Do we collect statistics at the end?
740 */
741enum OPTION_COLLECT_STATISTICS
742{
743 /**
744 * @brief We collect statistics at the end
745 */
746 COLLECT_STATISTICS,
747
748 /**
749 * @brief We do not collect statistics at the end
750 */
751 NO_COLLECT_STATISTICS,
752};
753
754/**
755 * @brief Do we collect views during run?
756 */
757enum OPTION_COLLECT_VIEW
758{
759 /**
760 * @brief We collect view during run
761 */
762 COLLECT_VIEW,
763
764 /**
765 * @brief We do not collect the view during run
766 */
767 NO_COLLECT_VIEW,
768};
769
770/**
771 * Structure to define a single test
772 */
773struct SingleTestRun
774{
775 /**
776 * Name of the test
777 */
778 char *name;
779
780 /**
781 * Called with a single peer in order to initialise that peer
782 */
783 InitPeer init_peer;
784
785 /**
786 * Called directly after connecting to the service
787 */
788 PreTest pre_test;
789
790 /**
791 * Main function for each peer
792 */
793 MainTest main_test;
794
795 /**
796 * Callback called once the requested peers are available
797 */
798 ReplyHandle reply_handle;
799
800 /**
801 * Called directly before disconnecting from the service
802 */
803 PostTest post_test;
804
805 /**
806 * Function to evaluate the test results
807 */
808 EvaluationCallback eval_cb;
809
810 /**
811 * Request interval
812 */
813 uint32_t request_interval;
814
815 /**
816 * Number of Requests to make.
817 */
818 uint32_t num_requests;
819
820 /**
821 * Run with (-out) churn
822 */
823 enum OPTION_CHURN have_churn;
824
825 /**
826 * Quit test before timeout?
827 */
828 enum OPTION_QUICK_QUIT have_quick_quit;
829
830 /**
831 * Collect statistics at the end?
832 */
833 enum OPTION_COLLECT_STATISTICS have_collect_statistics;
834
835 /**
836 * Collect view during run?
837 */
838 enum OPTION_COLLECT_VIEW have_collect_view;
839
840 /**
841 * @brief Mark which values from the statistics service to collect at the end
842 * of the run
843 */
844 uint32_t stat_collect_flags;
845} cur_test_run;
846
847/**
848 * Did we finish the test?
849 */
850static int post_test;
851
852/**
853 * Are we shutting down?
854 */
855static int in_shutdown;
856
857/**
858 * Append arguments to file
859 */
860static void
861tofile_ (const char *file_name, const char *line)
862{
863 struct GNUNET_DISK_FileHandle *f;
864 /* char output_buffer[512]; */
865 size_t size;
866 /* int size; */
867 size_t size2;
868
869 if (NULL == (f = GNUNET_DISK_file_open (file_name,
870 GNUNET_DISK_OPEN_APPEND
871 | GNUNET_DISK_OPEN_WRITE
872 | GNUNET_DISK_OPEN_CREATE,
873 GNUNET_DISK_PERM_USER_READ
874 | GNUNET_DISK_PERM_USER_WRITE
875 | GNUNET_DISK_PERM_GROUP_READ
876 | GNUNET_DISK_PERM_OTHER_READ)))
877 {
878 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
879 "Not able to open file %s\n",
880 file_name);
881 return;
882 }
883 /* size = GNUNET_snprintf (output_buffer,
884 sizeof (output_buffer),
885 "%llu %s\n",
886 GNUNET_TIME_absolute_get ().abs_value_us,
887 line);
888 if (0 > size)
889 {
890 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
891 "Failed to write string to buffer (size: %i)\n",
892 size);
893 return;
894 } */size = strlen (line) * sizeof(char);
895
896 size2 = GNUNET_DISK_file_write (f, line, size);
897 if (size != size2)
898 {
899 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
900 "Unable to write to file! (Size: %lu, size2: %lu)\n",
901 size,
902 size2);
903 if (GNUNET_YES != GNUNET_DISK_file_close (f))
904 {
905 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
906 "Unable to close file\n");
907 }
908 return;
909 }
910
911 if (GNUNET_YES != GNUNET_DISK_file_close (f))
912 {
913 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
914 "Unable to close file\n");
915 }
916}
917
918
919/**
920 * This function is used to facilitate writing important information to disk
921 */
922#define tofile(file_name, ...) do { \
923 char tmp_buf[512]; \
924 int size; \
925 size = GNUNET_snprintf (tmp_buf, sizeof(tmp_buf), __VA_ARGS__); \
926 if (0 > size) \
927 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \
928 "Failed to create tmp_buf\n"); \
929 else \
930 tofile_ (file_name, tmp_buf); \
931} while (0);
932
933
934/**
935 * Write the ids and their according index in the given array to a file
936 * Unused
937 */
938/* static void
939 ids_to_file (char *file_name,
940 struct GNUNET_PeerIdentity *peer_ids,
941 unsigned int num_peer_ids)
942 {
943 unsigned int i;
944
945 for (i=0 ; i < num_peer_ids ; i++)
946 {
947 to_file (file_name,
948 "%u\t%s",
949 i,
950 GNUNET_i2s_full (&peer_ids[i]));
951 }
952 } */
953
954/**
955 * Test the success of a single test
956 */
957static int
958evaluate (void)
959{
960 unsigned int i;
961 int tmp_ok;
962
963 tmp_ok = 1;
964
965 for (i = 0; i < num_peers; i++)
966 {
967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
968 "%u. peer [%s] received %u of %u expected peer_ids: %i\n",
969 i,
970 GNUNET_i2s (rps_peers[i].peer_id),
971 rps_peers[i].num_recv_ids,
972 rps_peers[i].num_ids_to_request,
973 (rps_peers[i].num_ids_to_request == rps_peers[i].num_recv_ids));
974 tmp_ok &= (rps_peers[i].num_ids_to_request == rps_peers[i].num_recv_ids);
975 }
976 return tmp_ok ? 0 : 1;
977}
978
979
980/**
981 * Creates an oplist entry and adds it to the oplist DLL
982 */
983static struct OpListEntry *
984make_oplist_entry ()
985{
986 struct OpListEntry *entry;
987
988 entry = GNUNET_new (struct OpListEntry);
989 GNUNET_CONTAINER_DLL_insert_tail (oplist_head, oplist_tail, entry);
990 return entry;
991}
992
993
994/**
995 * @brief Checks if given peer already received its statistics value from the
996 * statistics service.
997 *
998 * @param rps_peer the peer to check for
999 *
1000 * @return #GNUNET_YES if so
1001 * #GNUNET_NO otherwise
1002 */
1003static int
1004check_statistics_collect_completed_single_peer (
1005 const struct RPSPeer *rps_peer)
1006{
1007 if (cur_test_run.stat_collect_flags !=
1008 (cur_test_run.stat_collect_flags
1009 & rps_peer->stat_collected_flags))
1010 {
1011 return GNUNET_NO;
1012 }
1013 return GNUNET_YES;
1014}
1015
1016
1017/**
1018 * @brief Checks if all peers already received their statistics value from the
1019 * statistics service.
1020 *
1021 * @return #GNUNET_YES if so
1022 * #GNUNET_NO otherwise
1023 */
1024static int
1025check_statistics_collect_completed ()
1026{
1027 uint32_t i;
1028
1029 for (i = 0; i < num_peers; i++)
1030 {
1031 if (GNUNET_NO == check_statistics_collect_completed_single_peer (
1032 &rps_peers[i]))
1033 {
1034 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1035 "At least Peer %" PRIu32
1036 " did not yet receive all statistics values\n",
1037 i);
1038 return GNUNET_NO;
1039 }
1040 }
1041 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1042 "All peers received their statistics values\n");
1043 return GNUNET_YES;
1044}
1045
1046
1047static void
1048rps_disconnect_adapter (void *cls,
1049 void *op_result);
1050
1051static void
1052cancel_pending_req (struct PendingRequest *pending_req)
1053{
1054 struct RPSPeer *rps_peer;
1055
1056 rps_peer = pending_req->rps_peer;
1057 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_req_head,
1058 rps_peer->pending_req_tail,
1059 pending_req);
1060 rps_peer->num_pending_reqs--;
1061 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1062 "Cancelling pending rps get request\n");
1063 GNUNET_SCHEDULER_cancel (pending_req->request_task);
1064 GNUNET_free (pending_req);
1065}
1066
1067
1068static void
1069cancel_request (struct PendingReply *pending_rep)
1070{
1071 struct RPSPeer *rps_peer;
1072
1073 rps_peer = pending_rep->rps_peer;
1074 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_rep_head,
1075 rps_peer->pending_rep_tail,
1076 pending_rep);
1077 rps_peer->num_pending_reps--;
1078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1079 "Cancelling rps get reply\n");
1080 GNUNET_assert (NULL != pending_rep->req_handle);
1081 GNUNET_RPS_request_single_info_cancel (pending_rep->req_handle);
1082 pending_rep->req_handle = NULL;
1083 GNUNET_free (pending_rep);
1084 pending_rep = NULL;
1085}
1086
1087
1088void
1089clean_peer (unsigned peer_index)
1090{
1091 struct PendingRequest *pending_req;
1092
1093 while (NULL != (pending_req = rps_peers[peer_index].pending_req_head))
1094 {
1095 cancel_pending_req (pending_req);
1096 }
1097 pending_req = rps_peers[peer_index].pending_req_head;
1098 rps_disconnect_adapter (&rps_peers[peer_index],
1099 &rps_peers[peer_index].rps_handle);
1100 for (unsigned stat_type = STAT_TYPE_ROUNDS;
1101 stat_type < STAT_TYPE_MAX;
1102 stat_type++)
1103 {
1104 if (NULL != rps_peers[peer_index].h_stat_get[stat_type])
1105 {
1106 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1107 "(%u) did not yet receive stat value for `%s'\n",
1108 rps_peers[peer_index].index,
1109 stat_type_strings[stat_type]);
1110 GNUNET_STATISTICS_get_cancel (
1111 rps_peers[peer_index].h_stat_get[stat_type]);
1112 }
1113 }
1114 if (NULL != rps_peers[peer_index].op)
1115 {
1116 GNUNET_TESTBED_operation_done (rps_peers[peer_index].op);
1117 rps_peers[peer_index].op = NULL;
1118 }
1119}
1120
1121
1122/**
1123 * Task run on timeout to shut everything down.
1124 */
1125static void
1126shutdown_op (void *cls)
1127{
1128 unsigned int i;
1129 struct OpListEntry *entry;
1130
1131 (void) cls;
1132
1133 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1134 "Shutdown task scheduled, going down.\n");
1135 in_shutdown = GNUNET_YES;
1136
1137 if (NULL != shutdown_task)
1138 {
1139 GNUNET_SCHEDULER_cancel (shutdown_task);
1140 shutdown_task = NULL;
1141 }
1142 if (NULL != post_test_task)
1143 {
1144 GNUNET_SCHEDULER_cancel (post_test_task);
1145 post_test_task = NULL;
1146 }
1147 if (NULL != churn_task)
1148 {
1149 GNUNET_SCHEDULER_cancel (churn_task);
1150 churn_task = NULL;
1151 }
1152 entry = oplist_head;
1153 while (NULL != (entry = oplist_head))
1154 {
1155 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1156 "Operation still pending on shutdown (%u)\n",
1157 entry->index);
1158 GNUNET_TESTBED_operation_done (entry->op);
1159 GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1160 GNUNET_free (entry);
1161 }
1162 for (i = 0; i < num_peers; i++)
1163 {
1164 clean_peer (i);
1165 }
1166 close_all_files ();
1167}
1168
1169
1170static void
1171trigger_shutdown (void *cls)
1172{
1173 (void) cls;
1174
1175 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1176 "Shutdown was triggered by timeout, going down.\n");
1177 shutdown_task = NULL;
1178 GNUNET_SCHEDULER_shutdown ();
1179}
1180
1181
1182/**
1183 * Task run after #duration to collect statistics and potentially shut down.
1184 */
1185static void
1186post_test_op (void *cls)
1187{
1188 unsigned int i;
1189
1190 (void) cls;
1191
1192 post_test_task = NULL;
1193 post_test = GNUNET_YES;
1194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1195 "Executing post test op.\n");
1196 if (NULL != churn_task)
1197 {
1198 GNUNET_SCHEDULER_cancel (churn_task);
1199 churn_task = NULL;
1200 }
1201 for (i = 0; i < num_peers; i++)
1202 {
1203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1204 "Executing post test op. (peer %" PRIu32 ")\n",
1205 rps_peers[i].index);
1206 if (NULL != rps_peers[i].op)
1207 {
1208 GNUNET_TESTBED_operation_done (rps_peers[i].op);
1209 rps_peers[i].op = NULL;
1210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1211 "Cancelled testbed operation\n");
1212 }
1213 if (NULL != cur_test_run.post_test)
1214 {
1215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing post_test for peer %u\n",
1216 i);
1217 cur_test_run.post_test (&rps_peers[i]);
1218 }
1219 }
1220 /* If we do not collect statistics, shut down directly */
1221 if ((NO_COLLECT_STATISTICS == cur_test_run.have_collect_statistics) ||
1222 (GNUNET_YES == check_statistics_collect_completed ()) )
1223 {
1224 GNUNET_SCHEDULER_cancel (shutdown_task);
1225 shutdown_task = NULL;
1226 GNUNET_SCHEDULER_shutdown ();
1227 }
1228}
1229
1230
1231/**
1232 * Get the id of peer i.
1233 */
1234void
1235info_cb (void *cb_cls,
1236 struct GNUNET_TESTBED_Operation *op,
1237 const struct GNUNET_TESTBED_PeerInformation *pinfo,
1238 const char *emsg)
1239{
1240 struct OpListEntry *entry = (struct OpListEntry *) cb_cls;
1241
1242 (void) op;
1243
1244 if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1245 {
1246 return;
1247 }
1248
1249 if ((NULL == pinfo) || (NULL != emsg))
1250 {
1251 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got Error: %s\n", emsg);
1252 GNUNET_TESTBED_operation_done (entry->op);
1253 return;
1254 }
1255
1256 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1257 "Peer %u is %s\n",
1258 entry->index,
1259 GNUNET_i2s (pinfo->result.id));
1260
1261 rps_peer_ids[entry->index] = *(pinfo->result.id);
1262 rps_peers[entry->index].peer_id = &rps_peer_ids[entry->index];
1263
1264 GNUNET_assert (GNUNET_OK ==
1265 GNUNET_CONTAINER_multipeermap_put (peer_map,
1266 &rps_peer_ids[entry->index],
1267 &rps_peers[entry->index],
1268 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1269 tofile ("/tmp/rps/peer_ids",
1270 "%u\t%s\n",
1271 entry->index,
1272 GNUNET_i2s_full (&rps_peer_ids[entry->index]));
1273
1274 GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1275 GNUNET_TESTBED_operation_done (entry->op);
1276 GNUNET_free (entry);
1277}
1278
1279
1280/**
1281 * Callback to be called when RPS service connect operation is completed
1282 *
1283 * @param cls the callback closure from functions generating an operation
1284 * @param op the operation that has been finished
1285 * @param ca_result the RPS service handle returned from rps_connect_adapter
1286 * @param emsg error message in case the operation has failed; will be NULL if
1287 * operation has executed successfully.
1288 */
1289static void
1290rps_connect_complete_cb (void *cls,
1291 struct GNUNET_TESTBED_Operation *op,
1292 void *ca_result,
1293 const char *emsg)
1294{
1295 struct RPSPeer *rps_peer = cls;
1296 struct GNUNET_RPS_Handle *rps = ca_result;
1297
1298 if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1299 {
1300 return;
1301 }
1302
1303 rps_peer->rps_handle = rps;
1304 rps_peer->online = GNUNET_YES;
1305 num_peers_online++;
1306
1307 GNUNET_assert (op == rps_peer->op);
1308 if (NULL != emsg)
1309 {
1310 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1311 "Failed to connect to RPS service: %s\n",
1312 emsg);
1313 ok = 1;
1314 GNUNET_SCHEDULER_shutdown ();
1315 return;
1316 }
1317
1318 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1319 "Started client successfully (%u)\n",
1320 rps_peer->index);
1321
1322 cur_test_run.main_test (rps_peer);
1323}
1324
1325
1326/**
1327 * Adapter function called to establish a connection to
1328 * the RPS service.
1329 *
1330 * @param cls closure
1331 * @param cfg configuration of the peer to connect to; will be available until
1332 * GNUNET_TESTBED_operation_done() is called on the operation returned
1333 * from GNUNET_TESTBED_service_connect()
1334 * @return service handle to return in 'op_result', NULL on error
1335 */
1336static void *
1337rps_connect_adapter (void *cls,
1338 const struct GNUNET_CONFIGURATION_Handle *cfg)
1339{
1340 struct GNUNET_RPS_Handle *h;
1341
1342 h = GNUNET_RPS_connect (cfg);
1343
1344 if (NULL != cur_test_run.pre_test)
1345 cur_test_run.pre_test (cls, h);
1346
1347 return h;
1348}
1349
1350
1351/**
1352 * Called to open a connection to the peer's statistics
1353 *
1354 * @param cls peer context
1355 * @param cfg configuration of the peer to connect to; will be available until
1356 * GNUNET_TESTBED_operation_done() is called on the operation returned
1357 * from GNUNET_TESTBED_service_connect()
1358 * @return service handle to return in 'op_result', NULL on error
1359 */
1360static void *
1361stat_connect_adapter (void *cls,
1362 const struct GNUNET_CONFIGURATION_Handle *cfg)
1363{
1364 struct RPSPeer *peer = cls;
1365
1366 peer->stats_h = GNUNET_STATISTICS_create ("rps-profiler", cfg);
1367 return peer->stats_h;
1368}
1369
1370
1371/**
1372 * Called to disconnect from peer's statistics service
1373 *
1374 * @param cls peer context
1375 * @param op_result service handle returned from the connect adapter
1376 */
1377static void
1378stat_disconnect_adapter (void *cls, void *op_result)
1379{
1380 struct RPSPeer *peer = cls;
1381
1382 // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1383 // (peer->stats_h, "core", "# peers connected",
1384 // stat_iterator, peer));
1385 // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch_cancel
1386 // (peer->stats_h, "nse", "# peers connected",
1387 // stat_iterator, peer));
1388 GNUNET_STATISTICS_destroy (op_result, GNUNET_NO);
1389 peer->stats_h = NULL;
1390}
1391
1392
1393/**
1394 * Called after successfully opening a connection to a peer's statistics
1395 * service; we register statistics monitoring for CORE and NSE here.
1396 *
1397 * @param cls the callback closure from functions generating an operation
1398 * @param op the operation that has been finished
1399 * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
1400 * @param emsg error message in case the operation has failed; will be NULL if
1401 * operation has executed successfully.
1402 */
1403static void
1404stat_complete_cb (void *cls,
1405 struct GNUNET_TESTBED_Operation *op,
1406 void *ca_result,
1407 const char *emsg)
1408{
1409 // struct GNUNET_STATISTICS_Handle *sh = ca_result;
1410 // struct RPSPeer *peer = (struct RPSPeer *) cls;
1411 (void) cls;
1412 (void) op;
1413 (void) ca_result;
1414
1415 if (NULL != emsg)
1416 {
1417 GNUNET_break (0);
1418 return;
1419 }
1420 // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1421 // (sh, "core", "# peers connected",
1422 // stat_iterator, peer));
1423 // GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch
1424 // (sh, "nse", "# peers connected",
1425 // stat_iterator, peer));
1426}
1427
1428
1429/**
1430 * Adapter function called to destroy connection to
1431 * RPS service.
1432 *
1433 * @param cls closure
1434 * @param op_result service handle returned from the connect adapter
1435 */
1436static void
1437rps_disconnect_adapter (void *cls,
1438 void *op_result)
1439{
1440 struct RPSPeer *peer = cls;
1441 struct GNUNET_RPS_Handle *h = op_result;
1442 struct PendingReply *pending_rep;
1443
1444 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1445 "disconnect_adapter (%u)\n",
1446 peer->index);
1447 GNUNET_assert (NULL != peer);
1448 if (NULL != peer->rps_handle)
1449 {
1450 while (NULL != (pending_rep = peer->pending_rep_head))
1451 {
1452 cancel_request (pending_rep);
1453 }
1454 GNUNET_assert (h == peer->rps_handle);
1455 if (NULL != h)
1456 {
1457 GNUNET_RPS_disconnect (h);
1458 h = NULL;
1459 }
1460 peer->rps_handle = NULL;
1461 }
1462}
1463
1464
1465/***********************************************************************
1466* Definition of tests
1467***********************************************************************/
1468
1469/**
1470 * Callback to call on receipt of a reply
1471 *
1472 * @param cls closure
1473 * @param n number of peers
1474 * @param recv_peers the received peers
1475 */
1476static void
1477default_reply_handle (void *cls,
1478 uint64_t n,
1479 const struct GNUNET_PeerIdentity *recv_peers)
1480{
1481 struct RPSPeer *rps_peer;
1482 struct PendingReply *pending_rep = (struct PendingReply *) cls;
1483 unsigned int i;
1484
1485 rps_peer = pending_rep->rps_peer;
1486 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_rep_head,
1487 rps_peer->pending_rep_tail,
1488 pending_rep);
1489 rps_peer->num_pending_reps--;
1490 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1491 "[%s] got %" PRIu64 " peers:\n",
1492 GNUNET_i2s (rps_peer->peer_id),
1493 n);
1494
1495 for (i = 0; i < n; i++)
1496 {
1497 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1498 "%u: %s\n",
1499 i,
1500 GNUNET_i2s (&recv_peers[i]));
1501
1502 rps_peer->num_recv_ids++;
1503 }
1504
1505 if (GNUNET_YES != post_test)
1506 return;
1507 if (HAVE_QUICK_QUIT != cur_test_run.have_quick_quit)
1508 return;
1509 if (0 == evaluate ())
1510 {
1511 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1512 "Test succeeded before end of duration\n");
1513 if (NULL != post_test_task)
1514 GNUNET_SCHEDULER_cancel (post_test_task);
1515 post_test_task = GNUNET_SCHEDULER_add_now (&post_test_op, NULL);
1516 GNUNET_assert (NULL != post_test_task);
1517 }
1518}
1519
1520
1521static void
1522profiler_reply_handle_info (void *cls,
1523 const struct GNUNET_PeerIdentity *recv_peer,
1524 double probability,
1525 uint32_t num_observed);
1526
1527/**
1528 * Request random peers.
1529 */
1530static void
1531request_peers (void *cls)
1532{
1533 struct PendingRequest *pending_req = cls;
1534 struct RPSPeer *rps_peer;
1535 struct PendingReply *pending_rep;
1536
1537 rps_peer = pending_req->rps_peer;
1538 GNUNET_assert (1 <= rps_peer->num_pending_reqs);
1539 GNUNET_CONTAINER_DLL_remove (rps_peer->pending_req_head,
1540 rps_peer->pending_req_tail,
1541 pending_req);
1542 rps_peer->num_pending_reqs--;
1543 if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1544 return;
1545 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1546 "Requesting one peer\n");
1547 pending_rep = GNUNET_new (struct PendingReply);
1548 pending_rep->rps_peer = rps_peer;
1549 // pending_rep->req_handle = GNUNET_RPS_request_peers (rps_peer->rps_handle,
1550 // 1,
1551 // cur_test_run.reply_handle,
1552 // pending_rep);
1553 pending_rep->req_handle = GNUNET_RPS_request_peer_info (rps_peer->rps_handle,
1554 profiler_reply_handle_info,
1555 pending_rep);
1556 GNUNET_CONTAINER_DLL_insert_tail (rps_peer->pending_rep_head,
1557 rps_peer->pending_rep_tail,
1558 pending_rep);
1559 rps_peer->num_pending_reps++;
1560}
1561
1562
1563/**
1564 * Schedule requests for peer @a rps_peer that have neither been scheduled, nor
1565 * issued, nor replied
1566 */
1567void
1568schedule_missing_requests (struct RPSPeer *rps_peer)
1569{
1570 unsigned int i;
1571 struct PendingRequest *pending_req;
1572
1573 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1574 "Scheduling %u - %u missing requests\n",
1575 rps_peer->num_ids_to_request,
1576 rps_peer->num_pending_reqs + rps_peer->num_pending_reps);
1577 GNUNET_assert (rps_peer->num_pending_reqs + rps_peer->num_pending_reps <=
1578 rps_peer->num_ids_to_request);
1579 for (i = rps_peer->num_pending_reqs + rps_peer->num_pending_reps;
1580 i < rps_peer->num_ids_to_request; i++)
1581 {
1582 pending_req = GNUNET_new (struct PendingRequest);
1583 pending_req->rps_peer = rps_peer;
1584 pending_req->request_task = GNUNET_SCHEDULER_add_delayed (
1585 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
1586 cur_test_run.request_interval * i),
1587 request_peers,
1588 pending_req);
1589 GNUNET_CONTAINER_DLL_insert_tail (rps_peer->pending_req_head,
1590 rps_peer->pending_req_tail,
1591 pending_req);
1592 rps_peer->num_pending_reqs++;
1593 }
1594}
1595
1596
1597void
1598cancel_pending_req_rep (struct RPSPeer *rps_peer)
1599{
1600 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1601 "Cancelling all (pending) requests.\n");
1602 while (NULL != rps_peer->pending_req_head)
1603 cancel_pending_req (rps_peer->pending_req_head);
1604 GNUNET_assert (0 == rps_peer->num_pending_reqs);
1605 while (NULL != rps_peer->pending_rep_head)
1606 cancel_request (rps_peer->pending_rep_head);
1607 GNUNET_assert (0 == rps_peer->num_pending_reps);
1608}
1609
1610
1611/***********************************
1612* MALICIOUS
1613***********************************/
1614
1615///**
1616// * Initialise only non-mal RPSPeers
1617// */
1618//static void
1619//mal_init_peer (struct RPSPeer *rps_peer)
1620//{
1621// if (rps_peer->index >= round (portion * num_peers))
1622// rps_peer->num_ids_to_request = 1;
1623//}
1624
1625
1626///**
1627// * @brief Set peers to (non-)malicious before execution
1628// *
1629// * Of signature #PreTest
1630// *
1631// * @param rps_peer the peer to set (non-) malicious
1632// * @param h the handle to the service
1633// */
1634//static void
1635//mal_pre (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
1636//{
1637// #if ENABLE_MALICIOUS
1638// uint32_t num_mal_peers;
1639//
1640// GNUNET_assert ((1 >= portion) &&
1641// (0 < portion));
1642// num_mal_peers = round (portion * num_peers);
1643//
1644// if (rps_peer->index < num_mal_peers)
1645// {
1646// GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1647// "%u. peer [%s] of %" PRIu32
1648// " malicious peers turning malicious\n",
1649// rps_peer->index,
1650// GNUNET_i2s (rps_peer->peer_id),
1651// num_mal_peers);
1652//
1653// GNUNET_RPS_act_malicious (h, mal_type, num_mal_peers,
1654// rps_peer_ids, target_peer);
1655// }
1656// #endif /* ENABLE_MALICIOUS */
1657//}
1658
1659
1660// static void
1661// mal_cb (struct RPSPeer *rps_peer)
1662// {
1663// if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1664// {
1665// return;
1666// }
1667//
1668// #if ENABLE_MALICIOUS
1669// uint32_t num_mal_peers;
1670//
1671// GNUNET_assert ((1 >= portion) &&
1672// (0 < portion));
1673// num_mal_peers = round (portion * num_peers);
1674//
1675// if (rps_peer->index >= num_mal_peers)
1676// { /* It's useless to ask a malicious peer about a random sample -
1677// it's not sampling */
1678// GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (
1679// GNUNET_TIME_UNIT_SECONDS, 2),
1680// seed_peers, rps_peer);
1681// schedule_missing_requests (rps_peer);
1682// }
1683// #endif /* ENABLE_MALICIOUS */
1684// }
1685
1686
1687/***********************************
1688* CHURN
1689***********************************/
1690
1691static void
1692churn (void *cls);
1693
1694
1695/***********************************
1696* PROFILER
1697***********************************/
1698
1699/**
1700 * Callback to be called when RPS service is started or stopped at peers
1701 *
1702 * @param cls NULL
1703 * @param op the operation handle
1704 * @param emsg NULL on success; otherwise an error description
1705 */
1706static void
1707churn_cb (void *cls,
1708 struct GNUNET_TESTBED_Operation *op,
1709 const char *emsg)
1710{
1711 // FIXME
1712 struct OpListEntry *entry = cls;
1713
1714 (void) op;
1715
1716 if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1717 {
1718 return;
1719 }
1720
1721 GNUNET_TESTBED_operation_done (entry->op);
1722 if (NULL != emsg)
1723 {
1724 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1725 "Failed to start/stop RPS at a peer\n");
1726 GNUNET_SCHEDULER_shutdown ();
1727 return;
1728 }
1729 GNUNET_assert (0 != entry->delta);
1730
1731 num_peers_online += entry->delta;
1732
1733 if (PEER_GO_OFFLINE == entry->delta)
1734 { /* Peer hopefully just went offline */
1735 if (GNUNET_YES != rps_peers[entry->index].online)
1736 {
1737 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1738 "peer %s was expected to go offline but is still marked as online\n",
1739 GNUNET_i2s (rps_peers[entry->index].peer_id));
1740 GNUNET_break (0);
1741 }
1742 else
1743 {
1744 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1745 "peer %s probably went offline as expected\n",
1746 GNUNET_i2s (rps_peers[entry->index].peer_id));
1747 }
1748 rps_peers[entry->index].online = GNUNET_NO;
1749 }
1750
1751 else if (PEER_GO_ONLINE < entry->delta)
1752 { /* Peer hopefully just went online */
1753 if (GNUNET_NO != rps_peers[entry->index].online)
1754 {
1755 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1756 "peer %s was expected to go online but is still marked as offline\n",
1757 GNUNET_i2s (rps_peers[entry->index].peer_id));
1758 GNUNET_break (0);
1759 }
1760 else
1761 {
1762 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1763 "peer %s probably went online as expected\n",
1764 GNUNET_i2s (rps_peers[entry->index].peer_id));
1765 if (NULL != cur_test_run.pre_test)
1766 {
1767 cur_test_run.pre_test (&rps_peers[entry->index],
1768 rps_peers[entry->index].rps_handle);
1769 schedule_missing_requests (&rps_peers[entry->index]);
1770 }
1771 }
1772 rps_peers[entry->index].online = GNUNET_YES;
1773 }
1774 else
1775 {
1776 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1777 "Invalid value for delta: %i\n", entry->delta);
1778 GNUNET_break (0);
1779 }
1780
1781 GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
1782 rps_peers[entry->index].entry_op_manage = NULL;
1783 GNUNET_free (entry);
1784 // if (num_peers_in_round[current_round] == peers_running)
1785 // run_round ();
1786}
1787
1788
1789/**
1790 * @brief Set the rps-service up or down for a specific peer
1791 *
1792 * @param i index of action
1793 * @param j index of peer
1794 * @param delta (#PEER_ONLINE_DELTA) down (-1) or up (1)
1795 * @param prob_go_on_off the probability of the action
1796 */
1797static void
1798manage_service_wrapper (unsigned int i, unsigned int j,
1799 enum PEER_ONLINE_DELTA delta,
1800 double prob_go_on_off)
1801{
1802 struct OpListEntry *entry = NULL;
1803 uint32_t prob;
1804
1805 /* make sure that management operation is not already scheduled */
1806 if (NULL != rps_peers[j].entry_op_manage)
1807 {
1808 return;
1809 }
1810
1811 prob = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1812 UINT32_MAX);
1813 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1814 "%u. selected peer (%u: %s) is %s.\n",
1815 i,
1816 j,
1817 GNUNET_i2s (rps_peers[j].peer_id),
1818 (PEER_GO_ONLINE == delta) ? "online" : "offline");
1819 if (prob < prob_go_on_off * UINT32_MAX)
1820 {
1821 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1822 "%s goes %s\n",
1823 GNUNET_i2s (rps_peers[j].peer_id),
1824 (PEER_GO_OFFLINE == delta) ? "offline" : "online");
1825
1826 if (PEER_GO_OFFLINE == delta)
1827 cancel_pending_req_rep (&rps_peers[j]);
1828 entry = make_oplist_entry ();
1829 entry->delta = delta;
1830 entry->index = j;
1831 entry->op = GNUNET_TESTBED_peer_manage_service (NULL,
1832 testbed_peers[j],
1833 "rps",
1834 &churn_cb,
1835 entry,
1836 (PEER_GO_OFFLINE == delta) ?
1837 0 : 1);
1838 rps_peers[j].entry_op_manage = entry;
1839 }
1840}
1841
1842
1843static void
1844churn (void *cls)
1845{
1846 unsigned int i;
1847 unsigned int j;
1848 double portion_online;
1849 unsigned int *permut;
1850 double prob_go_offline;
1851 double portion_go_online;
1852 double portion_go_offline;
1853
1854 (void) cls;
1855
1856 if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
1857 {
1858 return;
1859 }
1860 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1861 "Churn function executing\n");
1862
1863 churn_task = NULL; /* Should be invalid by now */
1864
1865 /* Compute the probability for an online peer to go offline
1866 * this round */
1867 portion_online = num_peers_online * 1.0 / num_peers;
1868 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1869 "Portion online: %f\n",
1870 portion_online);
1871 portion_go_online = ((1 - portion_online) * .5 * .66);
1872 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1873 "Portion that should go online: %f\n",
1874 portion_go_online);
1875 portion_go_offline = (portion_online + portion_go_online) - .75;
1876 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1877 "Portion that probably goes offline: %f\n",
1878 portion_go_offline);
1879 prob_go_offline = portion_go_offline / (portion_online * .5);
1880 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1881 "Probability of a selected online peer to go offline: %f\n",
1882 prob_go_offline);
1883
1884 permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK,
1885 (unsigned int) num_peers);
1886
1887 /* Go over 50% randomly chosen peers */
1888 for (i = 0; i < .5 * num_peers; i++)
1889 {
1890 j = permut[i];
1891
1892 /* If online, shut down with certain probability */
1893 if (GNUNET_YES == rps_peers[j].online)
1894 {
1895 manage_service_wrapper (i, j, -1, prob_go_offline);
1896 }
1897
1898 /* If offline, restart with certain probability */
1899 else if (GNUNET_NO == rps_peers[j].online)
1900 {
1901 manage_service_wrapper (i, j, 1, 0.66);
1902 }
1903 }
1904
1905 GNUNET_free (permut);
1906
1907 churn_task = GNUNET_SCHEDULER_add_delayed (
1908 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2),
1909 churn,
1910 NULL);
1911}
1912
1913
1914/**
1915 * Initialise given RPSPeer
1916 */
1917static void
1918profiler_init_peer (struct RPSPeer *rps_peer)
1919{
1920 rps_peer->num_ids_to_request = cur_test_run.num_requests;
1921 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer shall request %i peers\n",
1922 rps_peer->num_ids_to_request);
1923}
1924
1925
1926/**
1927 * Callback to call on receipt of a reply
1928 *
1929 * @param cls closure
1930 * @param n number of peers
1931 * @param recv_peers the received peers
1932 */
1933static void
1934profiler_reply_handle (void *cls,
1935 uint64_t n,
1936 const struct GNUNET_PeerIdentity *recv_peers)
1937{
1938 struct RPSPeer *rps_peer;
1939 struct RPSPeer *rcv_rps_peer;
1940 char file_name_buf[128];
1941 char file_name_dh_buf[128];
1942 char file_name_dhr_buf[128];
1943 char file_name_dhru_buf[128];
1944 char *file_name = file_name_buf;
1945 char *file_name_dh = file_name_dh_buf;
1946 char *file_name_dhr = file_name_dhr_buf;
1947 char *file_name_dhru = file_name_dhru_buf;
1948 unsigned int i;
1949 struct PendingReply *pending_rep = (struct PendingReply *) cls;
1950
1951 pending_rep->req_handle = NULL;
1952 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
1953 rps_peer = pending_rep->rps_peer;
1954 (void) GNUNET_asprintf (&file_name,
1955 "/tmp/rps/received_ids-%u",
1956 rps_peer->index);
1957
1958 (void) GNUNET_asprintf (&file_name_dh,
1959 "/tmp/rps/diehard_input-%u",
1960 rps_peer->index);
1961 (void) GNUNET_asprintf (&file_name_dhr,
1962 "/tmp/rps/diehard_input_raw-%u",
1963 rps_peer->index);
1964 (void) GNUNET_asprintf (&file_name_dhru,
1965 "/tmp/rps/diehard_input_raw_aligned-%u",
1966 rps_peer->index);
1967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1968 "[%s] got %" PRIu64 " peers:\n",
1969 GNUNET_i2s (rps_peer->peer_id),
1970 n);
1971 for (i = 0; i < n; i++)
1972 {
1973 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1974 "%u: %s\n",
1975 i,
1976 GNUNET_i2s (&recv_peers[i]));
1977 tofile (file_name,
1978 "%s\n",
1979 GNUNET_i2s_full (&recv_peers[i]));
1980 rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get (peer_map, &recv_peers[i]);
1981 GNUNET_assert (NULL != rcv_rps_peer);
1982 tofile (file_name_dh,
1983 "%" PRIu32 "\n",
1984 (uint32_t) rcv_rps_peer->index);
1985#ifdef TO_FILE
1986 to_file_raw (file_name_dhr,
1987 (char *) &rcv_rps_peer->index,
1988 sizeof(uint32_t));
1989 to_file_raw_unaligned (file_name_dhru,
1990 (char *) &rcv_rps_peer->index,
1991 sizeof(uint32_t),
1992 bits_needed);
1993#endif /* TO_FILE */
1994 }
1995 default_reply_handle (cls, n, recv_peers);
1996}
1997
1998
1999/**
2000 * Callback to call on receipt of a reply
2001 *
2002 * @param cls closure
2003 * @param n number of peers
2004 * @param recv_peers the received peers
2005 */
2006static void
2007profiler_reply_handle_info (void *cls,
2008 const struct GNUNET_PeerIdentity *recv_peer,
2009 double probability,
2010 uint32_t num_observed)
2011{
2012 struct RPSPeer *rps_peer;
2013 struct RPSPeer *rcv_rps_peer;
2014 char file_name_buf[128];
2015 char file_name_dh_buf[128];
2016 char file_name_dhr_buf[128];
2017 char file_name_dhru_buf[128];
2018 char *file_name = file_name_buf;
2019 char *file_name_dh = file_name_dh_buf;
2020 char *file_name_dhr = file_name_dhr_buf;
2021 char *file_name_dhru = file_name_dhru_buf;
2022 struct PendingReply *pending_rep = (struct PendingReply *) cls;
2023
2024 pending_rep->req_handle = NULL;
2025 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "profiler_reply_handle()\n");
2026 rps_peer = pending_rep->rps_peer;
2027 (void) GNUNET_asprintf (&file_name,
2028 "/tmp/rps/received_ids-%u",
2029 rps_peer->index);
2030
2031 (void) GNUNET_asprintf (&file_name_dh,
2032 "/tmp/rps/diehard_input-%u",
2033 rps_peer->index);
2034 (void) GNUNET_asprintf (&file_name_dhr,
2035 "/tmp/rps/diehard_input_raw-%u",
2036 rps_peer->index);
2037 (void) GNUNET_asprintf (&file_name_dhru,
2038 "/tmp/rps/diehard_input_raw_aligned-%u",
2039 rps_peer->index);
2040 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2041 "[%s] got peer with info:\n",
2042 GNUNET_i2s (rps_peer->peer_id));
2043 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2044 " %s\n",
2045 GNUNET_i2s (recv_peer));
2046 tofile (file_name,
2047 "%s %f %" PRIu32 " \n",
2048 GNUNET_i2s_full (recv_peer),
2049 probability,
2050 num_observed);
2051 rcv_rps_peer = GNUNET_CONTAINER_multipeermap_get (peer_map, recv_peer);
2052 GNUNET_assert (NULL != rcv_rps_peer);
2053 tofile (file_name_dh,
2054 "%" PRIu32 "\n",
2055 (uint32_t) rcv_rps_peer->index);
2056#ifdef TO_FILE
2057 to_file_raw (file_name_dhr,
2058 (char *) &rcv_rps_peer->index,
2059 sizeof(uint32_t));
2060 to_file_raw_unaligned (file_name_dhru,
2061 (char *) &rcv_rps_peer->index,
2062 sizeof(uint32_t),
2063 bits_needed);
2064#endif /* TO_FILE */
2065 default_reply_handle (cls, 1, recv_peer);
2066}
2067
2068
2069static void
2070profiler_cb (struct RPSPeer *rps_peer)
2071{
2072 if ((GNUNET_YES == in_shutdown) || (GNUNET_YES == post_test))
2073 {
2074 return;
2075 }
2076
2077 /* Start churn */
2078 if ((HAVE_CHURN == cur_test_run.have_churn) && (NULL == churn_task))
2079 {
2080 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2081 "Starting churn task\n");
2082 churn_task = GNUNET_SCHEDULER_add_delayed (
2083 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
2084 churn,
2085 NULL);
2086 }
2087 else
2088 {
2089 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2090 "Not starting churn task\n");
2091 }
2092
2093 /* Only request peer ids at one peer.
2094 * (It's the before-last because last one is target of the focused attack.)
2095 */
2096 if (0 < rps_peer->num_ids_to_request)
2097 schedule_missing_requests (rps_peer);
2098}
2099
2100
2101/**
2102 * Function called from #profiler_eval with a filename.
2103 *
2104 * @param cls closure
2105 * @param filename complete filename (absolute path)
2106 * @return #GNUNET_OK to continue to iterate,
2107 * #GNUNET_NO to stop iteration with no error,
2108 * #GNUNET_SYSERR to abort iteration with error!
2109 */
2110static int
2111file_name_cb (void *cls, const char *filename)
2112{
2113 if (NULL != strstr (filename, "sampler_el"))
2114 {
2115 struct RPS_SamplerElement *s_elem;
2116 struct GNUNET_CRYPTO_AuthKey auth_key;
2117 const char *key_char;
2118 uint32_t i;
2119 (void) cls;
2120
2121 key_char = filename + 20; /* Length of "/tmp/rps/sampler_el-" */
2122 tofile (filename, "--------------------------\n");
2123
2124 auth_key = string_to_auth_key (key_char);
2125 s_elem = RPS_sampler_elem_create ();
2126 RPS_sampler_elem_set (s_elem, auth_key);
2127
2128 for (i = 0; i < num_peers; i++)
2129 {
2130 RPS_sampler_elem_next (s_elem, &rps_peer_ids[i]);
2131 }
2132 RPS_sampler_elem_destroy (s_elem);
2133 }
2134 return GNUNET_OK;
2135}
2136
2137
2138/**
2139 * This is run after the test finished.
2140 *
2141 * Compute all perfect samples.
2142 */
2143static int
2144profiler_eval (void)
2145{
2146#ifdef TO_FILE
2147 /* Compute perfect sample for each sampler element */
2148 if (-1 == GNUNET_DISK_directory_scan ("/tmp/rps/", file_name_cb, NULL))
2149 {
2150 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Scan of directory failed\n");
2151 }
2152#endif /* TO_FILE */
2153
2154 return evaluate ();
2155}
2156
2157
2158/** @brief is b in view of a?
2159 *
2160 * @param a
2161 * @param b
2162 *
2163 * @return
2164 */
2165static int
2166is_in_view (uint32_t a, uint32_t b)
2167{
2168 uint32_t i;
2169
2170 for (i = 0; i < rps_peers[a].cur_view_count; i++)
2171 {
2172 if (0 == memcmp (rps_peers[b].peer_id,
2173 &rps_peers[a].cur_view[i],
2174 sizeof(struct GNUNET_PeerIdentity)))
2175 {
2176 return GNUNET_YES;
2177 }
2178 }
2179 return GNUNET_NO;
2180}
2181
2182
2183static uint32_t
2184get_idx_of_pid (const struct GNUNET_PeerIdentity *pid)
2185{
2186 uint32_t i;
2187
2188 for (i = 0; i < num_peers; i++)
2189 {
2190 if (0 == memcmp (pid,
2191 rps_peers[i].peer_id,
2192 sizeof(struct GNUNET_PeerIdentity)))
2193 {
2194 return i;
2195 }
2196 }
2197 // return 0; /* Should not happen - make compiler happy */
2198 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2199 "No known _PeerIdentity %s!\n",
2200 GNUNET_i2s_full (pid));
2201 GNUNET_assert (0);
2202}
2203
2204
2205/**
2206 * @brief Counts number of peers in view of a that have b in their view
2207 *
2208 * @param a
2209 * @param b
2210 *
2211 * @return
2212 */
2213static uint32_t
2214count_containing_views (uint32_t a, uint32_t b)
2215{
2216 uint32_t i;
2217 uint32_t peer_idx;
2218 uint32_t count = 0;
2219
2220 for (i = 0; i < rps_peers[a].cur_view_count; i++)
2221 {
2222 peer_idx = get_idx_of_pid (&rps_peers[a].cur_view[i]);
2223 if (GNUNET_YES == is_in_view (peer_idx, b))
2224 {
2225 count++;
2226 }
2227 }
2228 return count;
2229}
2230
2231
2232/**
2233 * @brief Computes the probability for each other peer to be selected by the
2234 * sampling process based on the views of all peers
2235 *
2236 * @param peer_idx index of the peer that is about to sample
2237 */
2238static void
2239compute_probabilities (uint32_t peer_idx)
2240{
2241 // double probs[num_peers] = { 0 };
2242 double probs[num_peers];
2243 double probs_hist[num_peers]; /* Probability respecting the history */
2244 size_t probs_as_str_size = (num_peers * 10 + 2) * sizeof(char);
2245 char *probs_as_str = GNUNET_malloc (probs_as_str_size);
2246 char *probs_as_str_cpy;
2247 uint32_t i;
2248 double prob_push;
2249 double prob_pull;
2250 uint32_t view_size;
2251 uint32_t cont_views;
2252 uint32_t number_of_being_in_pull_events;
2253 int tmp;
2254 double sum_non_zero_prob = 0;
2255 double sum_non_zero_prob_hist = 0;
2256
2257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2258 "Computing probabilities for peer %" PRIu32 "\n", peer_idx);
2259 /* Firstly without knowledge of old views */
2260 for (i = 0; i < num_peers; i++)
2261 {
2262 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2263 "\tfor peer %" PRIu32 ":\n", i);
2264 view_size = rps_peers[i].cur_view_count;
2265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2266 "\t\tview_size: %" PRIu32 "\n", view_size);
2267 /* For peer i the probability of being sampled is
2268 * evenly distributed among all possibly observed peers. */
2269 /* We could have observed a peer in three cases:
2270 * 1. peer sent a push
2271 * 2. peer was contained in a pull reply
2272 * 3. peer was in history (sampler) - ignored for now */
2273 /* 1. Probability of having received a push from peer i */
2274 if ((GNUNET_YES == is_in_view (i, peer_idx)) &&
2275 (1 <= (0.45 * view_size)))
2276 {
2277 if (0 == binom (view_size, 0.45 * view_size))
2278 prob_push = 0;
2279 else
2280 {
2281 prob_push = 1.0 * binom (0.45 * view_size, 1)
2282 /
2283 binom (view_size, 0.45 * view_size);
2284 }
2285 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2286 "\t\t%" PRIu32 " is in %" PRIu32 "'s view, prob: %f\n",
2287 peer_idx,
2288 i,
2289 prob_push);
2290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2291 "\t\tposs choices from view: %" PRIu32 ", containing i: %"
2292 PRIu32 "\n",
2293 binom (view_size, 0.45 * view_size),
2294 binom (0.45 * view_size, 1));
2295 }
2296 else
2297 {
2298 prob_push = 0;
2299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2300 "\t\t%" PRIu32 " is not in %" PRIu32 "'s view, prob: 0\n",
2301 peer_idx,
2302 i);
2303 }
2304 /* 2. Probability of peer i being contained in pulls */
2305 view_size = rps_peers[peer_idx].cur_view_count;
2306 cont_views = count_containing_views (peer_idx, i);
2307 number_of_being_in_pull_events =
2308 (binom (view_size, 0.45 * view_size)
2309 - binom (view_size - cont_views, 0.45 * view_size));
2310 if (0 != number_of_being_in_pull_events)
2311 {
2312 prob_pull = number_of_being_in_pull_events
2313 /
2314 (1.0 * binom (view_size, 0.45 * view_size));
2315 }
2316 else
2317 {
2318 prob_pull = 0;
2319 }
2320 probs[i] = prob_push + prob_pull - (prob_push * prob_pull);
2321 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2322 "\t\t%" PRIu32 " has %" PRIu32 " of %" PRIu32
2323 " peers in its view who know %" PRIu32 " prob: %f\n",
2324 peer_idx,
2325 cont_views,
2326 view_size,
2327 i,
2328 prob_pull);
2329 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2330 "\t\tnumber of possible pull combinations: %" PRIu32 "\n",
2331 binom (view_size, 0.45 * view_size));
2332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2333 "\t\tnumber of possible pull combinations without %" PRIu32
2334 ": %" PRIu32 "\n",
2335 i,
2336 binom (view_size - cont_views, 0.45 * view_size));
2337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2338 "\t\tnumber of possible pull combinations with %" PRIu32
2339 ": %" PRIu32 "\n",
2340 i,
2341 number_of_being_in_pull_events);
2342
2343 probs_hist[i] = 0.9 * rps_peers[peer_idx].eval_probs_cache[i] + probs[i];
2344 rps_peers[peer_idx].eval_probs_cache[i] = probs_hist[i];
2345
2346 sum_non_zero_prob += probs[i];
2347 sum_non_zero_prob_hist += probs_hist[i];
2348 }
2349 /* normalize */
2350 if (0 != sum_non_zero_prob)
2351 {
2352 for (i = 0; i < num_peers; i++)
2353 {
2354 probs[i] = probs[i] * (1.0 / sum_non_zero_prob);
2355 }
2356 }
2357 if (0 != sum_non_zero_prob_hist)
2358 {
2359 for (i = 0; i < num_peers; i++)
2360 {
2361 probs_hist[i] = probs_hist[i] * (1.0 / sum_non_zero_prob_hist);
2362 }
2363 }
2364
2365 /* str repr */
2366 for (i = 0; i < num_peers; i++)
2367 {
2368 probs_as_str_cpy = GNUNET_strndup (probs_as_str, probs_as_str_size);
2369 tmp = GNUNET_snprintf (probs_as_str,
2370 probs_as_str_size,
2371 "%s %7.6f", probs_as_str_cpy, probs[i]);
2372 GNUNET_free (probs_as_str_cpy);
2373 GNUNET_assert (0 <= tmp);
2374 }
2375
2376 to_file_w_len (rps_peers[peer_idx].file_name_probs,
2377 probs_as_str_size,
2378 "%s",
2379 probs_as_str);
2380
2381 probs_as_str[0] = '\0';
2382 for (i = 0; i < num_peers; i++)
2383 {
2384 probs_as_str_cpy = GNUNET_strndup (probs_as_str, probs_as_str_size);
2385 tmp = GNUNET_snprintf (probs_as_str,
2386 probs_as_str_size,
2387 "%s %7.6f", probs_as_str_cpy, probs_hist[i]);
2388 GNUNET_free (probs_as_str_cpy);
2389 GNUNET_assert (0 <= tmp);
2390 }
2391
2392 to_file_w_len (rps_peers[peer_idx].file_name_probs_hist,
2393 probs_as_str_size,
2394 "%s",
2395 probs_as_str);
2396 GNUNET_free (probs_as_str);
2397}
2398
2399
2400/**
2401 * @brief This counts the number of peers in which views a given peer occurs.
2402 *
2403 * It also stores this value in the rps peer.
2404 *
2405 * @param peer_idx the index of the peer to count the representation
2406 *
2407 * @return the number of occurrences
2408 */
2409static uint32_t
2410count_peer_in_views_2 (uint32_t peer_idx)
2411{
2412 uint32_t i, j;
2413 uint32_t count = 0;
2414
2415 for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2416 {
2417 for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2418 {
2419 if (0 == memcmp (rps_peers[peer_idx].peer_id,
2420 &rps_peers[i].cur_view[j],
2421 sizeof(struct GNUNET_PeerIdentity)))
2422 {
2423 count++;
2424 break;
2425 }
2426 }
2427 }
2428 rps_peers[peer_idx].count_in_views = count;
2429 return count;
2430}
2431
2432
2433static uint32_t
2434cumulated_view_sizes ()
2435{
2436 uint32_t i;
2437
2438 view_sizes = 0;
2439 for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2440 {
2441 view_sizes += rps_peers[i].cur_view_count;
2442 }
2443 return view_sizes;
2444}
2445
2446
2447static void
2448count_peer_in_views (uint32_t *count_peers)
2449{
2450 uint32_t i, j;
2451
2452 for (i = 0; i < num_peers; i++) /* Peer in which view is counted */
2453 {
2454 for (j = 0; j < rps_peers[i].cur_view_count; j++) /* entry in view */
2455 {
2456 if (0 == memcmp (rps_peers[i].peer_id,
2457 &rps_peers[i].cur_view[j],
2458 sizeof(struct GNUNET_PeerIdentity)))
2459 {
2460 count_peers[i]++;
2461 }
2462 }
2463 }
2464}
2465
2466
2467void
2468compute_diversity ()
2469{
2470 uint32_t i;
2471 /* ith entry represents the number of occurrences in other peer's views */
2472 uint32_t *count_peers = GNUNET_new_array (num_peers, uint32_t);
2473 uint32_t views_total_size;
2474 double expected;
2475 /* deviation from expected number of peers */
2476 double *deviation = GNUNET_new_array (num_peers, double);
2477
2478 views_total_size = 0;
2479 expected = 0;
2480
2481 /* For each peer count its representation in other peer's views*/
2482 for (i = 0; i < num_peers; i++) /* Peer to count */
2483 {
2484 views_total_size += rps_peers[i].cur_view_count;
2485 count_peer_in_views (count_peers);
2486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2487 "Counted representation of %" PRIu32 "th peer [%s]: %" PRIu32
2488 "\n",
2489 i,
2490 GNUNET_i2s (rps_peers[i].peer_id),
2491 count_peers[i]);
2492 }
2493
2494 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2495 "size of all views combined: %" PRIu32 "\n",
2496 views_total_size);
2497 expected = ((double) 1 / num_peers) * views_total_size;
2498 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2499 "Expected number of occurrences of each peer in all views: %f\n",
2500 expected);
2501 for (i = 0; i < num_peers; i++) /* Peer to count */
2502 {
2503 deviation[i] = expected - count_peers[i];
2504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2505 "Deviation from expectation: %f\n", deviation[i]);
2506 }
2507 GNUNET_free (count_peers);
2508 GNUNET_free (deviation);
2509}
2510
2511
2512void
2513print_view_sizes ()
2514{
2515 uint32_t i;
2516
2517 for (i = 0; i < num_peers; i++) /* Peer to count */
2518 {
2519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2520 "View size of %" PRIu32 ". [%s] is %" PRIu32 "\n",
2521 i,
2522 GNUNET_i2s (rps_peers[i].peer_id),
2523 rps_peers[i].cur_view_count);
2524 }
2525}
2526
2527
2528void
2529all_views_updated_cb ()
2530{
2531 compute_diversity ();
2532 print_view_sizes ();
2533}
2534
2535
2536void
2537view_update_cb (void *cls,
2538 uint64_t view_size,
2539 const struct GNUNET_PeerIdentity *peers)
2540{
2541 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2542 "View was updated (%" PRIu64 ")\n", view_size);
2543 struct RPSPeer *rps_peer = (struct RPSPeer *) cls;
2544 to_file ("/tmp/rps/view_sizes.txt",
2545 "%" PRIu32 " %" PRIu64 "",
2546 rps_peer->index,
2547 view_size);
2548 for (uint64_t i = 0; i < view_size; i++)
2549 {
2550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2551 "\t%s\n", GNUNET_i2s (&peers[i]));
2552 }
2553 GNUNET_array_grow (rps_peer->cur_view,
2554 rps_peer->cur_view_count,
2555 view_size);
2556 // *rps_peer->cur_view = *peers;
2557 GNUNET_memcpy (rps_peer->cur_view,
2558 peers,
2559 view_size * sizeof(struct GNUNET_PeerIdentity));
2560 to_file ("/tmp/rps/count_in_views.txt",
2561 "%" PRIu32 " %" PRIu32 "",
2562 rps_peer->index,
2563 count_peer_in_views_2 (rps_peer->index));
2564 cumulated_view_sizes ();
2565 if (0 != view_size)
2566 {
2567 to_file ("/tmp/rps/repr.txt",
2568 "%" PRIu32 /* index */
2569 " %" PRIu32 /* occurrence in views */
2570 " %" PRIu32 /* view sizes */
2571 " %f" /* fraction of repr in views */
2572 " %f" /* average view size */
2573 " %f" /* prob of occurrence in view slot */
2574 " %f" "", /* exp frac of repr in views */
2575 rps_peer->index,
2576 count_peer_in_views_2 (rps_peer->index),
2577 view_sizes,
2578 count_peer_in_views_2 (rps_peer->index) / (view_size * 1.0), /* fraction of representation in views */
2579 view_sizes / (view_size * 1.0), /* average view size */
2580 1.0 / view_size, /* prob of occurrence in view slot */
2581 (1.0 / view_size) * (view_sizes / view_size) /* expected fraction of repr in views */
2582 );
2583 }
2584 compute_probabilities (rps_peer->index);
2585 all_views_updated_cb ();
2586}
2587
2588
2589static void
2590pre_profiler (struct RPSPeer *rps_peer, struct GNUNET_RPS_Handle *h)
2591{
2592 rps_peer->file_name_probs =
2593 store_prefix_file_name (rps_peer->index, "probs");
2594 rps_peer->file_name_probs_hist =
2595 store_prefix_file_name (rps_peer->index, "probs_hist");
2596 rps_peer->eval_probs_cache = GNUNET_new_array (num_peers, double);
2597 memset (rps_peer->eval_probs_cache, 0, num_peers * sizeof (double));
2598 GNUNET_RPS_view_request (h, 0, view_update_cb, rps_peer);
2599}
2600
2601void
2602write_final_stats (void)
2603{
2604 uint64_t sums[STAT_TYPE_MAX] = { 0 };
2605
2606 for (uint32_t i = 0; i < num_peers; i++)
2607 {
2608 to_file ("/tmp/rps/final_stats.csv",
2609 "%" PRIu32 ", " /* index */
2610 "%s, %" /* id */
2611 PRIu64 ", %" /* rounds */
2612 PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %"
2613 PRIu64 ", %" /* blocking */
2614 PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* issued */
2615 PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* sent */
2616 PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %"
2617 PRIu64 ", %" /* recv */
2618 PRIu64 ", %" /* view size */
2619 PRIu64 ", %" /* known peers */
2620 PRIu64 ", %" /* valid peers */
2621 PRIu64 ", %" /* learned peers */
2622 PRIu64 ", %" /* pending online checks */
2623 PRIu64 ", %" /* unrequested pull replies */
2624 PRIu64 ", %" /* peers in push map */
2625 PRIu64 ", %" /* peers in pull map */
2626 PRIu64 ", %" /* peers in view */
2627 PRIu64 "\n" /* view size aim */,
2628 i,
2629 GNUNET_i2s (rps_peers[i].peer_id),
2630 rps_peers[i].stats[STAT_TYPE_ROUNDS],
2631 rps_peers[i].stats[STAT_TYPE_BLOCKS],
2632 rps_peers[i].stats[STAT_TYPE_BLOCKS_MANY_PUSH],
2633 rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PUSH],
2634 rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PULL],
2635 rps_peers[i].stats[STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL],
2636 rps_peers[i].stats[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL],
2637 rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND],
2638 rps_peers[i].stats[STAT_TYPE_ISSUED_PUSH_SEND_MH],
2639 rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ],
2640 rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REQ_MH],
2641 rps_peers[i].stats[STAT_TYPE_ISSUED_PULL_REP],
2642 rps_peers[i].stats[STAT_TYPE_SENT_PUSH_SEND],
2643 rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ],
2644 rps_peers[i].stats[STAT_TYPE_SENT_PULL_REQ_MH],
2645 rps_peers[i].stats[STAT_TYPE_SENT_PULL_REP],
2646 rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND],
2647 rps_peers[i].stats[STAT_TYPE_RECV_PUSH_SEND_MH],
2648 rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ],
2649 rps_peers[i].stats[STAT_TYPE_RECV_PULL_REQ_MH],
2650 rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP_MH],
2651 rps_peers[i].stats[STAT_TYPE_RECV_PULL_REP],
2652 rps_peers[i].stats[STAT_TYPE_VIEW_SIZE],
2653 rps_peers[i].stats[STAT_TYPE_KNOWN_PEERS],
2654 rps_peers[i].stats[STAT_TYPE_VALID_PEERS],
2655 rps_peers[i].stats[STAT_TYPE_LEARND_PEERS],
2656 rps_peers[i].stats[STAT_TYPE_PENDING_ONLINE_CHECKS],
2657 rps_peers[i].stats[STAT_TYPE_UNREQUESTED_PULL_REPLIES],
2658 rps_peers[i].stats[STAT_TYPE_PEERS_IN_PUSH_MAP],
2659 rps_peers[i].stats[STAT_TYPE_PEERS_IN_PULL_MAP],
2660 rps_peers[i].stats[STAT_TYPE_PEERS_IN_VIEW],
2661 rps_peers[i].stats[STAT_TYPE_VIEW_SIZE_AIM]);
2662 for (enum STAT_TYPE stat_type = STAT_TYPE_ROUNDS;
2663 stat_type < STAT_TYPE_MAX;
2664 stat_type++)
2665 {
2666 sums[stat_type] += rps_peers[i].stats[stat_type];
2667 }
2668 }
2669 to_file ("/tmp/rps/final_stats.dat",
2670 "SUM %"
2671 PRIu64 " %" /* rounds */
2672 PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
2673 " %" /* blocking */
2674 PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* issued */
2675 PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" /* sent */
2676 PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %" PRIu64 ", %"
2677 PRIu64 ", %" /* recv */
2678 PRIu64 ", %" /* view size */
2679 PRIu64 ", %" /* known peers */
2680 PRIu64 ", %" /* valid peers */
2681 PRIu64 ", %" /* learned peers */
2682 PRIu64 ", %" /* pending online checks */
2683 PRIu64 ", %" /* unrequested pull replies */
2684 PRIu64 ", %" /* peers in push map */
2685 PRIu64 ", %" /* peers in pull map */
2686 PRIu64 ", %" /* peers in view */
2687 PRIu64 "\n" /* view size aim */,
2688 sums[STAT_TYPE_ROUNDS],
2689 sums[STAT_TYPE_BLOCKS],
2690 sums[STAT_TYPE_BLOCKS_MANY_PUSH],
2691 sums[STAT_TYPE_BLOCKS_NO_PUSH],
2692 sums[STAT_TYPE_BLOCKS_NO_PULL],
2693 sums[STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL],
2694 sums[STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL],
2695 sums[STAT_TYPE_ISSUED_PUSH_SEND],
2696 sums[STAT_TYPE_ISSUED_PUSH_SEND_MH],
2697 sums[STAT_TYPE_ISSUED_PULL_REQ],
2698 sums[STAT_TYPE_ISSUED_PULL_REQ_MH],
2699 sums[STAT_TYPE_ISSUED_PULL_REP],
2700 sums[STAT_TYPE_SENT_PUSH_SEND],
2701 sums[STAT_TYPE_SENT_PULL_REQ],
2702 sums[STAT_TYPE_SENT_PULL_REQ_MH],
2703 sums[STAT_TYPE_SENT_PULL_REP],
2704 sums[STAT_TYPE_RECV_PUSH_SEND],
2705 sums[STAT_TYPE_RECV_PUSH_SEND_MH],
2706 sums[STAT_TYPE_RECV_PULL_REQ],
2707 sums[STAT_TYPE_RECV_PULL_REQ_MH],
2708 sums[STAT_TYPE_RECV_PULL_REP],
2709 sums[STAT_TYPE_RECV_PULL_REP_MH],
2710 sums[STAT_TYPE_VIEW_SIZE],
2711 sums[STAT_TYPE_KNOWN_PEERS],
2712 sums[STAT_TYPE_VALID_PEERS],
2713 sums[STAT_TYPE_LEARND_PEERS],
2714 sums[STAT_TYPE_PENDING_ONLINE_CHECKS],
2715 sums[STAT_TYPE_UNREQUESTED_PULL_REPLIES],
2716 sums[STAT_TYPE_PEERS_IN_PUSH_MAP],
2717 sums[STAT_TYPE_PEERS_IN_PULL_MAP],
2718 sums[STAT_TYPE_PEERS_IN_VIEW],
2719 sums[STAT_TYPE_VIEW_SIZE_AIM]);
2720}
2721
2722
2723/**
2724 * Continuation called by #GNUNET_STATISTICS_get() functions.
2725 *
2726 * Remembers that this specific statistics value was received for this peer.
2727 * Checks whether all peers received their statistics yet.
2728 * Issues the shutdown.
2729 *
2730 * @param cls closure
2731 * @param success #GNUNET_OK if statistics were
2732 * successfully obtained, #GNUNET_SYSERR if not.
2733 */
2734void
2735post_test_shutdown_ready_cb (void *cls,
2736 int success)
2737{
2738 struct STATcls *stat_cls = (struct STATcls *) cls;
2739 struct RPSPeer *rps_peer = stat_cls->rps_peer;
2740
2741 rps_peer->h_stat_get[stat_cls->stat_type] = NULL;
2742 if (GNUNET_OK == success)
2743 {
2744 /* set flag that we we got the value */
2745 rps_peer->stat_collected_flags |= BIT (stat_cls->stat_type);
2746 }
2747 else
2748 {
2749 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2750 "Peer %u did not receive statistics value\n",
2751 rps_peer->index);
2752 GNUNET_free (stat_cls);
2753 GNUNET_break (0);
2754 return;
2755 }
2756
2757 if ((NULL != rps_peer->stat_op) &&
2758 (GNUNET_YES == check_statistics_collect_completed_single_peer (
2759 rps_peer)) )
2760 {
2761 GNUNET_TESTBED_operation_done (rps_peer->stat_op);
2762 }
2763
2764 write_final_stats ();
2765 if (GNUNET_YES == check_statistics_collect_completed ())
2766 {
2767 // write_final_stats ();
2768 GNUNET_free (stat_cls);
2769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2770 "Shutting down\n");
2771 GNUNET_SCHEDULER_shutdown ();
2772 }
2773 else
2774 {
2775 GNUNET_free (stat_cls);
2776 }
2777}
2778
2779
2780/**
2781 * Callback function to process statistic values.
2782 *
2783 * @param cls closure
2784 * @param subsystem name of subsystem that created the statistic
2785 * @param name the name of the datum
2786 * @param value the current value
2787 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
2788 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
2789 */
2790int
2791stat_iterator (void *cls,
2792 const char *subsystem,
2793 const char *name,
2794 uint64_t value,
2795 int is_persistent)
2796{
2797 const struct STATcls *stat_cls = (const struct STATcls *) cls;
2798 struct RPSPeer *rps_peer = (struct RPSPeer *) stat_cls->rps_peer;
2799 enum STAT_TYPE stat_type;
2800
2801 (void) subsystem;
2802 (void) is_persistent;
2803
2804 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2805 "Got stat value: %s - %" PRIu64 " (%u)\n",
2806 name,
2807 value,
2808 rps_peer->index);
2809 to_file (rps_peer->file_name_stats,
2810 "%s: %" PRIu64 "\n",
2811 name,
2812 value);
2813 stat_type = stat_str_2_type (name);
2814 GNUNET_assert (STAT_TYPE_ROUNDS <= stat_type &&
2815 STAT_TYPE_MAX > stat_type);
2816 rps_peer->stats[stat_type] = value;
2817 return GNUNET_OK;
2818}
2819
2820
2821void
2822post_profiler (struct RPSPeer *rps_peer)
2823{
2824 if (COLLECT_STATISTICS != cur_test_run.have_collect_statistics)
2825 {
2826 return;
2827 }
2828
2829 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2830 "Going to request statistic values with mask 0x%" PRIx32 "\n",
2831 cur_test_run.stat_collect_flags);
2832
2833 struct STATcls *stat_cls;
2834 uint32_t stat_type;
2835 for (stat_type = STAT_TYPE_ROUNDS;
2836 stat_type < STAT_TYPE_MAX;
2837 stat_type++)
2838 {
2839 if (BIT (stat_type) & cur_test_run.stat_collect_flags)
2840 {
2841 stat_cls = GNUNET_malloc (sizeof(struct STATcls));
2842 stat_cls->rps_peer = rps_peer;
2843 stat_cls->stat_type = stat_type;
2844 rps_peer->file_name_stats =
2845 store_prefix_file_name (rps_peer->index, "stats");
2846 rps_peer->h_stat_get[stat_type] =
2847 GNUNET_STATISTICS_get (rps_peer->stats_h,
2848 "rps",
2849 stat_type_strings [stat_type],
2850 post_test_shutdown_ready_cb,
2851 stat_iterator,
2852 (struct STATcls *) stat_cls);
2853 GNUNET_assert (NULL != rps_peer->h_stat_get);
2854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2855 "Requested statistics for %s (peer %" PRIu32 ")\n",
2856 stat_type_strings [stat_type],
2857 rps_peer->index);
2858 }
2859 }
2860 GNUNET_free (rps_peer->eval_probs_cache);
2861}
2862
2863
2864/***********************************************************************
2865* /Definition of tests
2866***********************************************************************/
2867
2868
2869/**
2870 * Actual "main" function for the testcase.
2871 *
2872 * @param cls closure
2873 * @param h the run handle
2874 * @param n_peers number of peers in 'peers'
2875 * @param peers handle to peers run in the testbed
2876 * @param links_succeeded the number of overlay link connection attempts that
2877 * succeeded
2878 * @param links_failed the number of overlay link connection attempts that
2879 * failed
2880 */
2881static void
2882test_run (void *cls,
2883 struct GNUNET_TESTBED_RunHandle *h,
2884 unsigned int n_peers,
2885 struct GNUNET_TESTBED_Peer **peers,
2886 unsigned int links_succeeded,
2887 unsigned int links_failed)
2888{
2889 unsigned int i;
2890 struct OpListEntry *entry;
2891
2892 (void) cls;
2893 (void) h;
2894 (void) links_failed;
2895
2896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "RUN was called\n");
2897
2898 /* Check whether we timed out */
2899 if ((n_peers != num_peers) ||
2900 (NULL == peers) ||
2901 (0 == links_succeeded) )
2902 {
2903 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2904 "Going down due to args (eg. timeout)\n");
2905 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tn_peers: %u\n", n_peers);
2906 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tnum_peers: %" PRIu32 "\n",
2907 num_peers);
2908 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tpeers: %p\n", peers);
2909 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tlinks_succeeded: %u\n",
2910 links_succeeded);
2911 ok = 1;
2912 GNUNET_SCHEDULER_shutdown ();
2913 return;
2914 }
2915
2916
2917 /* Initialize peers */
2918 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "going to initialise peers\n");
2919 testbed_peers = peers;
2920 num_peers_online = 0;
2921 for (i = 0; i < num_peers; i++)
2922 {
2923 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "initialising %u\n", i);
2924 entry = make_oplist_entry ();
2925 entry->index = i;
2926 rps_peers[i].index = i;
2927 if (NULL != cur_test_run.init_peer)
2928 cur_test_run.init_peer (&rps_peers[i]);
2929 if (NO_COLLECT_VIEW == cur_test_run.have_collect_view)
2930 {
2931 rps_peers->cur_view_count = 0;
2932 rps_peers->cur_view = NULL;
2933 }
2934 entry->op = GNUNET_TESTBED_peer_get_information (peers[i],
2935 GNUNET_TESTBED_PIT_IDENTITY,
2936 &info_cb,
2937 entry);
2938 }
2939
2940 /* Bring peers up */
2941 GNUNET_assert (num_peers == n_peers);
2942 for (i = 0; i < n_peers; i++)
2943 {
2944 rps_peers[i].index = i;
2945 rps_peers[i].op =
2946 GNUNET_TESTBED_service_connect (&rps_peers[i],
2947 peers[i],
2948 "rps",
2949 &rps_connect_complete_cb,
2950 &rps_peers[i],
2951 &rps_connect_adapter,
2952 &rps_disconnect_adapter,
2953 &rps_peers[i]);
2954 /* Connect all peers to statistics service */
2955 if (COLLECT_STATISTICS == cur_test_run.have_collect_statistics)
2956 {
2957 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2958 "Connecting to statistics service\n");
2959 rps_peers[i].stat_op =
2960 GNUNET_TESTBED_service_connect (NULL,
2961 peers[i],
2962 "statistics",
2963 stat_complete_cb,
2964 &rps_peers[i],
2965 &stat_connect_adapter,
2966 &stat_disconnect_adapter,
2967 &rps_peers[i]);
2968 }
2969 }
2970
2971 if (NULL != churn_task)
2972 GNUNET_SCHEDULER_cancel (churn_task);
2973 post_test_task = GNUNET_SCHEDULER_add_delayed (duration, &post_test_op, NULL);
2974 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "timeout for shutdown is %lu\n",
2975 timeout.rel_value_us / 1000000);
2976 shutdown_task = GNUNET_SCHEDULER_add_delayed (timeout,
2977 &trigger_shutdown,
2978 NULL);
2979 GNUNET_SCHEDULER_add_shutdown (shutdown_op, NULL);
2980}
2981
2982
2983/**
2984 * Entry point for the testcase, sets up the testbed.
2985 *
2986 * @param argc unused
2987 * @param argv unused
2988 */
2989static void
2990run (void *cls,
2991 char *const *args,
2992 const char *cfgfile,
2993 const struct GNUNET_CONFIGURATION_Handle *cfg)
2994{
2995 // int ret_value;
2996 (void) cls;
2997 (void) args;
2998 (void) cfgfile;
2999
3000 /* Defaults for tests */
3001 churn_task = NULL;
3002
3003 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n");
3004 cur_test_run.name = "test-rps-profiler";
3005 if (0 == num_peers)
3006 num_peers = 10;
3007 mal_type = 3;
3008 cur_test_run.init_peer = profiler_init_peer;
3009 // cur_test_run.pre_test = mal_pre;
3010 cur_test_run.pre_test = pre_profiler;
3011 cur_test_run.main_test = profiler_cb;
3012 cur_test_run.reply_handle = profiler_reply_handle;
3013 cur_test_run.eval_cb = profiler_eval;
3014 cur_test_run.post_test = post_profiler;
3015 cur_test_run.request_interval = 2;
3016 if (0 == cur_test_run.num_requests)
3017 cur_test_run.num_requests = 5;
3018 // cur_test_run.have_churn = HAVE_CHURN;
3019 cur_test_run.have_churn = HAVE_NO_CHURN;
3020 cur_test_run.have_quick_quit = HAVE_QUICK_QUIT;
3021 cur_test_run.have_collect_statistics = COLLECT_STATISTICS;
3022 cur_test_run.stat_collect_flags = BIT (STAT_TYPE_ROUNDS)
3023 | BIT (STAT_TYPE_BLOCKS)
3024 | BIT (STAT_TYPE_BLOCKS_MANY_PUSH)
3025 | BIT (STAT_TYPE_BLOCKS_NO_PUSH)
3026 | BIT (STAT_TYPE_BLOCKS_NO_PULL)
3027 | BIT (STAT_TYPE_BLOCKS_MANY_PUSH_NO_PULL)
3028 | BIT (STAT_TYPE_BLOCKS_NO_PUSH_NO_PULL)
3029 | BIT (STAT_TYPE_ISSUED_PUSH_SEND)
3030 | BIT (STAT_TYPE_ISSUED_PUSH_SEND_MH)
3031 | BIT (STAT_TYPE_ISSUED_PULL_REQ)
3032 | BIT (STAT_TYPE_ISSUED_PULL_REQ_MH)
3033 | BIT (STAT_TYPE_ISSUED_PULL_REP)
3034 | BIT (STAT_TYPE_SENT_PUSH_SEND)
3035 | BIT (STAT_TYPE_SENT_PULL_REQ)
3036 | BIT (STAT_TYPE_SENT_PULL_REQ_MH)
3037 | BIT (STAT_TYPE_SENT_PULL_REP)
3038 | BIT (STAT_TYPE_RECV_PUSH_SEND)
3039 | BIT (STAT_TYPE_RECV_PUSH_SEND_MH)
3040 | BIT (STAT_TYPE_RECV_PULL_REQ)
3041 | BIT (STAT_TYPE_RECV_PULL_REQ_MH)
3042 | BIT (STAT_TYPE_RECV_PULL_REP)
3043 | BIT (STAT_TYPE_RECV_PULL_REP_MH)
3044 | BIT (STAT_TYPE_VIEW_SIZE)
3045 | BIT (STAT_TYPE_KNOWN_PEERS)
3046 | BIT (STAT_TYPE_VALID_PEERS)
3047 | BIT (STAT_TYPE_LEARND_PEERS)
3048 | BIT (STAT_TYPE_PENDING_ONLINE_CHECKS)
3049 | BIT (STAT_TYPE_UNREQUESTED_PULL_REPLIES)
3050 | BIT (STAT_TYPE_PEERS_IN_PUSH_MAP)
3051 | BIT (STAT_TYPE_PEERS_IN_PULL_MAP)
3052 | BIT (STAT_TYPE_PEERS_IN_VIEW)
3053 | BIT (STAT_TYPE_VIEW_SIZE_AIM);
3054 cur_test_run.have_collect_view = COLLECT_VIEW;
3055
3056 /* 'Clean' directory */
3057 (void) GNUNET_DISK_directory_remove ("/tmp/rps/");
3058 GNUNET_DISK_directory_create ("/tmp/rps/");
3059 if (0 == duration.rel_value_us)
3060 {
3061 if (0 == timeout.rel_value_us)
3062 {
3063 duration = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 90);
3064 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
3065 (90 * 1.2)
3066 + (0.01 * num_peers));
3067 }
3068 else
3069 {
3070 duration = GNUNET_TIME_relative_multiply (
3071 GNUNET_TIME_UNIT_SECONDS,
3072 ( (double) timeout.rel_value_us / (double) 1000000)
3073 * 0.75);
3074 }
3075 }
3076 else
3077 {
3078 if (0 == timeout.rel_value_us)
3079 {
3080 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
3081 ((duration.rel_value_us
3082 / 1000000)
3083 * 1.2) + (0.01 * num_peers));
3084 }
3085 }
3086 GNUNET_assert (duration.rel_value_us < timeout.rel_value_us);
3087 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3088 "duration is %lus\n",
3089 duration.rel_value_us / 1000000);
3090 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3091 "timeout is %lus\n",
3092 timeout.rel_value_us / 1000000);
3093
3094 /* Compute number of bits for representing largest peer id */
3095 for (bits_needed = 1; (uint32_t) (1 << bits_needed) < num_peers; bits_needed++)
3096 ;
3097 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3098 "Need %u bits to represent %" PRIu32 " peers\n",
3099 bits_needed,
3100 num_peers);
3101
3102 rps_peers = GNUNET_new_array (num_peers, struct RPSPeer);
3103 peer_map = GNUNET_CONTAINER_multipeermap_create (num_peers, GNUNET_NO);
3104 rps_peer_ids = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
3105 if ((2 == mal_type) ||
3106 (3 == mal_type))
3107 target_peer = &rps_peer_ids[num_peers - 2];
3108
3109 ok = 1;
3110 GNUNET_TESTBED_run (NULL,
3111 cfg,
3112 num_peers,
3113 0, /* event mask */
3114 NULL,
3115 NULL,
3116 &test_run,
3117 NULL);
3118}
3119
3120
3121/**
3122 * Entry point for the testcase, sets up the testbed.
3123 *
3124 * @param argc unused
3125 * @param argv unused
3126 * @return 0 on success
3127 */
3128int
3129main (int argc, char *argv[])
3130{
3131 int ret_value;
3132 struct GNUNET_GETOPT_CommandLineOption options[] = {
3133 GNUNET_GETOPT_option_uint ('n',
3134 "num-peers",
3135 "COUNT",
3136 gettext_noop ("number of peers to start"),
3137 &num_peers),
3138 GNUNET_GETOPT_option_relative_time ('d',
3139 "duration",
3140 "DURATION",
3141 gettext_noop (
3142 "duration of the profiling"),
3143 &duration),
3144 GNUNET_GETOPT_option_relative_time ('t',
3145 "timeout",
3146 "TIMEOUT",
3147 gettext_noop (
3148 "timeout for the profiling"),
3149 &timeout),
3150 GNUNET_GETOPT_option_uint ('r',
3151 "num-requests",
3152 "COUNT",
3153 gettext_noop ("number of PeerIDs to request"),
3154 &cur_test_run.num_requests),
3155 GNUNET_GETOPT_OPTION_END
3156 };
3157
3158 unsetenv ("XDG_DATA_HOME");
3159 unsetenv ("XDG_CONFIG_HOME");
3160 // if (GNUNET_OK !=
3161 // GNUNET_STRINGS_get_utf8_args (argc, argv,
3162 // &argc, &argv))
3163 // return 2;
3164 ret_value = 0;
3165 if (GNUNET_OK !=
3166 GNUNET_PROGRAM_run (argc,
3167 argv,
3168 "gnunet-rps-profiler",
3169 gettext_noop (
3170 "Measure quality and performance of the RPS service."),
3171 options,
3172 &run,
3173 NULL))
3174 {
3175 ret_value = 1;
3176 }
3177 if (0 != ret_value)
3178 {
3179 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3180 "Test did not run successfully!\n");
3181 }
3182 else
3183 {
3184 ret_value = cur_test_run.eval_cb ();
3185 if (NO_COLLECT_VIEW == cur_test_run.have_collect_view)
3186 {
3187 GNUNET_array_grow (rps_peers->cur_view,
3188 rps_peers->cur_view_count,
3189 0);
3190 }
3191 GNUNET_free (rps_peers);
3192 GNUNET_free (rps_peer_ids);
3193 GNUNET_CONTAINER_multipeermap_destroy (peer_map);
3194 }
3195 return ret_value;
3196}
3197
3198
3199/* end of test_rps.c */
diff --git a/src/contrib/service/secretsharing/Makefile.am b/src/contrib/service/secretsharing/Makefile.am
index afc42309c..d9c2b37b4 100644
--- a/src/contrib/service/secretsharing/Makefile.am
+++ b/src/contrib/service/secretsharing/Makefile.am
@@ -16,23 +16,10 @@ endif
16libexec_PROGRAMS = \ 16libexec_PROGRAMS = \
17 gnunet-service-secretsharing 17 gnunet-service-secretsharing
18 18
19#noinst_PROGRAMS = \
20# gnunet-secretsharing-profiler
21
22lib_LTLIBRARIES = \ 19lib_LTLIBRARIES = \
23 libgnunetsecretsharing.la 20 libgnunetsecretsharing.la
24 21
25 22
26# TNG
27#gnunet_secretsharing_profiler_SOURCES = \
28# gnunet-secretsharing-profiler.c
29#gnunet_secretsharing_profiler_LDADD = \
30# libgnunetsecretsharing.la \
31# $(top_builddir)/src/service/testing/libgnunettesting.la \
32# $(top_builddir)/src/testbed/libgnunettestbed.la \
33# $(top_builddir)/src/lib/util/libgnunetutil.la \
34# $(GN_LIBINTL)
35
36gnunet_service_secretsharing_SOURCES = \ 23gnunet_service_secretsharing_SOURCES = \
37 gnunet-service-secretsharing.c \ 24 gnunet-service-secretsharing.c \
38 secretsharing_common.c \ 25 secretsharing_common.c \
diff --git a/src/contrib/service/secretsharing/gnunet-secretsharing-profiler.c b/src/contrib/service/secretsharing/gnunet-secretsharing-profiler.c
deleted file mode 100644
index 432d6da89..000000000
--- a/src/contrib/service/secretsharing/gnunet-secretsharing-profiler.c
+++ /dev/null
@@ -1,662 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2014 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file secretsharing/gnunet-secretsharing-profiler.c
23 * @brief profiling tool for distributed key generation and decryption
24 * @author Florian Dold
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_secretsharing_service.h"
29#include "gnunet_testbed_service.h"
30
31/**
32 * How many peers should participate in the key generation?
33 */
34static unsigned int num_peers = 3;
35
36/**
37 * What should the threshold for then key be?
38 */
39static unsigned int threshold = 2;
40
41/**
42 * Should we try to decrypt a value after the key generation?
43 */
44static int decrypt = GNUNET_NO;
45
46/**
47 * When would we like to see the operation finished?
48 */
49static struct GNUNET_TIME_Relative timeout;
50
51/**
52 * When should dkg communication start?
53 */
54static struct GNUNET_TIME_Relative delay;
55
56/**
57 * Handles for secretsharing sessions.
58 */
59static struct GNUNET_SECRETSHARING_Session **session_handles;
60
61static struct GNUNET_SECRETSHARING_DecryptionHandle **decrypt_handles;
62
63/**
64 * Shares we got from the distributed key generation.
65 */
66static struct GNUNET_SECRETSHARING_Share **shares;
67
68static struct GNUNET_SECRETSHARING_PublicKey common_pubkey;
69
70
71static unsigned int num_connected_sessions;
72
73static unsigned int num_connected_decrypt;
74
75/**
76 * Handles to the running peers.
77 * When peers[i] is NULL, the i-th peer has stopped.
78 */
79static struct GNUNET_TESTBED_Peer **peers;
80
81static struct GNUNET_PeerIdentity *peer_ids;
82
83static unsigned int num_retrieved_peer_ids;
84
85static unsigned int num_generated;
86
87static unsigned int num_decrypted;
88
89static struct GNUNET_HashCode session_id;
90
91static unsigned int verbose;
92
93static struct GNUNET_SECRETSHARING_Plaintext reference_plaintext;
94
95static struct GNUNET_SECRETSHARING_Ciphertext ciphertext;
96
97static struct GNUNET_TIME_Absolute dkg_start;
98
99static struct GNUNET_TIME_Absolute dkg_deadline;
100
101
102static struct GNUNET_TIME_Absolute decrypt_start;
103
104static struct GNUNET_TIME_Absolute decrypt_deadline;
105
106/**
107 * Connect operations, one for every peer.
108 */
109static struct GNUNET_TESTBED_Operation **connect_ops;
110
111/**
112 * Are we performing a shutdown right now?
113 */
114static int in_shutdown;
115
116
117/**
118 * Signature of the event handler function called by the
119 * respective event controller.
120 *
121 * @param cls closure
122 * @param event information about the event
123 */
124static void
125controller_cb (void *cls,
126 const struct GNUNET_TESTBED_EventInformation *event)
127{
128 GNUNET_assert (0);
129}
130
131
132/**
133 * Callback to be called when a service connect operation is completed
134 *
135 * @param cls the callback closure from functions generating an operation
136 * @param op the operation that has been finished
137 * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
138 * @param emsg error message in case the operation has failed; will be NULL if
139 * operation has executed successfully.
140 */
141static void
142session_connect_complete (void *cls,
143 struct GNUNET_TESTBED_Operation *op,
144 void *ca_result,
145 const char *emsg)
146{
147 if (NULL != emsg)
148 {
149 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
150 "testbed connect emsg: %s\n",
151 emsg);
152 GNUNET_assert (0);
153 }
154
155 num_connected_sessions++;
156
157 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
158 "dkg: session connect complete\n");
159
160 if (num_connected_sessions == num_peers)
161 {
162 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
163 "dkg: all peers connected\n");
164 }
165}
166
167
168/**
169 * Callback to be called when a service connect operation is completed
170 *
171 * @param cls the callback closure from functions generating an operation
172 * @param op the operation that has been finished
173 * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
174 * @param emsg error message in case the operation has failed; will be NULL if
175 * operation has executed successfully.
176 */
177static void
178decrypt_connect_complete (void *cls,
179 struct GNUNET_TESTBED_Operation *op,
180 void *ca_result,
181 const char *emsg)
182{
183 if (NULL != emsg)
184 {
185 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
186 "testbed connect emsg: %s\n",
187 emsg);
188 GNUNET_assert (0);
189 }
190
191 num_connected_decrypt++;
192
193 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
194 "decrypt: session connect complete\n");
195
196 if (num_connected_decrypt == num_peers)
197 {
198 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
199 "decrypt: all peers connected\n");
200 }
201}
202
203
204/**
205 * Called when a decryption has succeeded.
206 *
207 * @param cls Plaintext
208 * @param plaintext Plaintext
209 */
210static void
211decrypt_cb (void *cls,
212 const struct GNUNET_SECRETSHARING_Plaintext *plaintext)
213{
214 struct GNUNET_SECRETSHARING_DecryptionHandle **dhp = cls;
215 unsigned int n = dhp - decrypt_handles;
216
217 num_decrypted++;
218
219 *dhp = NULL;
220
221 // we should still be connected if this is called
222 GNUNET_assert (NULL != connect_ops[n]);
223
224 GNUNET_TESTBED_operation_done (connect_ops[n]);
225
226 if (NULL == plaintext)
227 {
228 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "decrypt failed for peer %u\n", n);
229 return;
230 }
231 else if (0 == GNUNET_memcmp (&reference_plaintext, plaintext))
232 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
233 "decrypt got correct result for peer %u\n", n);
234 else
235 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
236 "decrypt got wrong result for peer %u\n", n);
237
238 if (num_decrypted == num_peers)
239 {
240 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "every peer decrypted\n");
241 GNUNET_SCHEDULER_shutdown ();
242 }
243
244 *dhp = NULL;
245}
246
247
248/**
249 * Adapter function called to establish a connection to
250 * a service.
251 *
252 * @param cls closure
253 * @param cfg configuration of the peer to connect to; will be available until
254 * GNUNET_TESTBED_operation_done() is called on the operation returned
255 * from GNUNET_TESTBED_service_connect()
256 * @return service handle to return in 'op_result', NULL on error
257 */
258static void *
259decrypt_connect_adapter (void *cls,
260 const struct GNUNET_CONFIGURATION_Handle *cfg)
261{
262 struct GNUNET_SECRETSHARING_DecryptionHandle **hp = cls;
263 unsigned int n = hp - decrypt_handles;
264
265 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
266 "decrypt connect adapter, %d peers\n",
267 num_peers);
268 *hp = GNUNET_SECRETSHARING_decrypt (cfg, shares[n], &ciphertext,
269 decrypt_start, decrypt_deadline,
270 decrypt_cb,
271 hp);
272
273 return *hp;
274}
275
276
277/**
278 * Adapter function called to destroy a connection to
279 * a service.
280 *
281 * @param cls closure
282 * @param op_result service handle returned from the connect adapter
283 */
284static void
285decrypt_disconnect_adapter (void *cls, void *op_result)
286{
287 struct GNUNET_SECRETSHARING_DecryptionHandle **dh = cls;
288 unsigned int n = dh - decrypt_handles;
289
290 GNUNET_assert (*dh == decrypt_handles[n]);
291
292 if (NULL != *dh)
293 {
294 GNUNET_SECRETSHARING_decrypt_cancel (*dh);
295 *dh = NULL;
296 }
297
298 GNUNET_assert (NULL != connect_ops[n]);
299 connect_ops[n] = NULL;
300}
301
302
303static void
304secret_ready_cb (void *cls,
305 struct GNUNET_SECRETSHARING_Share *my_share,
306 struct GNUNET_SECRETSHARING_PublicKey *public_key,
307 unsigned int num_ready_peers,
308 const struct GNUNET_PeerIdentity *ready_peers)
309{
310 struct GNUNET_SECRETSHARING_Session **sp = cls;
311 unsigned int n = sp - session_handles;
312 char pubkey_str[1024];
313 char *ret;
314
315 num_generated++;
316 *sp = NULL;
317 shares[n] = my_share;
318 if (NULL == my_share)
319 {
320 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "key generation failed for peer #%u\n",
321 n);
322 }
323 else
324 {
325 ret = GNUNET_STRINGS_data_to_string (public_key, sizeof *public_key,
326 pubkey_str, 1024);
327 GNUNET_assert (NULL != ret);
328 *ret = '\0';
329 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
330 "key generation successful for peer #%u, pubkey %s\n", n,
331 pubkey_str);
332
333 /* we're the first to get the key -> store it */
334 if (num_generated == 1)
335 {
336 common_pubkey = *public_key;
337 }
338 else if (0 != GNUNET_memcmp (public_key, &common_pubkey))
339 {
340 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
341 "generated public keys do not match\n");
342 GNUNET_SCHEDULER_shutdown ();
343 return;
344 }
345 }
346
347 // we should still be connected
348 GNUNET_assert (NULL != connect_ops[n]);
349
350 // disconnect from the service, will call the disconnect callback
351 GNUNET_TESTBED_operation_done (connect_ops[n]);
352}
353
354
355/**
356 * Adapter function called to establish a connection to
357 * a service.
358 *
359 * @param cls closure
360 * @param cfg configuration of the peer to connect to; will be available until
361 * GNUNET_TESTBED_operation_done() is called on the operation returned
362 * from GNUNET_TESTBED_service_connect()
363 * @return service handle to return in 'op_result', NULL on error
364 */
365static void *
366session_connect_adapter (void *cls,
367 const struct GNUNET_CONFIGURATION_Handle *cfg)
368{
369 struct GNUNET_SECRETSHARING_Session **sp = cls;
370
371 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
372 "connect adapter, %d peers\n",
373 num_peers);
374 *sp = GNUNET_SECRETSHARING_create_session (cfg,
375 num_peers,
376 peer_ids,
377 &session_id,
378 dkg_start,
379 dkg_deadline,
380 threshold,
381 &secret_ready_cb, sp);
382 return *sp;
383}
384
385
386/**
387 * Adapter function called to destroy a connection to
388 * a service.
389 *
390 * @param cls closure
391 * @param op_result service handle returned from the connect adapter
392 */
393static void
394session_disconnect_adapter (void *cls, void *op_result)
395{
396 struct GNUNET_SECRETSHARING_Session **sp = cls;
397 unsigned int n = (sp - session_handles);
398
399 GNUNET_assert (*sp == session_handles[n]);
400
401 if (NULL != *sp)
402 {
403 GNUNET_SECRETSHARING_session_destroy (*sp);
404 *sp = NULL;
405 }
406
407 GNUNET_assert (NULL != connect_ops[n]);
408 connect_ops[n] = NULL;
409
410 if (GNUNET_YES == in_shutdown)
411 return;
412
413 // all peers received their secret
414 if (num_generated == num_peers)
415 {
416 int i;
417
418 // only do decryption if requested by the user
419 if (GNUNET_NO == decrypt)
420 {
421 GNUNET_SCHEDULER_shutdown ();
422 return;
423 }
424
425 decrypt_start = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
426 delay);
427 decrypt_deadline = GNUNET_TIME_absolute_add (decrypt_start, timeout);
428
429 // compute g^42 as the plaintext which we will decrypt and then
430 // cooperatively decrypt
431 GNUNET_SECRETSHARING_plaintext_generate_i (&reference_plaintext, 42);
432 GNUNET_SECRETSHARING_encrypt (&common_pubkey, &reference_plaintext,
433 &ciphertext);
434
435 for (i = 0; i < num_peers; i++)
436 connect_ops[i] =
437 GNUNET_TESTBED_service_connect (NULL, peers[i], "secretsharing",
438 &decrypt_connect_complete, NULL,
439 &decrypt_connect_adapter,
440 &decrypt_disconnect_adapter,
441 &decrypt_handles[i]);
442 }
443}
444
445
446/**
447 * Callback to be called when the requested peer information is available
448 *
449 * @param cb_cls the closure from GNUNET_TESTBED_peer_get_information()
450 * @param op the operation this callback corresponds to
451 * @param pinfo the result; will be NULL if the operation has failed
452 * @param emsg error message if the operation has failed; will be NULL if the
453 * operation is successful
454 */
455static void
456peer_info_cb (void *cb_cls,
457 struct GNUNET_TESTBED_Operation *op,
458 const struct GNUNET_TESTBED_PeerInformation *pinfo,
459 const char *emsg)
460{
461 struct GNUNET_PeerIdentity *p;
462 int i;
463
464 GNUNET_assert (NULL == emsg);
465
466 p = (struct GNUNET_PeerIdentity *) cb_cls;
467
468 if (pinfo->pit == GNUNET_TESTBED_PIT_IDENTITY)
469 {
470 *p = *pinfo->result.id;
471 num_retrieved_peer_ids++;
472 if (num_retrieved_peer_ids == num_peers)
473 for (i = 0; i < num_peers; i++)
474 connect_ops[i] =
475 GNUNET_TESTBED_service_connect (NULL, peers[i], "secretsharing",
476 session_connect_complete, NULL,
477 session_connect_adapter,
478 session_disconnect_adapter,
479 &session_handles[i]);
480 }
481 else
482 {
483 GNUNET_assert (0);
484 }
485
486 GNUNET_TESTBED_operation_done (op);
487}
488
489
490/**
491 * Signature of the main function of a task.
492 *
493 * @param cls closure
494 */
495static void
496handle_shutdown (void *cls)
497{
498 in_shutdown = GNUNET_YES;
499
500 if (NULL != connect_ops)
501 {
502 unsigned int i;
503 for (i = 0; i < num_peers; i++)
504 if (NULL != connect_ops[i])
505 {
506 // the disconnect callback will set the op to NULL
507 GNUNET_TESTBED_operation_done (connect_ops[i]);
508 }
509 GNUNET_free (connect_ops);
510 }
511
512 // killing the testbed operation will take care of remaining
513 // service handles in the disconnect callback
514}
515
516
517/**
518 * Signature of a main function for a testcase.
519 *
520 * @param cls closure
521 * @param h the run handle
522 * @param num_peers number of peers in 'peers'
523 * @param started_peers handle to peers run in the testbed. NULL upon timeout (see
524 * GNUNET_TESTBED_test_run()).
525 * @param links_succeeded the number of overlay link connection attempts that
526 * succeeded
527 * @param links_failed the number of overlay link connection attempts that
528 * failed
529 */
530static void
531test_master (void *cls,
532 struct GNUNET_TESTBED_RunHandle *h,
533 unsigned int num_peers,
534 struct GNUNET_TESTBED_Peer **started_peers,
535 unsigned int links_succeeded,
536 unsigned int links_failed)
537{
538 int i;
539
540 GNUNET_log_setup ("gnunet-secretsharing-profiler", "INFO", NULL);
541
542 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "test master\n");
543
544 GNUNET_SCHEDULER_add_shutdown (&handle_shutdown, NULL);
545
546 peers = started_peers;
547
548 peer_ids = GNUNET_malloc (num_peers * sizeof(struct GNUNET_PeerIdentity));
549
550 session_handles = GNUNET_new_array (num_peers, struct
551 GNUNET_SECRETSHARING_Session *);
552 decrypt_handles = GNUNET_new_array (num_peers, struct
553 GNUNET_SECRETSHARING_DecryptionHandle *);
554 connect_ops = GNUNET_new_array (num_peers, struct GNUNET_TESTBED_Operation *);
555 shares = GNUNET_new_array (num_peers, struct GNUNET_SECRETSHARING_Share *);
556
557 for (i = 0; i < num_peers; i++)
558 {
559 // we do not store the returned operation, as peer_info_cb
560 // will receive it as a parameter and call GNUNET_TESTBED_operation_done.
561 GNUNET_TESTBED_peer_get_information (peers[i],
562 GNUNET_TESTBED_PIT_IDENTITY,
563 peer_info_cb,
564 &peer_ids[i]);
565 }
566}
567
568
569static void
570run (void *cls, char *const *args, const char *cfgfile,
571 const struct GNUNET_CONFIGURATION_Handle *cfg)
572{
573 static char *session_str = "gnunet-secretsharing/test";
574 char *topology;
575 int topology_cmp_result;
576
577 dkg_start = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (), delay);
578 dkg_deadline = GNUNET_TIME_absolute_add (dkg_start, timeout);
579
580 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "testbed",
581 "OVERLAY_TOPOLOGY",
582 &topology))
583 {
584 fprintf (stderr,
585 "'OVERLAY_TOPOLOGY' not found in 'testbed' config section, "
586 "seems like you passed the wrong configuration file\n");
587 return;
588 }
589
590 topology_cmp_result = strcasecmp (topology, "NONE");
591 GNUNET_free (topology);
592
593 if (0 == topology_cmp_result)
594 {
595 fprintf (stderr,
596 "'OVERLAY_TOPOLOGY' set to 'NONE', "
597 "seems like you passed the wrong configuration file\n");
598 return;
599 }
600
601 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
602 "running gnunet-secretsharing-profiler\n");
603
604 GNUNET_CRYPTO_hash (session_str, strlen (session_str), &session_id);
605
606 (void) GNUNET_TESTBED_test_run ("gnunet-secretsharing-profiler",
607 cfgfile,
608 num_peers,
609 0,
610 controller_cb,
611 NULL,
612 test_master,
613 NULL);
614}
615
616
617int
618main (int argc, char **argv)
619{
620 struct GNUNET_GETOPT_CommandLineOption options[] = {
621 GNUNET_GETOPT_option_uint ('n',
622 "num-peers",
623 NULL,
624 gettext_noop ("number of peers in consensus"),
625 &num_peers),
626
627 GNUNET_GETOPT_option_relative_time ('D',
628 "delay",
629 NULL,
630 gettext_noop ("dkg start delay"),
631 &delay),
632
633 GNUNET_GETOPT_option_relative_time ('t',
634 "timeout",
635 NULL,
636 gettext_noop ("dkg timeout"),
637 &timeout),
638
639 GNUNET_GETOPT_option_uint ('k',
640 "threshold",
641 NULL,
642 gettext_noop ("threshold"),
643 &threshold),
644
645 GNUNET_GETOPT_option_flag ('d',
646 "descrypt",
647 gettext_noop ("also profile decryption"),
648 &decrypt),
649
650
651 GNUNET_GETOPT_option_verbose (&verbose),
652
653 GNUNET_GETOPT_OPTION_END
654 };
655
656 delay = GNUNET_TIME_UNIT_ZERO;
657 timeout = GNUNET_TIME_UNIT_MINUTES;
658 GNUNET_PROGRAM_run2 (argc, argv, "gnunet-secretsharing-profiler",
659 "help",
660 options, &run, NULL, GNUNET_YES);
661 return 0;
662}
diff --git a/src/service/cadet/cadet_test_lib.c b/src/service/cadet/cadet_test_lib.c
deleted file mode 100644
index 9c7b9063d..000000000
--- a/src/service/cadet/cadet_test_lib.c
+++ /dev/null
@@ -1,376 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2017 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file cadet/cadet_test_lib.c
22 * @author Bartlomiej Polot
23 * @brief library for writing CADET tests
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "cadet_test_lib.h"
28#include "gnunet_cadet_service.h"
29
30
31/**
32 * Test context for a CADET Test.
33 */
34struct GNUNET_CADET_TEST_Context
35{
36 /**
37 * Array of running peers.
38 */
39 struct GNUNET_TESTBED_Peer **peers;
40
41 /**
42 * Array of handles to the CADET for each peer.
43 */
44 struct GNUNET_CADET_Handle **cadets;
45
46 /**
47 * Operation associated with the connection to the CADET.
48 */
49 struct GNUNET_TESTBED_Operation **ops;
50
51 /**
52 * Number of peers running, size of the arrays above.
53 */
54 unsigned int num_peers;
55
56 /**
57 * Main function of the test to run once all CADETs are available.
58 */
59 GNUNET_CADET_TEST_AppMain app_main;
60
61 /**
62 * Closure for 'app_main'.
63 */
64 void *app_main_cls;
65
66 /**
67 * Handler for incoming tunnels.
68 */
69 GNUNET_CADET_ConnectEventHandler connects;
70
71 /**
72 * Function called when the transmit window size changes.
73 */
74 GNUNET_CADET_WindowSizeEventHandler window_changes;
75
76 /**
77 * Cleaner for destroyed incoming tunnels.
78 */
79 GNUNET_CADET_DisconnectEventHandler disconnects;
80
81 /**
82 * Message handlers.
83 */
84 struct GNUNET_MQ_MessageHandler *handlers;
85
86 /**
87 * Application ports.
88 */
89 const struct GNUNET_HashCode **ports;
90
91 /**
92 * Number of ports in #ports.
93 */
94 unsigned int port_count;
95};
96
97
98/**
99 * Context for a cadet adapter callback.
100 */
101struct GNUNET_CADET_TEST_AdapterContext
102{
103 /**
104 * Peer number for the particular peer.
105 */
106 unsigned int peer;
107
108 /**
109 * Port handlers for open ports.
110 */
111 struct GNUNET_CADET_Port **ports;
112
113 /**
114 * General context.
115 */
116 struct GNUNET_CADET_TEST_Context *ctx;
117};
118
119
120/**
121 * Adapter function called to establish a connection to
122 * the CADET service.
123 *
124 * @param cls closure
125 * @param cfg configuration of the peer to connect to; will be available until
126 * GNUNET_TESTBED_operation_done() is called on the operation returned
127 * from GNUNET_TESTBED_service_connect()
128 * @return service handle to return in 'op_result', NULL on error
129 */
130static void *
131cadet_connect_adapter (void *cls,
132 const struct GNUNET_CONFIGURATION_Handle *cfg)
133{
134 struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
135 struct GNUNET_CADET_TEST_Context *ctx = actx->ctx;
136 struct GNUNET_CADET_Handle *h;
137
138 h = GNUNET_CADET_connect (cfg);
139 if (NULL == h)
140 {
141 GNUNET_break (0);
142 return NULL;
143 }
144 if (NULL == ctx->ports)
145 return h;
146 actx->ports = GNUNET_new_array (ctx->port_count,
147 struct GNUNET_CADET_Port *);
148 for (unsigned int i = 0; i < ctx->port_count; i++)
149 {
150 actx->ports[i] = GNUNET_CADET_open_port (h,
151 ctx->ports[i],
152 ctx->connects,
153 (void *) (long) actx->peer,
154 ctx->window_changes,
155 ctx->disconnects,
156 ctx->handlers);
157 }
158 return h;
159}
160
161
162/**
163 * Adapter function called to destroy a connection to
164 * the CADET service.
165 *
166 * @param cls closure
167 * @param op_result service handle returned from the connect adapter
168 */
169static void
170cadet_disconnect_adapter (void *cls,
171 void *op_result)
172{
173 struct GNUNET_CADET_Handle *cadet = op_result;
174 struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
175
176 if (NULL != actx->ports)
177 {
178 for (unsigned int i = 0; i < actx->ctx->port_count; i++)
179 {
180 GNUNET_CADET_close_port (actx->ports[i]);
181 actx->ports[i] = NULL;
182 }
183 GNUNET_free (actx->ports);
184 }
185 GNUNET_free (actx);
186 GNUNET_CADET_disconnect (cadet);
187}
188
189
190/**
191 * Callback to be called when a service connect operation is completed.
192 *
193 * @param cls The callback closure from functions generating an operation.
194 * @param op The operation that has been finished.
195 * @param ca_result The service handle returned from
196 * GNUNET_TESTBED_ConnectAdapter() (cadet handle).
197 * @param emsg Error message in case the operation has failed.
198 * NULL if operation has executed successfully.
199 */
200static void
201cadet_connect_cb (void *cls,
202 struct GNUNET_TESTBED_Operation *op,
203 void *ca_result,
204 const char *emsg)
205{
206 struct GNUNET_CADET_TEST_Context *ctx = cls;
207
208 if (NULL != emsg)
209 {
210 fprintf (stderr,
211 "Failed to connect to CADET service: %s\n",
212 emsg);
213 GNUNET_SCHEDULER_shutdown ();
214 return;
215 }
216 for (unsigned int i = 0; i < ctx->num_peers; i++)
217 if (op == ctx->ops[i])
218 {
219 ctx->cadets[i] = ca_result;
220 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
221 "...cadet %u connected\n",
222 i);
223 }
224 for (unsigned int i = 0; i < ctx->num_peers; i++)
225 if (NULL == ctx->cadets[i])
226 return;
227 /* still some CADET connections missing */
228 /* all CADET connections ready! */
229 ctx->app_main (ctx->app_main_cls,
230 ctx,
231 ctx->num_peers,
232 ctx->peers,
233 ctx->cadets);
234}
235
236
237void
238GNUNET_CADET_TEST_cleanup (struct GNUNET_CADET_TEST_Context *ctx)
239{
240 for (unsigned int i = 0; i < ctx->num_peers; i++)
241 {
242 GNUNET_assert (NULL != ctx->ops[i]);
243 GNUNET_TESTBED_operation_done (ctx->ops[i]);
244 ctx->ops[i] = NULL;
245 }
246 GNUNET_free (ctx->ops);
247 GNUNET_free (ctx->cadets);
248 GNUNET_free (ctx->handlers);
249 GNUNET_free (ctx);
250 GNUNET_SCHEDULER_shutdown ();
251}
252
253
254/**
255 * Callback run when the testbed is ready (peers running and connected to
256 * each other)
257 *
258 * @param cls Closure (context).
259 * @param h the run handle
260 * @param num_peers Number of peers that are running.
261 * @param peers Handles to each one of the @c num_peers peers.
262 * @param links_succeeded the number of overlay link connection attempts that
263 * succeeded
264 * @param links_failed the number of overlay link connection attempts that
265 * failed
266 */
267static void
268cadet_test_run (void *cls,
269 struct GNUNET_TESTBED_RunHandle *h,
270 unsigned int num_peers,
271 struct GNUNET_TESTBED_Peer **peers,
272 unsigned int links_succeeded,
273 unsigned int links_failed)
274{
275 struct GNUNET_CADET_TEST_Context *ctx = cls;
276
277 if (0 != links_failed)
278 {
279 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
280 "Some links failed (%u), ending\n",
281 links_failed);
282 exit (77);
283 }
284 if (num_peers != ctx->num_peers)
285 {
286 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
287 "Peers started %u/%u, ending\n",
288 num_peers,
289 ctx->num_peers);
290 exit (1);
291 }
292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
293 "Testbed up, %u peers and %u links\n",
294 num_peers,
295 links_succeeded);
296 ctx->peers = peers;
297 for (unsigned int i = 0; i < num_peers; i++)
298 {
299 struct GNUNET_CADET_TEST_AdapterContext *newctx;
300
301 newctx = GNUNET_new (struct GNUNET_CADET_TEST_AdapterContext);
302 newctx->peer = i;
303 newctx->ctx = ctx;
304 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
305 "Connecting to cadet %u\n",
306 i);
307 ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx,
308 peers[i],
309 "cadet",
310 &cadet_connect_cb,
311 ctx,
312 &cadet_connect_adapter,
313 &cadet_disconnect_adapter,
314 newctx);
315 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
316 "op handle %p\n",
317 ctx->ops[i]);
318 }
319}
320
321
322/**
323 * Run a test using the given name, configuration file and number of peers.
324 * All cadet callbacks will receive the peer number (long) as the closure.
325 *
326 * @param testname Name of the test (for logging).
327 * @param cfgfile Name of the configuration file.
328 * @param num_peers Number of peers to start.
329 * @param tmain Main function to run once the testbed is ready.
330 * @param tmain_cls Closure for @a tmain.
331 * @param connects Handler for incoming channels.
332 * @param window_changes Handler for the window size change notification.
333 * @param disconnects Cleaner for destroyed incoming channels.
334 * @param handlers Message handlers.
335 * @param ports Ports the peers offer, NULL-terminated.
336 */
337void
338GNUNET_CADET_TEST_ruN (const char *testname,
339 const char *cfgfile,
340 unsigned int num_peers,
341 GNUNET_CADET_TEST_AppMain tmain,
342 void *tmain_cls,
343 GNUNET_CADET_ConnectEventHandler connects,
344 GNUNET_CADET_WindowSizeEventHandler window_changes,
345 GNUNET_CADET_DisconnectEventHandler disconnects,
346 struct GNUNET_MQ_MessageHandler *handlers,
347 const struct GNUNET_HashCode **ports)
348{
349 struct GNUNET_CADET_TEST_Context *ctx;
350
351 ctx = GNUNET_new (struct GNUNET_CADET_TEST_Context);
352 ctx->num_peers = num_peers;
353 ctx->ops = GNUNET_new_array (num_peers,
354 struct GNUNET_TESTBED_Operation *);
355 ctx->cadets = GNUNET_new_array (num_peers,
356 struct GNUNET_CADET_Handle *);
357 ctx->app_main = tmain;
358 ctx->app_main_cls = tmain_cls;
359 ctx->connects = connects;
360 ctx->window_changes = window_changes;
361 ctx->disconnects = disconnects;
362 ctx->handlers = GNUNET_MQ_copy_handlers (handlers);
363 ctx->ports = ports;
364 ctx->port_count = 0;
365 while (NULL != ctx->ports[ctx->port_count])
366 ctx->port_count++;
367 GNUNET_TESTBED_test_run (testname,
368 cfgfile,
369 num_peers,
370 0LL, NULL, NULL,
371 &cadet_test_run,
372 ctx);
373}
374
375
376/* end of cadet_test_lib.c */
diff --git a/src/service/cadet/cadet_test_lib.h b/src/service/cadet/cadet_test_lib.h
deleted file mode 100644
index 7d446801a..000000000
--- a/src/service/cadet/cadet_test_lib.h
+++ /dev/null
@@ -1,106 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012,2017 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file cadet/cadet_test_lib.h
22 * @author Bartlomiej Polot
23 * @brief library for writing CADET tests
24 */
25#ifndef CADET_TEST_LIB_H
26#define CADET_TEST_LIB_H
27
28#ifdef __cplusplus
29extern "C"
30{
31#if 0 /* keep Emacsens' auto-indent happy */
32}
33#endif
34#endif
35
36#include "gnunet_testbed_service.h"
37#include "gnunet_cadet_service.h"
38
39/**
40 * Test context for a CADET Test.
41 */
42struct GNUNET_CADET_TEST_Context;
43
44
45/**
46 * Main function of a CADET test.
47 *
48 * @param cls Closure.
49 * @param ctx Argument to give to GNUNET_CADET_TEST_cleanup on test end.
50 * @param num_peers Number of peers that are running.
51 * @param peers Array of peers.
52 * @param cadets Handle to each of the CADETs of the peers.
53 */
54typedef void (*GNUNET_CADET_TEST_AppMain) (void *cls,
55 struct GNUNET_CADET_TEST_Context *ctx,
56 unsigned int num_peers,
57 struct GNUNET_TESTBED_Peer **peers,
58 struct GNUNET_CADET_Handle **cadets);
59
60
61/**
62 * Run a test using the given name, configuration file and number of peers.
63 * All cadet callbacks will receive the peer number (long) as the closure.
64 *
65 * @param testname Name of the test (for logging).
66 * @param cfgfile Name of the configuration file.
67 * @param num_peers Number of peers to start.
68 * @param tmain Main function to run once the testbed is ready.
69 * @param tmain_cls Closure for @a tmain.
70 * @param connects Handler for incoming channels.
71 * @param window_changes Handler for the window size change notification.
72 * @param disconnects Cleaner for destroyed incoming channels.
73 * @param handlers Message handlers.
74 * @param ports Ports the peers offer, NULL-terminated.
75 */
76void
77GNUNET_CADET_TEST_ruN (const char *testname,
78 const char *cfgfile,
79 unsigned int num_peers,
80 GNUNET_CADET_TEST_AppMain tmain,
81 void *tmain_cls,
82 GNUNET_CADET_ConnectEventHandler connects,
83 GNUNET_CADET_WindowSizeEventHandler window_changes,
84 GNUNET_CADET_DisconnectEventHandler disconnects,
85 struct GNUNET_MQ_MessageHandler *handlers,
86 const struct GNUNET_HashCode **ports);
87
88/**
89 * Clean up the testbed.
90 *
91 * @param ctx handle for the testbed
92 */
93void
94GNUNET_CADET_TEST_cleanup (struct GNUNET_CADET_TEST_Context *ctx);
95
96
97#if 0 /* keep Emacsens' auto-indent happy */
98{
99#endif
100#ifdef __cplusplus
101}
102#endif
103
104
105/* ifndef CADET_TEST_LIB_H */
106#endif
diff --git a/src/service/dht/dht_test_lib.c b/src/service/dht/dht_test_lib.c
deleted file mode 100644
index 29c5088d1..000000000
--- a/src/service/dht/dht_test_lib.c
+++ /dev/null
@@ -1,202 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file dht/dht_test_lib.c
22 * @author Christian Grothoff
23 * @brief library for writing DHT tests
24 */
25#include "platform.h"
26#include "dht_test_lib.h"
27
28/**
29 * Test context for a DHT Test.
30 */
31struct GNUNET_DHT_TEST_Context
32{
33 /**
34 * Array of running peers.
35 */
36 struct GNUNET_TESTBED_Peer **peers;
37
38 /**
39 * Array of handles to the DHT for each peer.
40 */
41 struct GNUNET_DHT_Handle **dhts;
42
43 /**
44 * Operation associated with the connection to the DHT.
45 */
46 struct GNUNET_TESTBED_Operation **ops;
47
48 /**
49 * Main function of the test to run once all DHTs are available.
50 */
51 GNUNET_DHT_TEST_AppMain app_main;
52
53 /**
54 * Closure for 'app_main'.
55 */
56 void *app_main_cls;
57
58 /**
59 * Number of peers running, size of the arrays above.
60 */
61 unsigned int num_peers;
62};
63
64
65/**
66 * Adapter function called to establish a connection to
67 * the DHT service.
68 *
69 * @param cls closure
70 * @param cfg configuration of the peer to connect to; will be available until
71 * GNUNET_TESTBED_operation_done() is called on the operation returned
72 * from GNUNET_TESTBED_service_connect()
73 * @return service handle to return in 'op_result', NULL on error
74 */
75static void *
76dht_connect_adapter (void *cls,
77 const struct GNUNET_CONFIGURATION_Handle *cfg)
78{
79 return GNUNET_DHT_connect (cfg, 16);
80}
81
82
83/**
84 * Adapter function called to destroy a connection to
85 * the DHT service.
86 *
87 * @param cls closure
88 * @param op_result service handle returned from the connect adapter
89 */
90static void
91dht_disconnect_adapter (void *cls,
92 void *op_result)
93{
94 struct GNUNET_DHT_Handle *dht = op_result;
95
96 GNUNET_DHT_disconnect (dht);
97}
98
99
100/**
101 * Callback to be called when a service connect operation is completed
102 *
103 * @param cls the callback closure from functions generating an operation
104 * @param op the operation that has been finished
105 * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
106 * @param emsg error message in case the operation has failed; will be NULL if
107 * operation has executed successfully.
108 */
109static void
110dht_connect_cb (void *cls,
111 struct GNUNET_TESTBED_Operation *op,
112 void *ca_result,
113 const char *emsg)
114{
115 struct GNUNET_DHT_TEST_Context *ctx = cls;
116
117 if (NULL != emsg)
118 {
119 fprintf (stderr,
120 "Failed to connect to DHT service: %s\n",
121 emsg);
122 GNUNET_SCHEDULER_shutdown ();
123 return;
124 }
125 for (unsigned int i = 0; i < ctx->num_peers; i++)
126 if (op == ctx->ops[i])
127 ctx->dhts[i] = ca_result;
128 for (unsigned int i = 0; i < ctx->num_peers; i++)
129 if (NULL == ctx->dhts[i])
130 return;
131 /* still some DHT connections missing */
132 /* all DHT connections ready! */
133 ctx->app_main (ctx->app_main_cls,
134 ctx,
135 ctx->num_peers,
136 ctx->peers,
137 ctx->dhts);
138}
139
140
141void
142GNUNET_DHT_TEST_cleanup (struct GNUNET_DHT_TEST_Context *ctx)
143{
144 for (unsigned int i = 0; i < ctx->num_peers; i++)
145 GNUNET_TESTBED_operation_done (ctx->ops[i]);
146 GNUNET_free (ctx->ops);
147 GNUNET_free (ctx->dhts);
148 GNUNET_free (ctx);
149 GNUNET_SCHEDULER_shutdown ();
150}
151
152
153static void
154dht_test_run (void *cls,
155 struct GNUNET_TESTBED_RunHandle *h,
156 unsigned int num_peers,
157 struct GNUNET_TESTBED_Peer **peers,
158 unsigned int links_succeeded,
159 unsigned int links_failed)
160{
161 struct GNUNET_DHT_TEST_Context *ctx = cls;
162
163 GNUNET_assert (num_peers == ctx->num_peers);
164 ctx->peers = peers;
165 for (unsigned int i = 0; i < num_peers; i++)
166 ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx,
167 peers[i],
168 "dht",
169 &dht_connect_cb,
170 ctx,
171 &dht_connect_adapter,
172 &dht_disconnect_adapter,
173 ctx);
174}
175
176
177void
178GNUNET_DHT_TEST_run (const char *testname,
179 const char *cfgname,
180 unsigned int num_peers,
181 GNUNET_DHT_TEST_AppMain tmain,
182 void *tmain_cls)
183{
184 struct GNUNET_DHT_TEST_Context *ctx;
185
186 ctx = GNUNET_new (struct GNUNET_DHT_TEST_Context);
187 ctx->num_peers = num_peers;
188 ctx->ops = GNUNET_new_array (num_peers,
189 struct GNUNET_TESTBED_Operation *);
190 ctx->dhts = GNUNET_new_array (num_peers,
191 struct GNUNET_DHT_Handle *);
192 ctx->app_main = tmain;
193 ctx->app_main_cls = tmain_cls;
194 (void) GNUNET_TESTBED_test_run (testname,
195 cfgname,
196 num_peers,
197 0LL, NULL, NULL,
198 &dht_test_run, ctx);
199}
200
201
202/* end of dht_test_lib.c */
diff --git a/src/service/dht/dht_test_lib.h b/src/service/dht/dht_test_lib.h
deleted file mode 100644
index efffc9ef7..000000000
--- a/src/service/dht/dht_test_lib.h
+++ /dev/null
@@ -1,95 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file dht/dht_test_lib.h
22 * @author Christian Grothoff
23 * @brief library for writing DHT tests
24 */
25#ifndef DHT_TEST_LIB_H
26#define DHT_TEST_LIB_H
27
28#ifdef __cplusplus
29extern "C"
30{
31#if 0 /* keep Emacsens' auto-indent happy */
32}
33#endif
34#endif
35
36#include "gnunet_testbed_service.h"
37#include "gnunet_dht_service.h"
38
39/**
40 * Test context for a DHT Test.
41 */
42struct GNUNET_DHT_TEST_Context;
43
44
45/**
46 * Main function of a DHT test.
47 *
48 * @param cls closure
49 * @param ctx argument to give to GNUNET_DHT_TEST_cleanup on test end
50 * @param num_peers number of peers that are running
51 * @param peers array of peers
52 * @param dhts handle to each of the DHTs of the peers
53 */
54typedef void (*GNUNET_DHT_TEST_AppMain) (void *cls,
55 struct GNUNET_DHT_TEST_Context *ctx,
56 unsigned int num_peers,
57 struct GNUNET_TESTBED_Peer **peers,
58 struct GNUNET_DHT_Handle **dhts);
59
60
61/**
62 * Run a test using the given name, configuration file and number of
63 * peers.
64 *
65 * @param testname name of the test (for logging)
66 * @param cfgname name of the configuration file
67 * @param num_peers number of peers to start
68 * @param tmain main function to run once the testbed is ready
69 * @param tmain_cls closure for 'tmain'
70 */
71void
72GNUNET_DHT_TEST_run (const char *testname,
73 const char *cfgname,
74 unsigned int num_peers,
75 GNUNET_DHT_TEST_AppMain tmain,
76 void *tmain_cls);
77
78
79/**
80 * Clean up the testbed.
81 *
82 * @param ctx handle for the testbed
83 */
84void
85GNUNET_DHT_TEST_cleanup (struct GNUNET_DHT_TEST_Context *ctx);
86
87#if 0 /* keep Emacsens' auto-indent happy */
88{
89#endif
90#ifdef __cplusplus
91}
92#endif
93
94/* ifndef DHT_TEST_LIB_H */
95#endif
diff --git a/src/service/dht/test_dht_monitor.c b/src/service/dht/test_dht_monitor.c
deleted file mode 100644
index 3960a2235..000000000
--- a/src/service/dht/test_dht_monitor.c
+++ /dev/null
@@ -1,439 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011, 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file dht/test_dht_monitor.c
22 * @brief Test for the dht monitoring API; checks that we receive "some" monitor events
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet_testbed_service.h"
27#include "gnunet_dht_service.h"
28#include "dht_test_lib.h"
29
30
31/**
32 * How long do we run the test at most?
33 */
34#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
35
36/**
37 * How often do we run the PUTs?
38 */
39#define PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \
40 10)
41
42
43/**
44 * Information we keep for each GET operation.
45 */
46struct GetOperation
47{
48 /**
49 * DLL.
50 */
51 struct GetOperation *next;
52
53 /**
54 * DLL.
55 */
56 struct GetOperation *prev;
57
58 /**
59 * Handle for the operation.
60 */
61 struct GNUNET_DHT_GetHandle *get;
62};
63
64
65/**
66 * Return value from 'main'.
67 */
68static int ok;
69
70/**
71 * Head of list of active GET operations.
72 */
73static struct GetOperation *get_head;
74
75/**
76 * Tail of list of active GET operations.
77 */
78static struct GetOperation *get_tail;
79
80/**
81 * Array of the testbed's peers.
82 */
83static struct GNUNET_TESTBED_Peer **my_peers;
84
85/**
86 * Number of peers to run.
87 */
88static unsigned int NUM_PEERS = 3;
89
90/**
91 * Task called to disconnect peers.
92 */
93static struct GNUNET_SCHEDULER_Task *timeout_task;
94
95/**
96 * Task to do DHT_puts
97 */
98static struct GNUNET_SCHEDULER_Task *put_task;
99
100static struct GNUNET_DHT_MonitorHandle **monitors;
101
102static unsigned int monitor_counter;
103
104
105/**
106 * Task run on success or timeout to clean up.
107 * Terminates active get operations and shuts down
108 * the testbed.
109 *
110 * @param cls the `struct GNUNET_DHT_TEST_Context`
111 */
112static void
113shutdown_task (void *cls)
114{
115 struct GNUNET_DHT_TEST_Context *ctx = cls;
116 unsigned int i;
117 struct GetOperation *get_op;
118
119 ok = (monitor_counter > NUM_PEERS) ? 0 : 2;
120 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
121 "Received %u monitor events\n",
122 monitor_counter);
123 while (NULL != (get_op = get_tail))
124 {
125 GNUNET_DHT_get_stop (get_op->get);
126 GNUNET_CONTAINER_DLL_remove (get_head,
127 get_tail,
128 get_op);
129 GNUNET_free (get_op);
130 }
131 for (i = 0; i < NUM_PEERS; i++)
132 GNUNET_DHT_monitor_stop (monitors[i]);
133 GNUNET_free (monitors);
134 GNUNET_SCHEDULER_cancel (put_task);
135 GNUNET_DHT_TEST_cleanup (ctx);
136 if (NULL != timeout_task)
137 {
138 GNUNET_SCHEDULER_cancel (timeout_task);
139 timeout_task = NULL;
140 }
141}
142
143
144/**
145 * Task run on success or timeout to clean up.
146 * Terminates active get operations and shuts down
147 * the testbed.
148 *
149 * @param cls NULL
150 */
151static void
152timeout_task_cb (void *cls)
153{
154 timeout_task = NULL;
155 GNUNET_SCHEDULER_shutdown ();
156}
157
158
159/**
160 * Iterator called on each result obtained for a DHT
161 * operation that expects a reply
162 *
163 * @param cls closure with our 'struct GetOperation'
164 * @param exp when will this value expire
165 * @param key key of the result
166 * @param trunc_peer peer the path was truncated at, or NULL
167 * @param get_path peers on reply path (or NULL if not recorded)
168 * @param get_path_length number of entries in get_path
169 * @param put_path peers on the PUT path (or NULL if not recorded)
170 * @param put_path_length number of entries in get_path
171 * @param type type of the result
172 * @param size number of bytes in data
173 * @param data pointer to the result data
174 */
175static void
176dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp,
177 const struct GNUNET_HashCode *key,
178 const struct GNUNET_PeerIdentity *trunc_peer,
179 const struct GNUNET_DHT_PathElement *get_path,
180 unsigned int get_path_length,
181 const struct GNUNET_DHT_PathElement *put_path,
182 unsigned int put_path_length,
183 enum GNUNET_BLOCK_Type type,
184 size_t size, const void *data)
185{
186 struct GetOperation *get_op = cls;
187 struct GNUNET_HashCode want;
188
189 if (sizeof(struct GNUNET_HashCode) != size)
190 {
191 GNUNET_break (0);
192 return;
193 }
194 GNUNET_CRYPTO_hash (key,
195 sizeof(*key),
196 &want);
197 if (0 != memcmp (&want, data, sizeof(want)))
198 {
199 GNUNET_break (0);
200 return;
201 }
202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
203 "Get successful\n");
204 GNUNET_DHT_get_stop (get_op->get);
205 GNUNET_CONTAINER_DLL_remove (get_head,
206 get_tail,
207 get_op);
208 GNUNET_free (get_op);
209 if (NULL != get_head)
210 return;
211 /* all DHT GET operations successful; terminate! */
212 ok = 0;
213 GNUNET_SCHEDULER_shutdown ();
214}
215
216
217/**
218 * Task to put the id of each peer into the DHT.
219 *
220 * @param cls array with NUM_PEERS DHT handles
221 */
222static void
223do_puts (void *cls)
224{
225 struct GNUNET_DHT_Handle **hs = cls;
226 struct GNUNET_HashCode key;
227 struct GNUNET_HashCode value;
228
229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
230 "Putting values into DHT\n");
231 for (unsigned int i = 0; i < NUM_PEERS; i++)
232 {
233 GNUNET_CRYPTO_hash (&i, sizeof(i), &key);
234 GNUNET_CRYPTO_hash (&key, sizeof(key), &value);
235 GNUNET_DHT_put (hs[i], &key, 10U,
236 GNUNET_DHT_RO_RECORD_ROUTE
237 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
238 GNUNET_BLOCK_TYPE_TEST,
239 sizeof(value), &value,
240 GNUNET_TIME_UNIT_FOREVER_ABS,
241 NULL, NULL);
242 }
243 put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY,
244 &do_puts, hs);
245}
246
247
248/**
249 * Callback called on each GET request going through the DHT.
250 * Prints the info about the intercepted packet and increments a counter.
251 *
252 * @param cls Closure.
253 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
254 * @param type The type of data in the request.
255 * @param hop_count Hop count so far.
256 * @param desired_replication_level Desired replication level.
257 * @param key Key of the requested data.
258 */
259static void
260monitor_get_cb (void *cls,
261 enum GNUNET_DHT_RouteOption options,
262 enum GNUNET_BLOCK_Type type,
263 uint32_t hop_count,
264 uint32_t desired_replication_level,
265 const struct GNUNET_HashCode *key)
266{
267 unsigned int i;
268
269 i = (unsigned int) (long) cls;
270 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
271 "%u got a GET message for key %s\n",
272 i,
273 GNUNET_h2s (key));
274 monitor_counter++;
275}
276
277
278/**
279 * Callback called on each PUT request going through the DHT.
280 * Prints the info about the intercepted packet and increments a counter.
281 *
282 * @param cls Closure.
283 * @param options Options, for instance RecordRoute, DemultiplexEverywhere.
284 * @param type The type of data in the request.
285 * @param hop_count Hop count so far.
286 * @param trunc_peer peer the path was truncated at, or NULL
287 * @param path_length number of entries in path (or 0 if not recorded).
288 * @param path peers on the PUT path (or NULL if not recorded).
289 * @param desired_replication_level Desired replication level.
290 * @param exp Expiration time of the data.
291 * @param key Key under which data is to be stored.
292 * @param data Pointer to the data carried.
293 * @param size Number of bytes in data.
294 */
295static void
296monitor_put_cb (void *cls,
297 enum GNUNET_DHT_RouteOption options,
298 enum GNUNET_BLOCK_Type type,
299 uint32_t hop_count,
300 uint32_t desired_replication_level,
301 const struct GNUNET_PeerIdentity *trunc_peer,
302 unsigned int path_length,
303 const struct GNUNET_DHT_PathElement *path,
304 struct GNUNET_TIME_Absolute exp,
305 const struct GNUNET_HashCode *key,
306 const void *data,
307 size_t size)
308{
309 unsigned int i;
310
311 i = (unsigned int) (long) cls;
312 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
313 "%u got a PUT message for key %s with %u bytes\n",
314 i,
315 GNUNET_h2s (key),
316 (unsigned int) size);
317 monitor_counter++;
318}
319
320
321/**
322 * Callback called on each GET reply going through the DHT.
323 * Prints the info about the intercepted packet and increments a counter.
324 *
325 * @param cls Closure.
326 * @param type The type of data in the result.
327 * @param trunc_peer peer the path was truncated at, or NULL
328 * @param get_path Peers on GET path (or NULL if not recorded).
329 * @param get_path_length number of entries in get_path.
330 * @param put_path peers on the PUT path (or NULL if not recorded).
331 * @param put_path_length number of entries in get_path.
332 * @param exp Expiration time of the data.
333 * @param key Key of the data.
334 * @param data Pointer to the result data.
335 * @param size Number of bytes in data.
336 */
337static void
338monitor_res_cb (void *cls,
339 enum GNUNET_BLOCK_Type type,
340 const struct GNUNET_PeerIdentity *trunc_peer,
341 const struct GNUNET_DHT_PathElement *get_path,
342 unsigned int get_path_length,
343 const struct GNUNET_DHT_PathElement *put_path,
344 unsigned int put_path_length,
345 struct GNUNET_TIME_Absolute exp,
346 const struct GNUNET_HashCode *key,
347 const void *data,
348 size_t size)
349{
350 unsigned int i;
351
352 i = (unsigned int) (long) cls;
353 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
354 "%u got a REPLY message for key %s with %u bytes\n",
355 i,
356 GNUNET_h2s (key),
357 (unsigned int) size);
358 monitor_counter++;
359}
360
361
362/**
363 * Main function of the test.
364 *
365 * @param cls closure (NULL)
366 * @param ctx argument to give to GNUNET_DHT_TEST_cleanup on test end
367 * @param num_peers number of peers that are running
368 * @param peers array of peers
369 * @param dhts handle to each of the DHTs of the peers
370 */
371static void
372run (void *cls,
373 struct GNUNET_DHT_TEST_Context *ctx,
374 unsigned int num_peers,
375 struct GNUNET_TESTBED_Peer **peers,
376 struct GNUNET_DHT_Handle **dhts)
377{
378 unsigned int i;
379 unsigned int j;
380 struct GNUNET_HashCode key;
381 struct GetOperation *get_op;
382
383 GNUNET_assert (NUM_PEERS == num_peers);
384 my_peers = peers;
385 monitors = GNUNET_new_array (num_peers,
386 struct GNUNET_DHT_MonitorHandle *);
387 for (i = 0; i < num_peers; i++)
388 monitors[i] = GNUNET_DHT_monitor_start (dhts[i],
389 GNUNET_BLOCK_TYPE_ANY,
390 NULL,
391 &monitor_get_cb,
392 &monitor_res_cb,
393 &monitor_put_cb,
394 (void *) (long) i);
395 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
396 "Peers setup, starting test\n");
397 put_task = GNUNET_SCHEDULER_add_now (&do_puts, dhts);
398 for (i = 0; i < num_peers; i++)
399 {
400 GNUNET_CRYPTO_hash (&i, sizeof(i), &key);
401 for (j = 0; j < num_peers; j++)
402 {
403 get_op = GNUNET_new (struct GetOperation);
404 GNUNET_CONTAINER_DLL_insert (get_head,
405 get_tail,
406 get_op);
407 get_op->get = GNUNET_DHT_get_start (dhts[j],
408 GNUNET_BLOCK_TYPE_TEST, /* type */
409 &key, /*key to search */
410 4U, /* replication level */
411 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
412 NULL, /* xquery */
413 0, /* xquery bits */
414 &dht_get_handler, get_op);
415 }
416 }
417 timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
418 &timeout_task_cb,
419 NULL);
420 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
421 ctx);
422}
423
424
425/**
426 * Main: start test
427 */
428int
429main (int xargc, char *xargv[])
430{
431 GNUNET_DHT_TEST_run ("test-dht-monitor",
432 "test_dht_monitor.conf",
433 NUM_PEERS,
434 &run, NULL);
435 return ok;
436}
437
438
439/* end of test_dht_monitor.c */
diff --git a/src/service/dht/test_dht_monitor.conf b/src/service/dht/test_dht_monitor.conf
deleted file mode 100644
index 703065f00..000000000
--- a/src/service/dht/test_dht_monitor.conf
+++ /dev/null
@@ -1,39 +0,0 @@
1@INLINE@ ../../../contrib/conf/gnunet/no_forcestart.conf
2@INLINE@ ../../../contrib/conf/gnunet/no_autostart_above_core.conf
3
4
5[dhtcache]
6QUOTA = 1 MB
7DATABASE = heap
8
9[transport]
10PLUGINS = tcp
11
12[ats]
13WAN_QUOTA_IN = 1 GB
14WAN_QUOTA_OUT = 1 GB
15
16[testbed]
17OVERLAY_TOPOLOGY = LINE
18
19[PATHS]
20GNUNET_TEST_HOME = $GNUNET_TMP/test-dht-monitor/
21
22[nat]
23DISABLEV6 = YES
24ENABLE_UPNP = NO
25BEHIND_NAT = NO
26ALLOW_NAT = NO
27INTERNAL_ADDRESS = 127.0.0.1
28EXTERNAL_ADDRESS = 127.0.0.1
29USE_LOCALADDR = YES
30RETURN_LOCAL_ADDRESSES = YES
31
32
33[dht]
34START_ON_DEMAND = YES
35IMMEDIATE_START = YES
36
37[nse]
38START_ON_DEMAND = YES
39WORKBITS = 1
diff --git a/src/service/dht/test_dht_topo.c b/src/service/dht/test_dht_topo.c
deleted file mode 100644
index a8294c65d..000000000
--- a/src/service/dht/test_dht_topo.c
+++ /dev/null
@@ -1,637 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2016 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file dht/test_dht_topo.c
22 * @author Christian Grothoff
23 * @brief Test for the dht service: store and retrieve in various topologies.
24 * Each peer stores a value from the DHT and then each peer tries to get each
25 * value from each other peer.
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_dht_service.h"
30#include "dht_test_lib.h"
31
32/**
33 * How long until we give up on fetching the data?
34 */
35#define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \
36 120)
37
38/**
39 * How frequently do we execute the PUTs?
40 */
41#define PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \
42 5)
43
44
45/**
46 * Information we keep for each GET operation.
47 */
48struct GetOperation
49{
50 /**
51 * DLL.
52 */
53 struct GetOperation *next;
54
55 /**
56 * DLL.
57 */
58 struct GetOperation *prev;
59
60 /**
61 * Operation to fetch @a me.
62 */
63 struct GNUNET_TESTBED_Operation *to;
64
65 /**
66 * Handle for the operation.
67 */
68 struct GNUNET_DHT_GetHandle *get;
69
70 /**
71 * DHT used by this operation.
72 */
73 struct GNUNET_DHT_Handle *dht;
74
75 /**
76 * Key we are looking up.
77 */
78 struct GNUNET_HashCode key;
79
80 /**
81 * At which peer is this operation being performed?
82 */
83 struct GNUNET_PeerIdentity me;
84};
85
86
87/**
88 * Result of the test.
89 */
90static int ok;
91
92/**
93 * Task to do DHT_puts
94 */
95static struct GNUNET_SCHEDULER_Task *put_task;
96
97/**
98 * Task to do DHT_gets
99 */
100static struct GNUNET_SCHEDULER_Task *get_task;
101
102/**
103 * Task to time out / regular shutdown.
104 */
105static struct GNUNET_SCHEDULER_Task *timeout_task;
106
107/**
108 * Head of list of active GET operations.
109 */
110static struct GetOperation *get_head;
111
112/**
113 * Tail of list of active GET operations.
114 */
115static struct GetOperation *get_tail;
116
117/**
118 * Array of the testbed's peers.
119 */
120static struct GNUNET_TESTBED_Peer **my_peers;
121
122/**
123 * Number of peers to run.
124 */
125static unsigned int NUM_PEERS;
126
127
128/**
129 * Statistics we print out.
130 */
131static struct
132{
133 const char *subsystem;
134 const char *name;
135 unsigned long long total;
136} stats[] = {
137 { "core", "# bytes decrypted", 0 },
138 { "core", "# bytes encrypted", 0 },
139 { "core", "# type maps received", 0 },
140 { "core", "# session keys confirmed via PONG", 0 },
141 { "core", "# peers connected", 0 },
142 { "core", "# key exchanges initiated", 0 },
143 { "core", "# send requests dropped (disconnected)", 0 },
144 { "core", "# transmissions delayed due to corking", 0 },
145 { "core", "# messages discarded (expired prior to transmission)", 0 },
146 { "core", "# messages discarded (disconnected)", 0 },
147 { "core", "# discarded CORE_SEND requests", 0 },
148 { "core", "# discarded lower priority CORE_SEND requests", 0 },
149 { "transport", "# bytes received via TCP", 0 },
150 { "transport", "# bytes transmitted via TCP", 0 },
151 { "dht", "# PUT messages queued for transmission", 0 },
152 { "dht", "# P2P PUT requests received", 0 },
153 { "dht", "# GET messages queued for transmission", 0 },
154 { "dht", "# P2P GET requests received", 0 },
155 { "dht", "# RESULT messages queued for transmission", 0 },
156 { "dht", "# P2P RESULTS received", 0 },
157 { "dht", "# Queued messages discarded (peer disconnected)", 0 },
158 { "dht", "# Peers excluded from routing due to Bloomfilter", 0 },
159 { "dht", "# Peer selection failed", 0 },
160 { "dht", "# FIND PEER requests ignored due to Bloomfilter", 0 },
161 { "dht", "# FIND PEER requests ignored due to lack of HELLO", 0 },
162 { "dht", "# P2P FIND PEER requests processed", 0 },
163 { "dht", "# P2P GET requests ONLY routed", 0 },
164 { "dht", "# Preference updates given to core", 0 },
165 { "dht", "# REPLIES ignored for CLIENTS (no match)", 0 },
166 { "dht", "# GET requests from clients injected", 0 },
167 { "dht", "# GET requests received from clients", 0 },
168 { "dht", "# GET STOP requests received from clients", 0 },
169 { "dht", "# ITEMS stored in datacache", 0 },
170 { "dht", "# Good RESULTS found in datacache", 0 },
171 { "dht", "# GET requests given to datacache", 0 },
172 { NULL, NULL, 0 }
173};
174
175
176static struct GNUNET_DHT_TEST_Context *
177stop_ops (void)
178{
179 struct GetOperation *get_op;
180 struct GNUNET_DHT_TEST_Context *ctx = NULL;
181
182 if (NULL != timeout_task)
183 {
184 ctx = GNUNET_SCHEDULER_cancel (timeout_task);
185 timeout_task = NULL;
186 }
187 if (NULL != put_task)
188 {
189 GNUNET_SCHEDULER_cancel (put_task);
190 put_task = NULL;
191 }
192 if (NULL != get_task)
193 {
194 GNUNET_SCHEDULER_cancel (get_task);
195 get_task = NULL;
196 }
197 while (NULL != (get_op = get_tail))
198 {
199 if (NULL != get_op->to)
200 {
201 GNUNET_TESTBED_operation_done (get_op->to);
202 get_op->to = NULL;
203 }
204 if (NULL != get_op->get)
205 {
206 GNUNET_DHT_get_stop (get_op->get);
207 get_op->get = NULL;
208 }
209 GNUNET_CONTAINER_DLL_remove (get_head,
210 get_tail,
211 get_op);
212 GNUNET_free (get_op);
213 }
214 return ctx;
215}
216
217
218/**
219 * Function called once we're done processing stats.
220 *
221 * @param cls the test context
222 * @param op the stats operation
223 * @param emsg error message on failure
224 */
225static void
226stats_finished (void *cls,
227 struct GNUNET_TESTBED_Operation *op,
228 const char *emsg)
229{
230 struct GNUNET_DHT_TEST_Context *ctx = cls;
231
232 if (NULL != op)
233 GNUNET_TESTBED_operation_done (op);
234 if (NULL != emsg)
235 {
236 fprintf (stderr,
237 _ ("Gathering statistics failed: %s\n"),
238 emsg);
239 GNUNET_SCHEDULER_cancel (put_task);
240 GNUNET_DHT_TEST_cleanup (ctx);
241 return;
242 }
243 for (unsigned int i = 0; NULL != stats[i].name; i++)
244 fprintf (stderr,
245 "%6s/%60s = %12llu\n",
246 stats[i].subsystem,
247 stats[i].name,
248 stats[i].total);
249 GNUNET_DHT_TEST_cleanup (ctx);
250 GNUNET_SCHEDULER_shutdown ();
251}
252
253
254/**
255 * Function called to process statistic values from all peers.
256 *
257 * @param cls closure
258 * @param peer the peer the statistic belong to
259 * @param subsystem name of subsystem that created the statistic
260 * @param name the name of the datum
261 * @param value the current value
262 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
263 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
264 */
265static enum GNUNET_GenericReturnValue
266handle_stats (void *cls,
267 const struct GNUNET_TESTBED_Peer *peer,
268 const char *subsystem,
269 const char *name,
270 uint64_t value,
271 int is_persistent)
272{
273 for (unsigned int i = 0; NULL != stats[i].name; i++)
274 if ((0 == strcasecmp (subsystem,
275 stats[i].subsystem)) &&
276 (0 == strcasecmp (name,
277 stats[i].name)))
278 stats[i].total += value;
279 return GNUNET_OK;
280}
281
282
283/**
284 * Task run on shutdown to clean up. Terminates active get operations
285 * and shuts down the testbed.
286 *
287 * @param cls the 'struct GNUNET_DHT_TestContext'
288 */
289static void
290shutdown_task (void *cls)
291{
292 struct GNUNET_DHT_TEST_Context *ctx;
293
294 (void) cls;
295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
296 "Performing shutdown\n");
297 ctx = stop_ops ();
298 if (NULL != ctx)
299 GNUNET_DHT_TEST_cleanup (ctx);
300}
301
302
303/**
304 * Task run on timeout to clean up. Terminates active get operations
305 * and shuts down the testbed.
306 *
307 * @param cls the `struct GNUNET_DHT_TestContext`
308 */
309static void
310timeout_cb (void *cls)
311{
312 struct GNUNET_DHT_TEST_Context *ctx = cls;
313
314 timeout_task = GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT,
315 &timeout_cb,
316 ctx);
317 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
318 "Timeout\n");
319 GNUNET_SCHEDULER_shutdown ();
320}
321
322
323/**
324 * Iterator called on each result obtained for a DHT
325 * operation that expects a reply
326 *
327 * @param cls closure with our 'struct GetOperation'
328 * @param exp when will this value expire
329 * @param query query hash
330 * @param trunc_peer peer the path was truncated at, or NULL
331 * @param get_path peers on reply path (or NULL if not recorded)
332 * @param get_path_length number of entries in @a get_path
333 * @param put_path peers on the PUT path (or NULL if not recorded)
334 * @param put_path_length number of entries in @a put_path
335 * @param type type of the result
336 * @param size number of bytes in @a data
337 * @param data pointer to the result data
338 */
339static void
340dht_get_handler (void *cls,
341 struct GNUNET_TIME_Absolute exp,
342 const struct GNUNET_HashCode *query,
343 const struct GNUNET_PeerIdentity *trunc_peer,
344 const struct GNUNET_DHT_PathElement *get_path,
345 unsigned int get_path_length,
346 const struct GNUNET_DHT_PathElement *put_path,
347 unsigned int put_path_length,
348 enum GNUNET_BLOCK_Type type,
349 size_t size,
350 const void *data)
351{
352 struct GetOperation *get_op = cls;
353 struct GNUNET_HashCode want;
354 struct GNUNET_DHT_TEST_Context *ctx;
355
356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
357 "GET HANDLER called on PID %s\n",
358 GNUNET_i2s (&get_op->me));
359 if (sizeof(struct GNUNET_HashCode) != size)
360 {
361 GNUNET_break (0);
362 return;
363 }
364 if (0 != GNUNET_memcmp (query,
365 &get_op->key))
366 {
367 /* exact search should only yield exact results */
368 GNUNET_break (0);
369 return;
370 }
371 GNUNET_CRYPTO_hash (query,
372 sizeof(*query),
373 &want);
374 if (0 != memcmp (&want,
375 data,
376 sizeof(want)))
377 {
378 GNUNET_break (0);
379 return;
380 }
381 if (0 !=
382 GNUNET_DHT_verify_path (data,
383 size,
384 exp,
385 trunc_peer,
386 put_path,
387 put_path_length,
388 get_path,
389 get_path_length,
390 &get_op->me))
391 {
392 GNUNET_break (0);
393 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
394 "Path signature (%u/%u) verification failed for peer %s!\n",
395 get_path_length,
396 put_path_length,
397 GNUNET_i2s (&get_op->me));
398 }
399 else
400 {
401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
402 "Get successful\n");
403 ok--;
404 }
405 GNUNET_DHT_get_stop (get_op->get);
406 GNUNET_CONTAINER_DLL_remove (get_head,
407 get_tail,
408 get_op);
409 GNUNET_free (get_op);
410 if (NULL != get_head)
411 return;
412 /* all DHT GET operations successful; get stats! */
413 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
414 "All DHT operations successful. Obtaining stats!\n");
415 ctx = stop_ops ();
416 GNUNET_assert (NULL != ctx);
417 (void) GNUNET_TESTBED_get_statistics (NUM_PEERS,
418 my_peers,
419 NULL, NULL,
420 &handle_stats,
421 &stats_finished,
422 ctx);
423}
424
425
426/**
427 * Task to put the id of each peer into the DHT.
428 *
429 * @param cls array with NUM_PEERS DHT handles
430 * @param tc Task context
431 */
432static void
433do_puts (void *cls)
434{
435 struct GNUNET_DHT_Handle **hs = cls;
436 struct GNUNET_HashCode key;
437 struct GNUNET_HashCode value;
438
439 put_task = NULL;
440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
441 "Putting %u values into DHT\n",
442 NUM_PEERS);
443 for (unsigned int i = 0; i < NUM_PEERS; i++)
444 {
445 GNUNET_CRYPTO_hash (&i,
446 sizeof(i),
447 &key);
448 GNUNET_CRYPTO_hash (&key,
449 sizeof(key),
450 &value);
451 GNUNET_DHT_put (hs[i],
452 &key,
453 10U,
454 GNUNET_DHT_RO_RECORD_ROUTE
455 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
456 GNUNET_BLOCK_TYPE_TEST,
457 sizeof(value),
458 &value,
459 GNUNET_TIME_UNIT_FOREVER_ABS,
460 NULL,
461 NULL);
462 }
463 put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY,
464 &do_puts,
465 hs);
466}
467
468
469/**
470 * Callback to be called when the requested peer information is available
471 * The peer information in the callback is valid until the operation 'op' is canceled.
472 *
473 * @param cls a `struct GetOperation *`
474 * @param op the operation this callback corresponds to
475 * @param pinfo the result; will be NULL if the operation has failed
476 * @param emsg error message if the operation has failed; will be NULL if the
477 * operation is successful
478 */
479static void
480pid_cb (void *cls,
481 struct GNUNET_TESTBED_Operation *op,
482 const struct GNUNET_TESTBED_PeerInformation *pinfo,
483 const char *emsg)
484{
485 struct GetOperation *get_op = cls;
486
487 if (NULL != emsg)
488 {
489 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
490 "Testbed failure: %s\n",
491 emsg);
492 GNUNET_TESTBED_operation_done (get_op->to);
493 get_op->to = NULL;
494 GNUNET_SCHEDULER_shutdown ();
495 return;
496 }
497 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
498 "Testbed provided PID %s\n",
499 GNUNET_i2s (pinfo->result.id));
500 get_op->me = *pinfo->result.id;
501 GNUNET_TESTBED_operation_done (get_op->to);
502 get_op->to = NULL;
503 get_op->get = GNUNET_DHT_get_start (get_op->dht,
504 GNUNET_BLOCK_TYPE_TEST,
505 &get_op->key,
506 4U, /* replication level */
507 GNUNET_DHT_RO_RECORD_ROUTE
508 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
509 NULL, /* xquery */
510 0, /* xquery bits */
511 &dht_get_handler,
512 get_op);
513}
514
515
516/**
517 * Start GET operations.
518 */
519static void
520start_get (void *cls)
521{
522 struct GNUNET_DHT_Handle **dhts = cls;
523
524 get_task = NULL;
525 for (unsigned int i = 0; i < NUM_PEERS; i++)
526 {
527 struct GNUNET_HashCode key;
528
529 GNUNET_CRYPTO_hash (&i,
530 sizeof(i),
531 &key);
532 for (unsigned int j = 0; j < NUM_PEERS; j++)
533 {
534 struct GetOperation *get_op;
535
536 get_op = GNUNET_new (struct GetOperation);
537 ok++;
538 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
539 "Starting GET %p\n",
540 get_op);
541 get_op->key = key;
542 get_op->dht = dhts[j];
543 get_op->to = GNUNET_TESTBED_peer_get_information (my_peers[j],
544 GNUNET_TESTBED_PIT_IDENTITY,
545 &pid_cb,
546 get_op);
547 GNUNET_CONTAINER_DLL_insert (get_head,
548 get_tail,
549 get_op);
550 }
551 }
552}
553
554
555/**
556 * Main function of the test.
557 *
558 * @param cls closure (NULL)
559 * @param ctx argument to give to #GNUNET_DHT_TEST_cleanup on test end
560 * @param num_peers number of @a peers that are running
561 * @param peers array of peers
562 * @param dhts handle to each of the DHTs of the peers
563 */
564static void
565run (void *cls,
566 struct GNUNET_DHT_TEST_Context *ctx,
567 unsigned int num_peers,
568 struct GNUNET_TESTBED_Peer **peers,
569 struct GNUNET_DHT_Handle **dhts)
570{
571 GNUNET_assert (NUM_PEERS == num_peers);
572 my_peers = peers;
573 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
574 "Peers setup, starting test\n");
575 put_task = GNUNET_SCHEDULER_add_now (&do_puts,
576 dhts);
577 get_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
578 &start_get,
579 dhts);
580 timeout_task = GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT,
581 &timeout_cb,
582 ctx);
583 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
584 ctx);
585}
586
587
588/**
589 * Main: start test
590 */
591int
592main (int xargc, char *xargv[])
593{
594 const char *cfg_filename;
595 const char *test_name;
596
597 unsetenv ("XDG_DATA_HOME");
598 unsetenv ("XDG_CONFIG_HOME");
599 unsetenv ("XDG_CACHE_HOME");
600 if (NULL != strstr (xargv[0], "test_dht_2dtorus"))
601 {
602 cfg_filename = "test_dht_2dtorus.conf";
603 test_name = "test-dht-2dtorus";
604 NUM_PEERS = 16;
605 }
606 else if (NULL != strstr (xargv[0], "test_dht_line"))
607 {
608 cfg_filename = "test_dht_line.conf";
609 test_name = "test-dht-line";
610 NUM_PEERS = 5;
611 }
612 else if (NULL != strstr (xargv[0], "test_dht_twopeer"))
613 {
614 cfg_filename = "test_dht_line.conf";
615 test_name = "test-dht-twopeer";
616 NUM_PEERS = 2;
617 }
618 else if (NULL != strstr (xargv[0], "test_dht_multipeer"))
619 {
620 cfg_filename = "test_dht_multipeer.conf";
621 test_name = "test-dht-multipeer";
622 NUM_PEERS = 10;
623 }
624 else
625 {
626 GNUNET_break (0);
627 return 1;
628 }
629 GNUNET_DHT_TEST_run (test_name,
630 cfg_filename,
631 NUM_PEERS,
632 &run, NULL);
633 return ok;
634}
635
636
637/* end of test_dht_topo.c */
diff --git a/src/service/fs/Makefile.am b/src/service/fs/Makefile.am
index 93c8814ca..c1d545af1 100644
--- a/src/service/fs/Makefile.am
+++ b/src/service/fs/Makefile.am
@@ -118,7 +118,6 @@ check_PROGRAMS = \
118 test_fs_search_probes \ 118 test_fs_search_probes \
119 test_fs_search_persistence \ 119 test_fs_search_persistence \
120 test_fs_start_stop \ 120 test_fs_start_stop \
121 test_fs_test_lib \
122 test_fs_unindex \ 121 test_fs_unindex \
123 test_fs_unindex_persistence \ 122 test_fs_unindex_persistence \
124 test_fs_uri \ 123 test_fs_uri \
@@ -298,13 +297,6 @@ test_fs_uri_LDADD = \
298 $(top_builddir)/src/lib/util/libgnunetutil.la 297 $(top_builddir)/src/lib/util/libgnunetutil.la
299 298
300# TNG 299# TNG
301#test_fs_test_lib_SOURCES = \
302# test_fs_test_lib.c
303#test_fs_test_lib_LDADD = \
304# libgnunetfstest.a \
305# $(top_builddir)/src/testbed/libgnunettestbed.la \
306# libgnunetfs.la \
307# $(top_builddir)/src/lib/util/libgnunetutil.la
308 300
309#test_gnunet_service_fs_p2p_SOURCES = \ 301#test_gnunet_service_fs_p2p_SOURCES = \
310# test_gnunet_service_fs_p2p.c 302# test_gnunet_service_fs_p2p.c
@@ -367,7 +359,6 @@ test_fs_uri_LDADD = \
367# $(top_builddir)/src/lib/util/libgnunetutil.la 359# $(top_builddir)/src/lib/util/libgnunetutil.la
368 360
369EXTRA_DIST = \ 361EXTRA_DIST = \
370 fs_test_lib_data.conf \
371 perf_gnunet_service_fs_p2p.conf \ 362 perf_gnunet_service_fs_p2p.conf \
372 test_fs_data.conf \ 363 test_fs_data.conf \
373 test_fs_defaults.conf \ 364 test_fs_defaults.conf \
diff --git a/src/service/fs/fs_test_lib.c b/src/service/fs/fs_test_lib.c
deleted file mode 100644
index f80a2859c..000000000
--- a/src/service/fs/fs_test_lib.c
+++ /dev/null
@@ -1,630 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010, 2011, 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file fs/fs_test_lib.c
23 * @brief library routines for testing FS publishing and downloading;
24 * this code is limited to flat files
25 * and no keywords (those functions can be tested with
26 * single-peer setups; this is for testing routing).
27 * @author Christian Grothoff
28 */
29#include "platform.h"
30#include "fs_api.h"
31#include "fs_test_lib.h"
32
33
34#define CONTENT_LIFETIME GNUNET_TIME_UNIT_HOURS
35
36
37/**
38 * Handle for a publishing operation started for testing FS.
39 */
40struct TestPublishOperation
41{
42 /**
43 * Handle for the operation to connect to the peer's 'fs' service.
44 */
45 struct GNUNET_TESTBED_Operation *fs_op;
46
47 /**
48 * Handle to the file sharing context using this daemon.
49 */
50 struct GNUNET_FS_Handle *fs;
51
52 /**
53 * Function to call when upload is done.
54 */
55 GNUNET_FS_TEST_UriContinuation publish_cont;
56
57 /**
58 * Closure for publish_cont.
59 */
60 void *publish_cont_cls;
61
62 /**
63 * Task to abort publishing (timeout).
64 */
65 struct GNUNET_SCHEDULER_Task *publish_timeout_task;
66
67 /**
68 * Seed for file generation.
69 */
70 uint32_t publish_seed;
71
72 /**
73 * Context for current publishing operation.
74 */
75 struct GNUNET_FS_PublishContext *publish_context;
76
77 /**
78 * Result URI.
79 */
80 struct GNUNET_FS_Uri *publish_uri;
81
82 /**
83 * Name of the temporary file used, or NULL for none.
84 */
85 char *publish_tmp_file;
86
87 /**
88 * Size of the file.
89 */
90 uint64_t size;
91
92 /**
93 * Anonymity level used.
94 */
95 uint32_t anonymity;
96
97 /**
98 * Verbosity level of the current operation.
99 */
100 unsigned int verbose;
101
102 /**
103 * Are we testing indexing? (YES: index, NO: insert, SYSERR: simulate)
104 */
105 int do_index;
106};
107
108
109/**
110 * Handle for a download operation started for testing FS.
111 */
112struct TestDownloadOperation
113{
114 /**
115 * Handle for the operation to connect to the peer's 'fs' service.
116 */
117 struct GNUNET_TESTBED_Operation *fs_op;
118
119 /**
120 * Handle to the file sharing context using this daemon.
121 */
122 struct GNUNET_FS_Handle *fs;
123
124 /**
125 * Handle to the daemon via testing.
126 */
127 struct GNUNET_TESTING_Daemon *daemon;
128
129 /**
130 * Function to call when download is done.
131 */
132 GNUNET_SCHEDULER_TaskCallback download_cont;
133
134 /**
135 * Closure for download_cont.
136 */
137 void *download_cont_cls;
138
139 /**
140 * URI to download.
141 */
142 struct GNUNET_FS_Uri *uri;
143
144 /**
145 * Task to abort downloading (timeout).
146 */
147 struct GNUNET_SCHEDULER_Task *download_timeout_task;
148
149 /**
150 * Context for current download operation.
151 */
152 struct GNUNET_FS_DownloadContext *download_context;
153
154 /**
155 * Size of the file.
156 */
157 uint64_t size;
158
159 /**
160 * Anonymity level used.
161 */
162 uint32_t anonymity;
163
164 /**
165 * Seed for download verification.
166 */
167 uint32_t download_seed;
168
169 /**
170 * Verbosity level of the current operation.
171 */
172 unsigned int verbose;
173};
174
175
176/**
177 * Task scheduled to report on the completion of our publish operation.
178 *
179 * @param cls the publish operation context
180 */
181static void
182report_uri (void *cls)
183{
184 struct TestPublishOperation *po = cls;
185
186 GNUNET_FS_publish_stop (po->publish_context);
187 GNUNET_TESTBED_operation_done (po->fs_op);
188 po->publish_cont (po->publish_cont_cls,
189 po->publish_uri,
190 (GNUNET_YES == po->do_index)
191 ? po->publish_tmp_file
192 : NULL);
193 GNUNET_FS_uri_destroy (po->publish_uri);
194 if ((GNUNET_YES != po->do_index) &&
195 (NULL != po->publish_tmp_file))
196 (void) GNUNET_DISK_directory_remove (po->publish_tmp_file);
197 GNUNET_free (po->publish_tmp_file);
198 GNUNET_free (po);
199}
200
201
202/**
203 * Task scheduled to run when publish operation times out.
204 *
205 * @param cls the publish operation context
206 */
207static void
208publish_timeout (void *cls)
209{
210 struct TestPublishOperation *po = cls;
211
212 po->publish_timeout_task = NULL;
213 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
214 "Timeout while trying to publish data\n");
215 GNUNET_TESTBED_operation_done (po->fs_op);
216 GNUNET_FS_publish_stop (po->publish_context);
217 po->publish_cont (po->publish_cont_cls, NULL, NULL);
218 (void) GNUNET_DISK_directory_remove (po->publish_tmp_file);
219 GNUNET_free (po->publish_tmp_file);
220 GNUNET_free (po);
221}
222
223
224/**
225 * Progress callback for file-sharing events while publishing.
226 *
227 * @param cls the publish operation context
228 * @param info information about the event
229 */
230static void *
231publish_progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
232{
233 struct TestPublishOperation *po = cls;
234
235 switch (info->status)
236 {
237 case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
238 GNUNET_SCHEDULER_cancel (po->publish_timeout_task);
239 po->publish_timeout_task = NULL;
240 po->publish_uri =
241 GNUNET_FS_uri_dup (info->value.publish.specifics.completed.chk_uri);
242 GNUNET_SCHEDULER_add_now (&report_uri,
243 po);
244 break;
245
246 case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
247 if (po->verbose)
248 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Publishing at %llu/%llu bytes\n",
249 (unsigned long long) info->value.publish.completed,
250 (unsigned long long) info->value.publish.size);
251 break;
252
253 case GNUNET_FS_STATUS_PUBLISH_PROGRESS_DIRECTORY:
254 break;
255
256 case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
257 if (po->verbose)
258 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Download at %llu/%llu bytes\n",
259 (unsigned long long) info->value.download.completed,
260 (unsigned long long) info->value.download.size);
261 break;
262
263 default:
264 break;
265 }
266 return NULL;
267}
268
269
270/**
271 * Generate test data for publishing test.
272 *
273 * @param cls pointer to uint32_t with publishing seed
274 * @param offset offset to generate data for
275 * @param max maximum number of bytes to generate
276 * @param buf where to write generated data
277 * @param emsg where to store error message (unused)
278 * @return number of bytes written to buf
279 */
280static size_t
281file_generator (void *cls,
282 uint64_t offset,
283 size_t max,
284 void *buf,
285 char **emsg)
286{
287 uint32_t *publish_seed = cls;
288 uint64_t pos;
289 uint8_t *cbuf = buf;
290 int mod;
291
292 if (emsg != NULL)
293 *emsg = NULL;
294 if (buf == NULL)
295 return 0;
296 for (pos = 0; pos < 8; pos++)
297 cbuf[pos] = (uint8_t) (offset >> pos * 8);
298 for (pos = 8; pos < max; pos++)
299 {
300 mod = (255 - (offset / 1024 / 32));
301 if (mod == 0)
302 mod = 1;
303 cbuf[pos] = (uint8_t) ((offset * (*publish_seed)) % mod);
304 }
305 return max;
306}
307
308
309/**
310 * Connect adapter for publishing operation.
311 *
312 * @param cls the 'struct TestPublishOperation'
313 * @param cfg configuration of the peer to connect to; will be available until
314 * GNUNET_TESTBED_operation_done() is called on the operation returned
315 * from GNUNET_TESTBED_service_connect()
316 * @return service handle to return in 'op_result', NULL on error
317 */
318static void *
319publish_connect_adapter (void *cls,
320 const struct GNUNET_CONFIGURATION_Handle *cfg)
321{
322 struct TestPublishOperation *po = cls;
323
324 return GNUNET_FS_start (cfg,
325 "fs-test-publish",
326 &publish_progress_cb, po,
327 GNUNET_FS_FLAGS_NONE,
328 GNUNET_FS_OPTIONS_END);
329}
330
331
332/**
333 * Adapter function called to destroy connection to file-sharing service.
334 *
335 * @param cls the 'struct GNUNET_FS_Handle'
336 * @param op_result unused (different for publish/download!)
337 */
338static void
339fs_disconnect_adapter (void *cls,
340 void *op_result)
341{
342 struct GNUNET_FS_Handle *fs = op_result;
343
344 GNUNET_FS_stop (fs);
345}
346
347
348/**
349 * Callback to be called when testbed has connected to the fs service
350 *
351 * @param cls the 'struct TestPublishOperation'
352 * @param op the operation that has been finished
353 * @param ca_result the 'struct GNUNET_FS_Handle ' (NULL on error)
354 * @param emsg error message in case the operation has failed; will be NULL if
355 * operation has executed successfully.
356 */
357static void
358publish_fs_connect_complete_cb (void *cls,
359 struct GNUNET_TESTBED_Operation *op,
360 void *ca_result,
361 const char *emsg)
362{
363 struct TestPublishOperation *po = cls;
364 struct GNUNET_FS_FileInformation *fi;
365 struct GNUNET_DISK_FileHandle *fh;
366 char *em;
367 uint64_t off;
368 char buf[DBLOCK_SIZE];
369 size_t bsize;
370 struct GNUNET_FS_BlockOptions bo;
371
372 if (NULL == ca_result)
373 {
374 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
375 "Failed to connect to FS for publishing: %s\n", emsg);
376 po->publish_cont (po->publish_cont_cls,
377 NULL, NULL);
378 GNUNET_TESTBED_operation_done (po->fs_op);
379 GNUNET_free (po);
380 return;
381 }
382 po->fs = ca_result;
383
384 bo.expiration_time = GNUNET_TIME_relative_to_absolute (CONTENT_LIFETIME);
385 bo.anonymity_level = po->anonymity;
386 bo.content_priority = 42;
387 bo.replication_level = 1;
388 if (GNUNET_YES == po->do_index)
389 {
390 po->publish_tmp_file = GNUNET_DISK_mktemp ("fs-test-publish-index");
391 GNUNET_assert (po->publish_tmp_file != NULL);
392 fh = GNUNET_DISK_file_open (po->publish_tmp_file,
393 GNUNET_DISK_OPEN_WRITE
394 | GNUNET_DISK_OPEN_CREATE,
395 GNUNET_DISK_PERM_USER_READ
396 | GNUNET_DISK_PERM_USER_WRITE);
397 GNUNET_assert (NULL != fh);
398 off = 0;
399 while (off < po->size)
400 {
401 bsize = GNUNET_MIN (sizeof(buf), po->size - off);
402 emsg = NULL;
403 GNUNET_assert (bsize == file_generator (&po->publish_seed, off, bsize,
404 buf, &em));
405 GNUNET_assert (em == NULL);
406 GNUNET_assert (bsize == GNUNET_DISK_file_write (fh, buf, bsize));
407 off += bsize;
408 }
409 GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
410 fi = GNUNET_FS_file_information_create_from_file (po->fs, po,
411 po->publish_tmp_file,
412 NULL, NULL, po->do_index,
413 &bo);
414 GNUNET_assert (NULL != fi);
415 }
416 else
417 {
418 fi = GNUNET_FS_file_information_create_from_reader (po->fs, po,
419 po->size,
420 &file_generator,
421 &po->publish_seed,
422 NULL, NULL,
423 po->do_index, &bo);
424 GNUNET_assert (NULL != fi);
425 }
426 po->publish_context =
427 GNUNET_FS_publish_start (po->fs, fi, NULL, NULL, NULL,
428 GNUNET_FS_PUBLISH_OPTION_NONE);
429}
430
431
432void
433GNUNET_FS_TEST_publish (struct GNUNET_TESTBED_Peer *peer,
434 struct GNUNET_TIME_Relative timeout, uint32_t anonymity,
435 int do_index, uint64_t size, uint32_t seed,
436 unsigned int verbose,
437 GNUNET_FS_TEST_UriContinuation cont, void *cont_cls)
438{
439 struct TestPublishOperation *po;
440
441 po = GNUNET_new (struct TestPublishOperation);
442 po->publish_cont = cont;
443 po->publish_cont_cls = cont_cls;
444 po->publish_seed = seed;
445 po->anonymity = anonymity;
446 po->size = size;
447 po->verbose = verbose;
448 po->do_index = do_index;
449 po->fs_op = GNUNET_TESTBED_service_connect (po,
450 peer,
451 "fs",
452 &publish_fs_connect_complete_cb,
453 po,
454 &publish_connect_adapter,
455 &fs_disconnect_adapter,
456 po);
457 po->publish_timeout_task =
458 GNUNET_SCHEDULER_add_delayed (timeout, &publish_timeout, po);
459}
460
461
462/* ************************** download ************************ */
463
464
465/**
466 * Task scheduled to run when download operation times out.
467 *
468 * @param cls the download operation context
469 */
470static void
471download_timeout (void *cls)
472{
473 struct TestDownloadOperation *dop = cls;
474
475 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
476 "Timeout while trying to download file\n");
477 dop->download_timeout_task = NULL;
478 GNUNET_FS_download_stop (dop->download_context,
479 GNUNET_YES);
480 GNUNET_SCHEDULER_add_now (dop->download_cont,
481 dop->download_cont_cls);
482 GNUNET_TESTBED_operation_done (dop->fs_op);
483 GNUNET_FS_uri_destroy (dop->uri);
484 GNUNET_free (dop);
485}
486
487
488/**
489 * Task scheduled to report on the completion of our download operation.
490 *
491 * @param cls the download operation context
492 */
493static void
494report_success (void *cls)
495{
496 struct TestDownloadOperation *dop = cls;
497
498 GNUNET_FS_download_stop (dop->download_context,
499 GNUNET_YES);
500 GNUNET_SCHEDULER_add_now (dop->download_cont,
501 dop->download_cont_cls);
502 GNUNET_TESTBED_operation_done (dop->fs_op);
503 GNUNET_FS_uri_destroy (dop->uri);
504 GNUNET_free (dop);
505}
506
507
508/**
509 * Progress callback for file-sharing events while downloading.
510 *
511 * @param cls the download operation context
512 * @param info information about the event
513 */
514static void *
515download_progress_cb (void *cls,
516 const struct GNUNET_FS_ProgressInfo *info)
517{
518 struct TestDownloadOperation *dop = cls;
519
520 switch (info->status)
521 {
522 case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS:
523 if (dop->verbose)
524 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
525 "Download at %llu/%llu bytes\n",
526 (unsigned long long) info->value.download.completed,
527 (unsigned long long) info->value.download.size);
528 break;
529
530 case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED:
531 GNUNET_SCHEDULER_cancel (dop->download_timeout_task);
532 dop->download_timeout_task = NULL;
533 GNUNET_SCHEDULER_add_now (&report_success, dop);
534 break;
535
536 case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE:
537 case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE:
538 break;
539
540 /* FIXME: monitor data correctness during download progress */
541 /* FIXME: do performance reports given sufficient verbosity */
542 /* FIXME: advance timeout task to "immediate" on error */
543 default:
544 break;
545 }
546 return NULL;
547}
548
549
550/**
551 * Connect adapter for download operation.
552 *
553 * @param cls the 'struct TestDownloadOperation'
554 * @param cfg configuration of the peer to connect to; will be available until
555 * GNUNET_TESTBED_operation_done() is called on the operation returned
556 * from GNUNET_TESTBED_service_connect()
557 * @return service handle to return in 'op_result', NULL on error
558 */
559static void *
560download_connect_adapter (void *cls,
561 const struct GNUNET_CONFIGURATION_Handle *cfg)
562{
563 struct TestPublishOperation *po = cls;
564
565 return GNUNET_FS_start (cfg,
566 "fs-test-download",
567 &download_progress_cb, po,
568 GNUNET_FS_FLAGS_NONE,
569 GNUNET_FS_OPTIONS_END);
570}
571
572
573/**
574 * Callback to be called when testbed has connected to the fs service
575 *
576 * @param cls the 'struct TestPublishOperation'
577 * @param op the operation that has been finished
578 * @param ca_result the 'struct GNUNET_FS_Handle ' (NULL on error)
579 * @param emsg error message in case the operation has failed; will be NULL if
580 * operation has executed successfully.
581 */
582static void
583download_fs_connect_complete_cb (void *cls,
584 struct GNUNET_TESTBED_Operation *op,
585 void *ca_result,
586 const char *emsg)
587{
588 struct TestDownloadOperation *dop = cls;
589
590 dop->fs = ca_result;
591 GNUNET_assert (NULL != dop->fs);
592 dop->download_context =
593 GNUNET_FS_download_start (dop->fs, dop->uri, NULL, NULL, NULL, 0, dop->size,
594 dop->anonymity, GNUNET_FS_DOWNLOAD_OPTION_NONE,
595 NULL, NULL);
596}
597
598
599void
600GNUNET_FS_TEST_download (struct GNUNET_TESTBED_Peer *peer,
601 struct GNUNET_TIME_Relative timeout,
602 uint32_t anonymity, uint32_t seed,
603 const struct GNUNET_FS_Uri *uri, unsigned int verbose,
604 GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
605{
606 struct TestDownloadOperation *dop;
607
608 dop = GNUNET_new (struct TestDownloadOperation);
609 dop->uri = GNUNET_FS_uri_dup (uri);
610 dop->size = GNUNET_FS_uri_chk_get_file_size (uri);
611 dop->verbose = verbose;
612 dop->anonymity = anonymity;
613 dop->download_cont = cont;
614 dop->download_cont_cls = cont_cls;
615 dop->download_seed = seed;
616
617 dop->fs_op = GNUNET_TESTBED_service_connect (dop,
618 peer,
619 "fs",
620 &download_fs_connect_complete_cb,
621 dop,
622 &download_connect_adapter,
623 &fs_disconnect_adapter,
624 dop);
625 dop->download_timeout_task =
626 GNUNET_SCHEDULER_add_delayed (timeout, &download_timeout, dop);
627}
628
629
630/* end of fs_test_lib.c */
diff --git a/src/service/fs/fs_test_lib.h b/src/service/fs/fs_test_lib.h
deleted file mode 100644
index 36244eb19..000000000
--- a/src/service/fs/fs_test_lib.h
+++ /dev/null
@@ -1,102 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010, 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file fs/fs_test_lib.h
23 * @brief library routines for testing FS publishing and downloading;
24 * this code is limited to flat files
25 * and no keywords (those functions can be tested with
26 * single-peer setups; this is for testing routing).
27 * @author Christian Grothoff
28 */
29#ifndef FS_TEST_LIB_H
30#define FS_TEST_LIB_H
31
32#include "gnunet_util_lib.h"
33#include "gnunet_fs_service.h"
34#include "gnunet_testbed_service.h"
35
36
37/**
38 * Function signature.
39 *
40 * @param cls closure (user defined)
41 * @param uri a URI, NULL for errors
42 * @param fn name of the file on disk to be removed upon
43 * completion, or NULL for inserted files (also NULL on error)
44 */
45typedef void
46(*GNUNET_FS_TEST_UriContinuation) (void *cls,
47 const struct GNUNET_FS_Uri *uri,
48 const char *fn);
49
50
51/**
52 * Publish a file at the given daemon.
53 *
54 * @param peer where to publish
55 * @param timeout if this operation cannot be completed within the
56 * given period, call the continuation with an error code
57 * @param anonymity option for publication
58 * @param do_index #GNUNET_YES for index, #GNUNET_NO for insertion,
59 * #GNUNET_SYSERR for simulation
60 * @param size size of the file to publish
61 * @param seed seed to use for file generation
62 * @param verbose how verbose to be in reporting
63 * @param cont function to call when done
64 * @param cont_cls closure for @a cont
65 */
66void
67GNUNET_FS_TEST_publish (struct GNUNET_TESTBED_Peer *peer,
68 struct GNUNET_TIME_Relative timeout,
69 uint32_t anonymity,
70 int do_index,
71 uint64_t size,
72 uint32_t seed,
73 unsigned int verbose,
74 GNUNET_FS_TEST_UriContinuation cont,
75 void *cont_cls);
76
77
78/**
79 * Perform test download.
80 *
81 * @param peer which peer to download from
82 * @param timeout if this operation cannot be completed within the
83 * given period, call the continuation with an error code
84 * @param anonymity option for download
85 * @param seed used for file validation
86 * @param uri URI of file to download (CHK/LOC only)
87 * @param verbose how verbose to be in reporting
88 * @param cont function to call when done
89 * @param cont_cls closure for @a cont
90 */
91void
92GNUNET_FS_TEST_download (struct GNUNET_TESTBED_Peer *peer,
93 struct GNUNET_TIME_Relative timeout,
94 uint32_t anonymity,
95 uint32_t seed,
96 const struct GNUNET_FS_Uri *uri,
97 unsigned int verbose,
98 GNUNET_SCHEDULER_TaskCallback cont,
99 void *cont_cls);
100
101
102#endif
diff --git a/src/service/fs/fs_test_lib_data.conf b/src/service/fs/fs_test_lib_data.conf
deleted file mode 100644
index c99674798..000000000
--- a/src/service/fs/fs_test_lib_data.conf
+++ /dev/null
@@ -1,17 +0,0 @@
1@INLINE@ test_fs_defaults.conf
2[PATHS]
3GNUNET_TEST_HOME = $GNUNET_TMP/gnunet-fs-test-lib/
4
5[ats]
6WAN_QUOTA_IN = 3932160
7WAN_QUOTA_OUT = 3932160
8
9[datastore]
10QUOTA = 2 GB
11#PLUGIN = heap
12#
13[fs]
14IMMEDIATE_START = YES
15
16[testbed]
17OVERLAY_TOPOLOGY = CLIQUE
diff --git a/src/service/nse/Makefile.am b/src/service/nse/Makefile.am
index 7b89ef635..40690e81c 100644
--- a/src/service/nse/Makefile.am
+++ b/src/service/nse/Makefile.am
@@ -28,20 +28,6 @@ libgnunetnse_la_LDFLAGS = \
28libexec_PROGRAMS = \ 28libexec_PROGRAMS = \
29 gnunet-service-nse 29 gnunet-service-nse
30 30
31#noinst_PROGRAMS = \
32# gnunet-nse-profiler
33
34# FIXME no testbed in TNG
35#gnunet_nse_profiler_SOURCES = \
36# gnunet-nse-profiler.c
37#gnunet_nse_profiler_LDADD = -lm \
38# libgnunetnse.la \
39# $(top_builddir)/src/lib/util/libgnunetutil.la \
40# $(top_builddir)/src/service/statistics/libgnunetstatistics.la \
41# $(top_builddir)/src/service/testing/libgnunettesting.la \
42# $(top_builddir)/src/testbed/libgnunettestbed.la \
43# $(GN_LIBINTL)
44
45gnunet_service_nse_SOURCES = \ 31gnunet_service_nse_SOURCES = \
46 gnunet-service-nse.c 32 gnunet-service-nse.c
47gnunet_service_nse_LDADD = \ 33gnunet_service_nse_LDADD = \
diff --git a/src/service/nse/gnunet-nse-profiler.c b/src/service/nse/gnunet-nse-profiler.c
deleted file mode 100644
index 4b256bc52..000000000
--- a/src/service/nse/gnunet-nse-profiler.c
+++ /dev/null
@@ -1,921 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011, 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file nse/gnunet-nse-profiler.c
22 *
23 * @brief Profiling driver for the network size estimation service.
24 * Generally, the profiler starts a given number of peers,
25 * then churns some off, waits a certain amount of time, then
26 * churns again, and repeats.
27 * @author Christian Grothoff
28 * @author Nathan Evans
29 * @author Sree Harsha Totakura
30 */
31
32#include "platform.h"
33#include "gnunet_testbed_service.h"
34#include "gnunet_nse_service.h"
35
36/**
37 * Generic loggins shorthand
38 */
39#define LOG(kind, ...) GNUNET_log (kind, __VA_ARGS__)
40
41/**
42 * Debug logging shorthand
43 */
44#define LOG_DEBUG(...) LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
45
46
47/**
48 * Information we track for a peer in the testbed.
49 */
50struct NSEPeer
51{
52 /**
53 * Prev reference in DLL.
54 */
55 struct NSEPeer *prev;
56
57 /**
58 * Next reference in DLL.
59 */
60 struct NSEPeer *next;
61
62 /**
63 * Handle with testbed.
64 */
65 struct GNUNET_TESTBED_Peer *daemon;
66
67 /**
68 * Testbed operation to connect to NSE service.
69 */
70 struct GNUNET_TESTBED_Operation *nse_op;
71
72 /**
73 * Testbed operation to connect to statistics service
74 */
75 struct GNUNET_TESTBED_Operation *stat_op;
76
77 /**
78 * Handle to the statistics service
79 */
80 struct GNUNET_STATISTICS_Handle *sh;
81};
82
83
84/**
85 * Operation map entry
86 */
87struct OpListEntry
88{
89 /**
90 * DLL next ptr
91 */
92 struct OpListEntry *next;
93
94 /**
95 * DLL prev ptr
96 */
97 struct OpListEntry *prev;
98
99 /**
100 * The testbed operation
101 */
102 struct GNUNET_TESTBED_Operation *op;
103
104 /**
105 * Depending on whether we start or stop NSE service at the peer set this to 1
106 * or -1
107 */
108 int delta;
109};
110
111
112/**
113 * Head of DLL of peers we monitor closely.
114 */
115static struct NSEPeer *peer_head;
116
117/**
118 * Tail of DLL of peers we monitor closely.
119 */
120static struct NSEPeer *peer_tail;
121
122/**
123 * Return value from 'main' (0 == success)
124 */
125static int ok;
126
127/**
128 * Be verbose (configuration option)
129 */
130static unsigned int verbose;
131
132/**
133 * Name of the file with the hosts to run the test over (configuration option)
134 */
135static char *hosts_file;
136
137/**
138 * Maximum number of peers in the test.
139 */
140static unsigned int num_peers;
141
142/**
143 * Total number of rounds to execute.
144 */
145static unsigned int num_rounds;
146
147/**
148 * Current round we are in.
149 */
150static unsigned int current_round;
151
152/**
153 * Array of size 'num_rounds' with the requested number of peers in the given round.
154 */
155static unsigned int *num_peers_in_round;
156
157/**
158 * How many peers are running right now?
159 */
160static unsigned int peers_running;
161
162/**
163 * Specification for the numbers of peers to have in each round.
164 */
165static char *num_peer_spec;
166
167/**
168 * Handles to all of the running peers.
169 */
170static struct GNUNET_TESTBED_Peer **daemons;
171
172/**
173 * Global configuration file
174 */
175static struct GNUNET_CONFIGURATION_Handle *testing_cfg;
176
177/**
178 * Maximum number of connections to NSE services.
179 */
180static unsigned int connection_limit;
181
182/**
183 * Total number of connections in the whole network.
184 */
185static unsigned int total_connections;
186
187/**
188 * File to report results to.
189 */
190static struct GNUNET_DISK_FileHandle *output_file;
191
192/**
193 * Filename to log results to.
194 */
195static char *output_filename;
196
197/**
198 * File to log connection info, statistics to.
199 */
200static struct GNUNET_DISK_FileHandle *data_file;
201
202/**
203 * Filename to log connection info, statistics to.
204 */
205static char *data_filename;
206
207/**
208 * How long to wait before triggering next round?
209 * Default: 60 s.
210 */
211static struct GNUNET_TIME_Relative wait_time = { 60 * 1000 };
212
213/**
214 * DLL head for operation list
215 */
216static struct OpListEntry *oplist_head;
217
218/**
219 * DLL tail for operation list
220 */
221static struct OpListEntry *oplist_tail;
222
223/**
224 * Task running each round of the experiment.
225 */
226static struct GNUNET_SCHEDULER_Task *round_task;
227
228
229/**
230 * Clean up all of the monitoring connections to NSE and
231 * STATISTICS that we keep to selected peers.
232 */
233static void
234close_monitor_connections ()
235{
236 struct NSEPeer *pos;
237 struct OpListEntry *oplist_entry;
238
239 while (NULL != (pos = peer_head))
240 {
241 if (NULL != pos->nse_op)
242 GNUNET_TESTBED_operation_done (pos->nse_op);
243 if (NULL != pos->stat_op)
244 GNUNET_TESTBED_operation_done (pos->stat_op);
245 GNUNET_CONTAINER_DLL_remove (peer_head, peer_tail, pos);
246 GNUNET_free (pos);
247 }
248 while (NULL != (oplist_entry = oplist_head))
249 {
250 GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, oplist_entry);
251 GNUNET_TESTBED_operation_done (oplist_entry->op);
252 GNUNET_free (oplist_entry);
253 }
254}
255
256
257/**
258 * Task run on shutdown; cleans up everything.
259 *
260 * @param cls unused
261 */
262static void
263shutdown_task (void *cls)
264{
265 LOG_DEBUG ("Ending test.\n");
266 close_monitor_connections ();
267 if (NULL != round_task)
268 {
269 GNUNET_SCHEDULER_cancel (round_task);
270 round_task = NULL;
271 }
272 if (NULL != data_file)
273 {
274 GNUNET_DISK_file_close (data_file);
275 data_file = NULL;
276 }
277 if (NULL != output_file)
278 {
279 GNUNET_DISK_file_close (output_file);
280 output_file = NULL;
281 }
282 if (NULL != testing_cfg)
283 {
284 GNUNET_CONFIGURATION_destroy (testing_cfg);
285 testing_cfg = NULL;
286 }
287}
288
289
290/**
291 * Callback to call when network size estimate is updated.
292 *
293 * @param cls closure with the 'struct NSEPeer' providing the update
294 * @param timestamp server timestamp
295 * @param estimate the value of the current network size estimate
296 * @param std_dev standard deviation (rounded down to nearest integer)
297 * of the size estimation values seen
298 */
299static void
300handle_estimate (void *cls,
301 struct GNUNET_TIME_Absolute timestamp,
302 double estimate,
303 double std_dev)
304{
305 struct NSEPeer *peer = cls;
306 char output_buffer[512];
307 size_t size;
308
309 if (NULL == output_file)
310 {
311 fprintf (stderr,
312 "Received network size estimate from peer %p. Size: %f std.dev. %f\n",
313 peer,
314 estimate,
315 std_dev);
316 return;
317 }
318 size = GNUNET_snprintf (output_buffer,
319 sizeof(output_buffer),
320 "%p %u %llu %f %f %f\n",
321 peer,
322 peers_running,
323 (unsigned long long) timestamp.abs_value_us,
324 GNUNET_NSE_log_estimate_to_n (estimate),
325 estimate,
326 std_dev);
327 if (size != GNUNET_DISK_file_write (output_file, output_buffer, size))
328 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to write to file!\n");
329}
330
331
332/**
333 * Adapter function called to establish a connection to
334 * NSE service.
335 *
336 * @param cls closure (the 'struct NSEPeer')
337 * @param cfg configuration of the peer to connect to; will be available until
338 * GNUNET_TESTBED_operation_done() is called on the operation returned
339 * from GNUNET_TESTBED_service_connect()
340 * @return service handle to return in 'op_result', NULL on error
341 */
342static void *
343nse_connect_adapter (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
344{
345 struct NSEPeer *current_peer = cls;
346
347 return GNUNET_NSE_connect (cfg, &handle_estimate, current_peer);
348}
349
350
351/**
352 * Adapter function called to destroy a connection to
353 * NSE service.
354 *
355 * @param cls closure
356 * @param op_result service handle returned from the connect adapter
357 */
358static void
359nse_disconnect_adapter (void *cls, void *op_result)
360{
361 GNUNET_NSE_disconnect (op_result);
362}
363
364
365/**
366 * Callback function to process statistic values.
367 *
368 * @param cls `struct NSEPeer`
369 * @param subsystem name of subsystem that created the statistic
370 * @param name the name of the datum
371 * @param value the current value
372 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
373 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
374 */
375static int
376stat_iterator (void *cls,
377 const char *subsystem,
378 const char *name,
379 uint64_t value,
380 int is_persistent)
381{
382 char *output_buffer;
383 struct GNUNET_TIME_Absolute now;
384 int size;
385 unsigned int flag;
386
387 GNUNET_assert (NULL != data_file);
388 now = GNUNET_TIME_absolute_get ();
389 flag = strcasecmp (subsystem, "core");
390 if (0 != flag)
391 flag = 1;
392 size = GNUNET_asprintf (&output_buffer,
393 "%llu %llu %u\n",
394 (unsigned long long) now.abs_value_us / 1000LL / 1000LL,
395 (unsigned long long) value,
396 flag);
397 if (0 > size)
398 {
399 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Error formatting output buffer.\n");
400 GNUNET_free (output_buffer);
401 return GNUNET_SYSERR;
402 }
403 if (size != GNUNET_DISK_file_write (data_file, output_buffer, (size_t) size))
404 {
405 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to write to file!\n");
406 GNUNET_free (output_buffer);
407 return GNUNET_SYSERR;
408 }
409 GNUNET_free (output_buffer);
410 return GNUNET_OK;
411}
412
413
414/**
415 * Called to open a connection to the peer's statistics
416 *
417 * @param cls peer context
418 * @param cfg configuration of the peer to connect to; will be available until
419 * GNUNET_TESTBED_operation_done() is called on the operation returned
420 * from GNUNET_TESTBED_service_connect()
421 * @return service handle to return in 'op_result', NULL on error
422 */
423static void *
424stat_connect_adapter (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
425{
426 struct NSEPeer *peer = cls;
427
428 peer->sh = GNUNET_STATISTICS_create ("nse-profiler", cfg);
429 return peer->sh;
430}
431
432
433/**
434 * Called to disconnect from peer's statistics service
435 *
436 * @param cls peer context
437 * @param op_result service handle returned from the connect adapter
438 */
439static void
440stat_disconnect_adapter (void *cls, void *op_result)
441{
442 struct NSEPeer *peer = cls;
443
444 GNUNET_break (GNUNET_OK ==
445 GNUNET_STATISTICS_watch_cancel (peer->sh,
446 "core",
447 "# peers connected",
448 stat_iterator,
449 peer));
450 GNUNET_break (GNUNET_OK ==
451 GNUNET_STATISTICS_watch_cancel (peer->sh,
452 "nse",
453 "# peers connected",
454 stat_iterator,
455 peer));
456 GNUNET_STATISTICS_destroy (op_result, GNUNET_NO);
457 peer->sh = NULL;
458}
459
460
461/**
462 * Called after successfully opening a connection to a peer's statistics
463 * service; we register statistics monitoring for CORE and NSE here.
464 *
465 * @param cls the callback closure from functions generating an operation
466 * @param op the operation that has been finished
467 * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter()
468 * @param emsg error message in case the operation has failed; will be NULL if
469 * operation has executed successfully.
470 */
471static void
472stat_comp_cb (void *cls,
473 struct GNUNET_TESTBED_Operation *op,
474 void *ca_result,
475 const char *emsg)
476{
477 struct GNUNET_STATISTICS_Handle *sh = ca_result;
478 struct NSEPeer *peer = cls;
479
480 if (NULL != emsg)
481 {
482 GNUNET_break (0);
483 return;
484 }
485 GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch (sh,
486 "core",
487 "# peers connected",
488 stat_iterator,
489 peer));
490 GNUNET_break (GNUNET_OK == GNUNET_STATISTICS_watch (sh,
491 "nse",
492 "# peers connected",
493 stat_iterator,
494 peer));
495}
496
497
498/**
499 * Task run to connect to the NSE and statistics services to a subset of
500 * all of the running peers.
501 */
502static void
503connect_nse_service ()
504{
505 struct NSEPeer *current_peer;
506 unsigned int i;
507 unsigned int connections;
508
509 if (0 == connection_limit)
510 return;
511 LOG_DEBUG ("Connecting to nse service of peers\n");
512 connections = 0;
513 for (i = 0; i < num_peers_in_round[current_round]; i++)
514 {
515 if ((num_peers_in_round[current_round] > connection_limit) &&
516 (0 != (i % (num_peers_in_round[current_round] / connection_limit))))
517 continue;
518 LOG_DEBUG ("Connecting to nse service of peer %d\n", i);
519 current_peer = GNUNET_new (struct NSEPeer);
520 current_peer->daemon = daemons[i];
521 current_peer->nse_op =
522 GNUNET_TESTBED_service_connect (NULL,
523 current_peer->daemon,
524 "nse",
525 NULL,
526 NULL,
527 &nse_connect_adapter,
528 &nse_disconnect_adapter,
529 current_peer);
530 if (NULL != data_file)
531 current_peer->stat_op =
532 GNUNET_TESTBED_service_connect (NULL,
533 current_peer->daemon,
534 "statistics",
535 stat_comp_cb,
536 current_peer,
537 &stat_connect_adapter,
538 &stat_disconnect_adapter,
539 current_peer);
540 GNUNET_CONTAINER_DLL_insert (peer_head, peer_tail, current_peer);
541 if (++connections == connection_limit)
542 break;
543 }
544}
545
546
547/**
548 * Task that starts/stops peers to move to the next round.
549 *
550 * @param cls NULL, unused
551 */
552static void
553next_round (void *cls);
554
555
556/**
557 * We're at the end of a round. Stop monitoring, write total
558 * number of connections to log and get full stats. Then trigger
559 * the next round.
560 *
561 * @param cls unused, NULL
562 */
563static void
564finish_round (void *cls)
565{
566 LOG (GNUNET_ERROR_TYPE_INFO, "Have %u connections\n", total_connections);
567 close_monitor_connections ();
568 round_task = GNUNET_SCHEDULER_add_now (&next_round, NULL);
569}
570
571
572/**
573 * We have reached the desired number of peers for the current round.
574 * Run it (by connecting and monitoring a few peers and waiting the
575 * specified delay before finishing the round).
576 */
577static void
578run_round ()
579{
580 LOG_DEBUG ("Running round %u\n", current_round);
581 connect_nse_service ();
582 GNUNET_SCHEDULER_add_delayed (wait_time, &finish_round, NULL);
583}
584
585
586/**
587 * Creates an oplist entry and adds it to the oplist DLL
588 */
589static struct OpListEntry *
590make_oplist_entry ()
591{
592 struct OpListEntry *entry;
593
594 entry = GNUNET_new (struct OpListEntry);
595 GNUNET_CONTAINER_DLL_insert_tail (oplist_head, oplist_tail, entry);
596 return entry;
597}
598
599
600/**
601 * Callback to be called when NSE service is started or stopped at peers
602 *
603 * @param cls NULL
604 * @param op the operation handle
605 * @param emsg NULL on success; otherwise an error description
606 */
607static void
608manage_service_cb (void *cls,
609 struct GNUNET_TESTBED_Operation *op,
610 const char *emsg)
611{
612 struct OpListEntry *entry = cls;
613
614 GNUNET_TESTBED_operation_done (entry->op);
615 if (NULL != emsg)
616 {
617 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to start/stop NSE at a peer\n");
618 GNUNET_SCHEDULER_shutdown ();
619 return;
620 }
621 GNUNET_assert (0 != entry->delta);
622 peers_running += entry->delta;
623 GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
624 GNUNET_free (entry);
625 if (num_peers_in_round[current_round] == peers_running)
626 run_round ();
627}
628
629
630/**
631 * Adjust the number of running peers to match the required number of running
632 * peers for the round
633 */
634static void
635adjust_running_peers ()
636{
637 struct OpListEntry *entry;
638 unsigned int i;
639
640 /* start peers if we have too few */
641 for (i = peers_running; i < num_peers_in_round[current_round]; i++)
642 {
643 entry = make_oplist_entry ();
644 entry->delta = 1;
645 entry->op = GNUNET_TESTBED_peer_manage_service (NULL,
646 daemons[i],
647 "nse",
648 &manage_service_cb,
649 entry,
650 1);
651 }
652 /* stop peers if we have too many */
653 for (i = num_peers_in_round[current_round]; i < peers_running; i++)
654 {
655 entry = make_oplist_entry ();
656 entry->delta = -1;
657 entry->op = GNUNET_TESTBED_peer_manage_service (NULL,
658 daemons[i],
659 "nse",
660 &manage_service_cb,
661 entry,
662 0);
663 }
664}
665
666
667/**
668 * Task run at the end of a round. Disconnect from all monitored
669 * peers; then get statistics from *all* peers.
670 *
671 * @param cls NULL, unused
672 */
673static void
674next_round (void *cls)
675{
676 round_task = NULL;
677 LOG_DEBUG ("Disconnecting nse service of peers\n");
678 current_round++;
679 if (current_round == num_rounds)
680 {
681 /* this was the last round, terminate */
682 ok = 0;
683 GNUNET_SCHEDULER_shutdown ();
684 return;
685 }
686 if (num_peers_in_round[current_round] == peers_running)
687 {
688 /* no need to churn, just run next round */
689 run_round ();
690 return;
691 }
692 adjust_running_peers ();
693}
694
695
696/**
697 * Function that will be called whenever something in the
698 * testbed changes.
699 *
700 * @param cls closure, NULL
701 * @param event information on what is happening
702 */
703static void
704master_controller_cb (void *cls,
705 const struct GNUNET_TESTBED_EventInformation *event)
706{
707 switch (event->type)
708 {
709 case GNUNET_TESTBED_ET_CONNECT:
710 total_connections++;
711 break;
712
713 case GNUNET_TESTBED_ET_DISCONNECT:
714 total_connections--;
715 break;
716
717 default:
718 break;
719 }
720}
721
722
723/**
724 * Signature of a main function for a testcase.
725 *
726 * @param cls NULL
727 * @param h the run handle
728 * @param num_peers_ number of peers in 'peers'
729 * @param peers handle to peers run in the testbed. NULL upon timeout (see
730 * GNUNET_TESTBED_test_run()).
731 * @param links_succeeded the number of overlay link connection attempts that
732 * succeeded
733 * @param links_failed the number of overlay link connection attempts that
734 * failed
735 */
736static void
737test_master (void *cls,
738 struct GNUNET_TESTBED_RunHandle *h,
739 unsigned int num_peers_,
740 struct GNUNET_TESTBED_Peer **peers,
741 unsigned int links_succeeded,
742 unsigned int links_failed)
743{
744 if (NULL == peers)
745 {
746 GNUNET_SCHEDULER_shutdown ();
747 return;
748 }
749 daemons = peers;
750 GNUNET_break (num_peers_ == num_peers);
751 peers_running = num_peers;
752 if (num_peers_in_round[current_round] == peers_running)
753 {
754 /* no need to churn, just run the starting round */
755 run_round ();
756 return;
757 }
758 adjust_running_peers ();
759}
760
761
762/**
763 * Actual main function that runs the emulation.
764 *
765 * @param cls unused
766 * @param args remaining args, unused
767 * @param cfgfile name of the configuration
768 * @param cfg configuration handle
769 */
770static void
771run (void *cls,
772 char *const *args,
773 const char *cfgfile,
774 const struct GNUNET_CONFIGURATION_Handle *cfg)
775{
776 char *tok;
777 uint64_t event_mask;
778 unsigned int num;
779
780 ok = 1;
781 testing_cfg = GNUNET_CONFIGURATION_dup (cfg);
782 LOG_DEBUG ("Starting daemons.\n");
783 if (NULL == num_peer_spec)
784 {
785 fprintf (stderr, "You need to specify the number of peers to run\n");
786 return;
787 }
788 for (tok = strtok (num_peer_spec, ","); NULL != tok; tok = strtok (NULL, ","))
789 {
790 if (1 != sscanf (tok, "%u", &num))
791 {
792 fprintf (stderr, "You need to specify numbers, not `%s'\n", tok);
793 return;
794 }
795 if (0 == num)
796 {
797 fprintf (stderr, "Refusing to run a round with 0 peers\n");
798 return;
799 }
800 GNUNET_array_append (num_peers_in_round, num_rounds, num);
801 num_peers = GNUNET_MAX (num_peers, num);
802 }
803 if (0 == num_peers)
804 {
805 fprintf (stderr, "Refusing to run a testbed with no rounds\n");
806 return;
807 }
808 if ((NULL != data_filename) &&
809 (NULL ==
810 (data_file = GNUNET_DISK_file_open (data_filename,
811 GNUNET_DISK_OPEN_READWRITE
812 | GNUNET_DISK_OPEN_TRUNCATE
813 | GNUNET_DISK_OPEN_CREATE,
814 GNUNET_DISK_PERM_USER_READ
815 | GNUNET_DISK_PERM_USER_WRITE))))
816 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", data_filename);
817
818 if ((NULL != output_filename) &&
819 (NULL ==
820 (output_file = GNUNET_DISK_file_open (output_filename,
821 GNUNET_DISK_OPEN_READWRITE
822 | GNUNET_DISK_OPEN_CREATE,
823 GNUNET_DISK_PERM_USER_READ
824 | GNUNET_DISK_PERM_USER_WRITE))))
825 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", output_filename);
826 event_mask = 0LL;
827 event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_START);
828 event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_STOP);
829 event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT);
830 event_mask |= (1LL << GNUNET_TESTBED_ET_DISCONNECT);
831 GNUNET_TESTBED_run (hosts_file,
832 cfg,
833 num_peers,
834 event_mask,
835 master_controller_cb,
836 NULL, /* master_controller_cb cls */
837 &test_master,
838 NULL); /* test_master cls */
839 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
840}
841
842
843/**
844 * Main function.
845 *
846 * @return 0 on success
847 */
848int
849main (int argc, char *const *argv)
850{
851 struct GNUNET_GETOPT_CommandLineOption options[] =
852 { GNUNET_GETOPT_option_uint (
853 'C',
854 "connections",
855 "COUNT",
856 gettext_noop (
857 "limit to the number of connections to NSE services, 0 for none"),
858 &connection_limit),
859 GNUNET_GETOPT_option_string (
860 'd',
861 "details",
862 "FILENAME",
863 gettext_noop (
864 "name of the file for writing connection information and statistics"),
865 &data_filename),
866
867 GNUNET_GETOPT_option_string (
868 'H',
869 "hosts",
870 "FILENAME",
871 gettext_noop (
872 "name of the file with the login information for the testbed"),
873 &hosts_file),
874
875 GNUNET_GETOPT_option_string (
876 'o',
877 "output",
878 "FILENAME",
879 gettext_noop ("name of the file for writing the main results"),
880 &output_filename),
881
882
883 GNUNET_GETOPT_option_string (
884 'p',
885 "peers",
886 "NETWORKSIZESPEC",
887 gettext_noop (
888 "Number of peers to run in each round, separated by commas"),
889 &num_peer_spec),
890
891 GNUNET_GETOPT_option_increment_uint (
892 'V',
893 "verbose",
894 gettext_noop ("be verbose (print progress information)"),
895 &verbose),
896
897 GNUNET_GETOPT_option_relative_time ('w',
898 "wait",
899 "DELAY",
900 gettext_noop ("delay between rounds"),
901 &wait_time),
902 GNUNET_GETOPT_OPTION_END };
903
904 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
905 return 2;
906 if (
907 GNUNET_OK !=
908 GNUNET_PROGRAM_run (argc,
909 argv,
910 "nse-profiler",
911 gettext_noop (
912 "Measure quality and performance of the NSE service."),
913 options,
914 &run,
915 NULL))
916 ok = 1;
917 return ok;
918}
919
920
921/* end of nse-profiler.c */
diff --git a/src/service/regex/Makefile.am b/src/service/regex/Makefile.am
index 255988889..0ce42880d 100644
--- a/src/service/regex/Makefile.am
+++ b/src/service/regex/Makefile.am
@@ -52,21 +52,6 @@ libgnunetregex_la_LDFLAGS = \
52 -version-info 3:1:0 52 -version-info 3:1:0
53 53
54 54
55# FIXME we phased out mysql. If we want to keep, needs rewrite
56#if HAVE_MYSQL
57#noinst_mysql_progs = \
58# gnunet-regex-simulation-profiler
59
60#gnunet_regex_simulation_profiler_SOURCES = \
61# $(REGEX_INTERNAL) gnunet-regex-simulation-profiler.c
62#gnunet_regex_simulation_profiler_LDADD = \
63# libgnunetregexblock.la \
64# $(top_builddir)/src/lib/util/libgnunetutil.la \
65# $(top_builddir)/src/service/dht/libgnunetdht.la \
66# $(top_builddir)/src/lib/block/libgnunetblock.la \
67# $(top_builddir)/src/service/statistics/libgnunetstatistics.la
68#endif
69
70noinst_PROGRAMS = $(noinst_mysql_progs) \ 55noinst_PROGRAMS = $(noinst_mysql_progs) \
71 perf-regex 56 perf-regex
72 57
@@ -151,5 +136,4 @@ test_regex_graph_api_LDADD = -lm \
151 136
152 137
153EXTRA_DIST = \ 138EXTRA_DIST = \
154 regex_simulation_profiler_test.conf \
155 test_regex_api_data.conf 139 test_regex_api_data.conf
diff --git a/src/service/regex/gnunet-regex-simulation-profiler.c b/src/service/regex/gnunet-regex-simulation-profiler.c
deleted file mode 100644
index abdb1abeb..000000000
--- a/src/service/regex/gnunet-regex-simulation-profiler.c
+++ /dev/null
@@ -1,727 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011, 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21
22/**
23 * @file regex/gnunet-regex-simulation-profiler.c
24 * @brief Regex profiler that dumps all DFAs into a database instead of
25 * using the DHT (with cadet).
26 * @author Maximilian Szengel
27 * @author Christophe Genevey
28 *
29 */
30
31#include "platform.h"
32#include "gnunet_util_lib.h"
33#include "regex_internal_lib.h"
34#include "gnunet_mysql_lib.h"
35#include "gnunet_mysql_compat.h"
36#include "gnunet_my_lib.h"
37#include <mysql/mysql.h>
38
39/**
40 * MySQL statement to insert an edge.
41 */
42#define INSERT_EDGE_STMT "INSERT IGNORE INTO `%s` " \
43 "(`key`, `label`, `to_key`, `accepting`) " \
44 "VALUES (?, ?, ?, ?);"
45
46/**
47 * MySQL statement to select a key count.
48 */
49#define SELECT_KEY_STMT "SELECT COUNT(*) FROM `%s` " \
50 "WHERE `key` = ? AND `label` = ?;"
51
52/**
53 * Simple struct to keep track of progress, and print a
54 * nice little percentage meter for long running tasks.
55 */
56struct ProgressMeter
57{
58 /**
59 * Total number of elements.
60 */
61 unsigned int total;
62
63 /**
64 * Interval for printing percentage.
65 */
66 unsigned int modnum;
67
68 /**
69 * Number of dots to print.
70 */
71 unsigned int dotnum;
72
73 /**
74 * Completed number.
75 */
76 unsigned int completed;
77
78 /**
79 * Should the meter be printed?
80 */
81 int print;
82
83 /**
84 * String to print on startup.
85 */
86 char *startup_string;
87};
88
89
90/**
91 * Handle for the progress meter
92 */
93static struct ProgressMeter *meter;
94
95/**
96 * Scan task identifier;
97 */
98static struct GNUNET_SCHEDULER_Task *scan_task;
99
100/**
101 * Global testing status.
102 */
103static int result;
104
105/**
106 * MySQL context.
107 */
108static struct GNUNET_MYSQL_Context *mysql_ctx;
109
110/**
111 * MySQL prepared statement handle.
112 */
113static struct GNUNET_MYSQL_StatementHandle *stmt_handle;
114
115/**
116 * MySQL prepared statement handle for `key` select.
117 */
118static struct GNUNET_MYSQL_StatementHandle *select_stmt_handle;
119
120/**
121 * MySQL table name.
122 */
123static char *table_name;
124
125/**
126 * Policy dir containing files that contain policies.
127 */
128static char *policy_dir;
129
130/**
131 * Number of policy files.
132 */
133static unsigned int num_policy_files;
134
135/**
136 * Number of policies.
137 */
138static unsigned int num_policies;
139
140/**
141 * Maximal path compression length.
142 */
143static unsigned int max_path_compression;
144
145/**
146 * Number of merged transitions.
147 */
148static unsigned long long num_merged_transitions;
149
150/**
151 * Number of merged states from different policies.
152 */
153static unsigned long long num_merged_states;
154
155/**
156 * Prefix to add before every regex we're announcing.
157 */
158static char *regex_prefix;
159
160
161/**
162 * Create a meter to keep track of the progress of some task.
163 *
164 * @param total the total number of items to complete
165 * @param start_string a string to prefix the meter with (if printing)
166 * @param print GNUNET_YES to print the meter, GNUNET_NO to count
167 * internally only
168 *
169 * @return the progress meter
170 */
171static struct ProgressMeter *
172create_meter (unsigned int total, char *start_string, int print)
173{
174 struct ProgressMeter *ret;
175
176 ret = GNUNET_new (struct ProgressMeter);
177 ret->print = print;
178 ret->total = total;
179 ret->modnum = total / 4;
180 if (ret->modnum == 0) /* Divide by zero check */
181 ret->modnum = 1;
182 ret->dotnum = (total / 50) + 1;
183 if (start_string != NULL)
184 ret->startup_string = GNUNET_strdup (start_string);
185 else
186 ret->startup_string = GNUNET_strdup ("");
187
188 return ret;
189}
190
191
192/**
193 * Update progress meter (increment by one).
194 *
195 * @param meter the meter to update and print info for
196 *
197 * @return GNUNET_YES if called the total requested,
198 * GNUNET_NO if more items expected
199 */
200static int
201update_meter (struct ProgressMeter *meter)
202{
203 if (meter->print == GNUNET_YES)
204 {
205 if (meter->completed % meter->modnum == 0)
206 {
207 if (meter->completed == 0)
208 {
209 fprintf (stdout, "%sProgress: [0%%", meter->startup_string);
210 }
211 else
212 fprintf (stdout, "%d%%",
213 (int) (((float) meter->completed / meter->total) * 100));
214 }
215 else if (meter->completed % meter->dotnum == 0)
216 fprintf (stdout, "%s", ".");
217
218 if (meter->completed + 1 == meter->total)
219 fprintf (stdout, "%d%%]\n", 100);
220 fflush (stdout);
221 }
222 meter->completed++;
223
224 if (meter->completed == meter->total)
225 return GNUNET_YES;
226 if (meter->completed > meter->total)
227 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Progress meter overflow!!\n");
228 return GNUNET_NO;
229}
230
231
232/**
233 * Reset progress meter.
234 *
235 * @param meter the meter to reset
236 *
237 * @return #GNUNET_YES if meter reset,
238 * #GNUNET_SYSERR on error
239 */
240static int
241reset_meter (struct ProgressMeter *meter)
242{
243 if (meter == NULL)
244 return GNUNET_SYSERR;
245
246 meter->completed = 0;
247 return GNUNET_YES;
248}
249
250
251/**
252 * Release resources for meter
253 *
254 * @param meter the meter to free
255 */
256static void
257free_meter (struct ProgressMeter *meter)
258{
259 GNUNET_free (meter->startup_string);
260 GNUNET_free (meter);
261}
262
263
264/**
265 * Shutdown task.
266 *
267 * @param cls NULL
268 */
269static void
270do_shutdown (void *cls)
271{
272 if (NULL != mysql_ctx)
273 {
274 GNUNET_MYSQL_context_destroy (mysql_ctx);
275 mysql_ctx = NULL;
276 }
277 if (NULL != meter)
278 {
279 free_meter (meter);
280 meter = NULL;
281 }
282}
283
284
285/**
286 * Abort task to run on test timed out.
287 *
288 * FIXME: this doesn't actually work, it used to cancel
289 * the already running 'scan_task', but now that should
290 * always be NULL and do nothing. We instead need to set
291 * a global variable and abort scan_task internally, not
292 * via scheduler.
293 *
294 * @param cls NULL
295 */
296static void
297do_abort (void *cls)
298{
299 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Aborting\n");
300 if (NULL != scan_task)
301 {
302 GNUNET_SCHEDULER_cancel (scan_task);
303 scan_task = NULL;
304 }
305 result = GNUNET_SYSERR;
306 GNUNET_SCHEDULER_shutdown ();
307}
308
309
310/**
311 * Iterator over all states that inserts each state into the MySQL db.
312 *
313 * @param cls closure.
314 * @param key hash for current state.
315 * @param proof proof for current state.
316 * @param accepting #GNUNET_YES if this is an accepting state, #GNUNET_NO if not.
317 * @param num_edges number of edges leaving current state.
318 * @param edges edges leaving current state.
319 */
320static void
321regex_iterator (void *cls,
322 const struct GNUNET_HashCode *key,
323 const char *proof,
324 int accepting,
325 unsigned int num_edges,
326 const struct REGEX_BLOCK_Edge *edges)
327{
328 unsigned int i;
329 int result;
330
331 uint32_t iaccepting = (uint32_t) accepting;
332 uint64_t total;
333
334 GNUNET_assert (NULL != mysql_ctx);
335
336 for (i = 0; i < num_edges; i++)
337 {
338 struct GNUNET_MY_QueryParam params_select[] = {
339 GNUNET_MY_query_param_auto_from_type (key),
340 GNUNET_MY_query_param_string (edges[i].label),
341 GNUNET_MY_query_param_end
342 };
343
344 struct GNUNET_MY_ResultSpec results_select[] = {
345 GNUNET_MY_result_spec_uint64 (&total),
346 GNUNET_MY_result_spec_end
347 };
348
349 result =
350 GNUNET_MY_exec_prepared (mysql_ctx,
351 select_stmt_handle,
352 params_select);
353
354 if (GNUNET_SYSERR == result)
355 {
356 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
357 "Error executing prepared mysql select statement\n");
358 GNUNET_SCHEDULER_add_now (&do_abort, NULL);
359 return;
360 }
361
362 result =
363 GNUNET_MY_extract_result (select_stmt_handle,
364 results_select);
365
366 if (GNUNET_SYSERR == result)
367 {
368 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
369 "Error extracting result mysql select statement\n");
370 GNUNET_SCHEDULER_add_now (&do_abort, NULL);
371 return;
372 }
373
374 if ((-1 != total) && (total > 0) )
375 {
376 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Total: %llu (%s, %s)\n",
377 (unsigned long long) total,
378 GNUNET_h2s (key), edges[i].label);
379 }
380
381 struct GNUNET_MY_QueryParam params_stmt[] = {
382 GNUNET_MY_query_param_auto_from_type (&key),
383 GNUNET_MY_query_param_string (edges[i].label),
384 GNUNET_MY_query_param_auto_from_type (&edges[i].destination),
385 GNUNET_MY_query_param_uint32 (&iaccepting),
386 GNUNET_MY_query_param_end
387 };
388
389 result =
390 GNUNET_MY_exec_prepared (mysql_ctx,
391 stmt_handle,
392 params_stmt);
393
394 if (0 == result)
395 {
396 char *key_str = GNUNET_strdup (GNUNET_h2s (key));
397 char *to_key_str = GNUNET_strdup (GNUNET_h2s (&edges[i].destination));
398
399 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Merged (%s, %s, %s, %i)\n",
400 key_str,
401 edges[i].label,
402 to_key_str,
403 accepting);
404
405 GNUNET_free (key_str);
406 GNUNET_free (to_key_str);
407 num_merged_transitions++;
408 }
409 else if (-1 != total)
410 {
411 num_merged_states++;
412 }
413
414 if ((GNUNET_SYSERR == result) || ((1 != result) && (0 != result) ))
415 {
416 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
417 "Error executing prepared mysql statement for edge: Affected rows: %i, expected 0 or 1!\n",
418 result);
419 GNUNET_SCHEDULER_add_now (&do_abort, NULL);
420 }
421 }
422
423 if (0 == num_edges)
424 {
425 struct GNUNET_MY_QueryParam params_stmt[] = {
426 GNUNET_MY_query_param_auto_from_type (key),
427 GNUNET_MY_query_param_string (""),
428 GNUNET_MY_query_param_fixed_size (NULL, 0),
429 GNUNET_MY_query_param_uint32 (&iaccepting),
430 GNUNET_MY_query_param_end
431 };
432
433 result =
434 GNUNET_MY_exec_prepared (mysql_ctx,
435 stmt_handle,
436 params_stmt);
437
438 if ((1 != result) && (0 != result) )
439 {
440 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
441 "Error executing prepared mysql statement for edge: Affected rows: %i, expected 0 or 1!\n",
442 result);
443 GNUNET_SCHEDULER_add_now (&do_abort, NULL);
444 }
445 }
446}
447
448
449/**
450 * Announce a regex by creating the DFA and iterating over each state, inserting
451 * each state into a MySQL database.
452 *
453 * @param regex regular expression.
454 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure.
455 */
456static int
457announce_regex (const char *regex)
458{
459 struct REGEX_INTERNAL_Automaton *dfa;
460
461 dfa =
462 REGEX_INTERNAL_construct_dfa (regex,
463 strlen (regex),
464 max_path_compression);
465
466 if (NULL == dfa)
467 {
468 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
469 "Failed to create DFA for regex %s\n",
470 regex);
471 GNUNET_SCHEDULER_add_now (&do_abort, NULL);
472 return GNUNET_SYSERR;
473 }
474 REGEX_INTERNAL_iterate_all_edges (dfa,
475 &regex_iterator, NULL);
476 REGEX_INTERNAL_automaton_destroy (dfa);
477
478 return GNUNET_OK;
479}
480
481
482/**
483 * Function called with a filename.
484 *
485 * @param cls closure
486 * @param filename complete filename (absolute path)
487 * @return #GNUNET_OK to continue to iterate,
488 * #GNUNET_SYSERR to abort iteration with error!
489 */
490static int
491policy_filename_cb (void *cls, const char *filename)
492{
493 char *regex;
494 char *data;
495 char *buf;
496 uint64_t filesize;
497 unsigned int offset;
498
499 GNUNET_assert (NULL != filename);
500
501 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
502 "Announcing regexes from file %s\n",
503 filename);
504
505 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
506 {
507 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
508 "Could not find policy file %s\n",
509 filename);
510 return GNUNET_OK;
511 }
512 if (GNUNET_OK !=
513 GNUNET_DISK_file_size (filename, &filesize,
514 GNUNET_YES, GNUNET_YES))
515 filesize = 0;
516 if (0 == filesize)
517 {
518 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Policy file %s is empty.\n",
519 filename);
520 return GNUNET_OK;
521 }
522 data = GNUNET_malloc (filesize);
523 if (filesize != GNUNET_DISK_fn_read (filename, data, filesize))
524 {
525 GNUNET_free (data);
526 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
527 "Could not read policy file %s.\n",
528 filename);
529 return GNUNET_OK;
530 }
531
532 update_meter (meter);
533
534 buf = data;
535 offset = 0;
536 regex = NULL;
537 while (offset < (filesize - 1))
538 {
539 offset++;
540 if (((data[offset] == '\n')) && (buf != &data[offset]))
541 {
542 data[offset] = '|';
543 num_policies++;
544 buf = &data[offset + 1];
545 }
546 else if ((data[offset] == '\n') || (data[offset] == '\0'))
547 buf = &data[offset + 1];
548 }
549 data[offset] = '\0';
550 GNUNET_asprintf (&regex, "%s(%s)", regex_prefix, data);
551 GNUNET_assert (NULL != regex);
552 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
553 "Announcing regex: %s\n", regex);
554
555 if (GNUNET_OK != announce_regex (regex))
556 {
557 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
558 "Could not announce regex %s\n",
559 regex);
560 }
561 GNUNET_free (regex);
562 GNUNET_free (data);
563 return GNUNET_OK;
564}
565
566
567/**
568 * Iterate over files contained in policy_dir.
569 *
570 * @param cls NULL
571 */
572static void
573do_directory_scan (void *cls)
574{
575 struct GNUNET_TIME_Absolute start_time;
576 struct GNUNET_TIME_Relative duration;
577 char *stmt;
578
579 /* Create an MySQL prepared statement for the inserts */
580 scan_task = NULL;
581 GNUNET_asprintf (&stmt, INSERT_EDGE_STMT, table_name);
582 stmt_handle = GNUNET_MYSQL_statement_prepare (mysql_ctx, stmt);
583 GNUNET_free (stmt);
584
585 GNUNET_asprintf (&stmt, SELECT_KEY_STMT, table_name);
586 select_stmt_handle = GNUNET_MYSQL_statement_prepare (mysql_ctx, stmt);
587 GNUNET_free (stmt);
588
589 GNUNET_assert (NULL != stmt_handle);
590
591 meter = create_meter (num_policy_files,
592 "Announcing policy files\n",
593 GNUNET_YES);
594 start_time = GNUNET_TIME_absolute_get ();
595 GNUNET_DISK_directory_scan (policy_dir,
596 &policy_filename_cb,
597 stmt_handle);
598 duration = GNUNET_TIME_absolute_get_duration (start_time);
599 reset_meter (meter);
600 free_meter (meter);
601 meter = NULL;
602
603 printf ("Announced %u files containing %u policies in %s\n"
604 "Duplicate transitions: %llu\nMerged states: %llu\n",
605 num_policy_files,
606 num_policies,
607 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_NO),
608 num_merged_transitions,
609 num_merged_states);
610 result = GNUNET_OK;
611 GNUNET_SCHEDULER_shutdown ();
612}
613
614
615/**
616 * Main function that will be run by the scheduler.
617 *
618 * @param cls closure
619 * @param args remaining command-line arguments
620 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
621 * @param config configuration
622 */
623static void
624run (void *cls,
625 char *const *args,
626 const char *cfgfile,
627 const struct GNUNET_CONFIGURATION_Handle *config)
628{
629 if (NULL == args[0])
630 {
631 fprintf (stderr,
632 _ ("No policy directory specified on command line. Exiting.\n"));
633 result = GNUNET_SYSERR;
634 return;
635 }
636 if (GNUNET_YES !=
637 GNUNET_DISK_directory_test (args[0], GNUNET_YES))
638 {
639 fprintf (stderr,
640 _ ("Specified policies directory does not exist. Exiting.\n"));
641 result = GNUNET_SYSERR;
642 return;
643 }
644 policy_dir = args[0];
645
646 num_policy_files = GNUNET_DISK_directory_scan (policy_dir,
647 NULL, NULL);
648 meter = NULL;
649
650 if (NULL == table_name)
651 {
652 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
653 "No table name specified, using default \"NFA\".\n");
654 table_name = "NFA";
655 }
656
657 mysql_ctx = GNUNET_MYSQL_context_create (config, "regex-mysql");
658 if (NULL == mysql_ctx)
659 {
660 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
661 "Failed to create mysql context\n");
662 result = GNUNET_SYSERR;
663 return;
664 }
665
666 if (GNUNET_OK !=
667 GNUNET_CONFIGURATION_get_value_string (config,
668 "regex-mysql",
669 "REGEX_PREFIX",
670 &regex_prefix))
671 {
672 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
673 "regex-mysql",
674 "REGEX_PREFIX");
675 result = GNUNET_SYSERR;
676 return;
677 }
678
679 result = GNUNET_OK;
680 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
681 NULL);
682 scan_task = GNUNET_SCHEDULER_add_now (&do_directory_scan, NULL);
683}
684
685
686/**
687 * Main function.
688 *
689 * @param argc argument count
690 * @param argv argument values
691 * @return 0 on success
692 */
693int
694main (int argc, char *const *argv)
695{
696 struct GNUNET_GETOPT_CommandLineOption options[] = {
697 GNUNET_GETOPT_option_string ('t',
698 "table",
699 "TABLENAME",
700 gettext_noop (
701 "name of the table to write DFAs"),
702 &table_name),
703
704 GNUNET_GETOPT_option_uint ('p',
705 "max-path-compression",
706 "MAX_PATH_COMPRESSION",
707 gettext_noop ("maximum path compression length"),
708 &max_path_compression),
709
710 GNUNET_GETOPT_OPTION_END
711 };
712 int ret;
713
714 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
715 return 2;
716
717 result = GNUNET_SYSERR;
718 ret =
719 GNUNET_PROGRAM_run (argc, argv,
720 "gnunet-regex-simulationprofiler [OPTIONS] policy-dir",
721 _ ("Profiler for regex library"), options, &run, NULL);
722 if (GNUNET_OK != ret)
723 return ret;
724 if (GNUNET_OK != result)
725 return 1;
726 return 0;
727}
diff --git a/src/service/regex/regex_simulation_profiler_test.conf b/src/service/regex/regex_simulation_profiler_test.conf
deleted file mode 100644
index 9384aa249..000000000
--- a/src/service/regex/regex_simulation_profiler_test.conf
+++ /dev/null
@@ -1,7 +0,0 @@
1[regex-mysql]
2DATABASE = regex
3USER = gnunet
4PASSWORD =
5HOST = localhost
6PORT = 3306
7REGEX_PREFIX = GNVPN-0001-PAD