GNUnet 0.22.2
gnunet-regex-profiler.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011 - 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
27#include "platform.h"
28#include "gnunet_applications.h"
29#include "gnunet_util_lib.h"
30#include "regex_internal_lib.h"
31#include "gnunet_arm_service.h"
32#include "gnunet_dht_service.h"
33#include "gnunet_testbed_service.h"
34
35#define FIND_TIMEOUT \
36 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 90)
37
42{
46 struct GNUNET_TESTBED_Operation *op;
47
51 void *cls;
52
57
62};
63
64
69{
74
79
84
89
94
99
106
107
112{
116 unsigned int id;
117
122
126 struct GNUNET_TESTBED_Peer *peer_handle;
127
131 const char *search_str;
132
140
145
150
154 struct GNUNET_TESTBED_Operation *op_handle;
155
160
165
170
174 struct GNUNET_TESTBED_Operation *daemon_op;
175};
176
180static int in_shutdown;
181
185static struct RegexPeer *peers;
186
190static struct GNUNET_TESTBED_HostRegistrationHandle *reg_handle;
191
195static struct GNUNET_TESTBED_ControllerProc *mc_proc;
196
200static struct GNUNET_TESTBED_Controller *mc;
201
206
211
216
220static uint64_t event_mask;
221
226
231
235static unsigned int num_peers;
236
240static int result;
241
246
250static char *policy_dir;
251
255static char *hosts_file;
256
260static char *strings_file;
261
265static char **search_strings;
266
270static long long unsigned int init_parallel_searches;
271
275static unsigned int parallel_searches;
276
280static unsigned int strings_found;
281
285static unsigned int next_search;
286
291
296
301
305static char *data_filename;
306
311static char *regex_prefix;
312
317
318
319/******************************************************************************/
320/****************************** DECLARATIONS ********************************/
321/******************************************************************************/
322
333static void
334dht_connect_cb (void *cls, struct GNUNET_TESTBED_Operation *op,
335 void *ca_result, const char *emsg);
336
345static void *
346dht_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg);
347
348
356static void
357dht_da (void *cls, void *op_result);
358
359
369static void
370stats_connect_cb (void *cls,
371 struct GNUNET_TESTBED_Operation *op,
372 void *ca_result,
373 const char *emsg);
374
375
381static void
382announce_next_regex (void *cls);
383
384
385/******************************************************************************/
386/******************************** SHUTDOWN **********************************/
387/******************************************************************************/
388
389
395static void
396do_shutdown (void *cls)
397{
398 struct RegexPeer *peer;
399 unsigned int peer_cnt;
400 unsigned int search_str_cnt;
401 char output_buffer[512];
402 size_t size;
403
404 if (NULL != abort_task)
405 {
407 abort_task = NULL;
408 }
409 if (NULL != register_hosts_task)
410 {
412 register_hosts_task = NULL;
413 }
414 for (peer_cnt = 0; peer_cnt < num_peers; peer_cnt++)
415 {
416 peer = &peers[peer_cnt];
417
418 if ((GNUNET_YES != peer->search_str_matched) && (NULL != data_file) )
419 {
421 size =
422 GNUNET_snprintf (output_buffer,
423 sizeof(output_buffer),
424 "%p Search string not found: %s (%d)\n"
425 "%p On peer: %u (%p)\n"
426 "%p After: %s\n",
427 peer, peer->search_str, peer->search_str_matched,
428 peer, peer->id, peer,
429 peer,
431 GNUNET_NO));
432 if (size != GNUNET_DISK_file_write (data_file, output_buffer, size))
433 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to write to file!\n");
434 }
435
436 if (NULL != peers[peer_cnt].op_handle)
437 GNUNET_TESTBED_operation_done (peers[peer_cnt].op_handle);
438 }
439
440 if (NULL != data_file)
441 {
443 data_file = NULL;
444 }
445 for (search_str_cnt = 0;
446 search_str_cnt < num_peers && NULL != search_strings;
447 search_str_cnt++)
448 {
449 GNUNET_free (search_strings[search_str_cnt]);
450 }
452 search_strings = NULL;
453
454 if (NULL != reg_handle)
455 {
456 GNUNET_TESTBED_cancel_registration (reg_handle);
457 reg_handle = NULL;
458 }
459 if (NULL != mc)
460 {
461 GNUNET_TESTBED_controller_disconnect (mc);
462 mc = NULL;
463 }
464 if (NULL != mc_proc)
465 {
466 GNUNET_TESTBED_controller_stop (mc_proc);
467 mc_proc = NULL;
468 }
469 if (NULL != cfg)
470 {
472 cfg = NULL;
473 }
474}
475
476
482static void
483do_abort (void *cls)
484{
485 unsigned long i = (unsigned long) cls;
486
488 "Aborting from line %lu...\n", i);
489 abort_task = NULL;
492}
493
494
495/******************************************************************************/
496/********************* STATISTICS SERVICE CONNECTIONS ***********************/
497/******************************************************************************/
498
509static void *
510stats_ca (void *cls,
511 const struct GNUNET_CONFIGURATION_Handle *cfg)
512{
513 return GNUNET_STATISTICS_create ("<driver>", cfg);
514}
515
516
524static void
525stats_da (void *cls, void *op_result)
526{
527 struct RegexPeer *peer = cls;
528
529 GNUNET_assert (op_result == peer->stats_handle);
530
532 peer->stats_handle = NULL;
533}
534
535
546static int
547stats_iterator (void *cls,
548 const char *subsystem,
549 const char *name,
550 uint64_t value, int is_persistent)
551{
552 struct RegexPeer *peer = cls;
553 char output_buffer[512];
554 size_t size;
555
556 if (NULL == data_file)
557 {
559 "%p -> %s [%s]: %llu\n",
560 peer,
561 subsystem,
562 name,
563 (unsigned long long) value);
564 return GNUNET_OK;
565 }
566 size =
567 GNUNET_snprintf (output_buffer,
568 sizeof(output_buffer),
569 "%p [%s] %llu %s\n",
570 peer,
571 subsystem,
572 (unsigned long long) value,
573 name);
574 if (size != GNUNET_DISK_file_write (data_file, output_buffer, size))
576 "Unable to write to file!\n");
577
578 return GNUNET_OK;
579}
580
581
590static void
591stats_cb (void *cls,
592 int success)
593{
594 static unsigned int peer_cnt;
595 struct RegexPeer *peer = cls;
596
597 if (GNUNET_OK != success)
598 {
600 "Getting statistics for peer %u failed!\n",
601 peer->id);
602 return;
603 }
604
605 GNUNET_assert (NULL != peer->op_handle);
606
607 GNUNET_TESTBED_operation_done (peer->op_handle);
608 peer->op_handle = NULL;
609
610 peer_cnt++;
611 peer = &peers[peer_cnt];
612
613 fprintf (stderr, "s");
614 if (peer_cnt == num_peers)
615 {
617 "\nCollecting stats finished. Shutting down.\n");
620 }
621 else
622 {
623 peer->op_handle =
624 GNUNET_TESTBED_service_connect (NULL,
625 peer->peer_handle,
626 "statistics",
628 peer,
629 &stats_ca,
630 &stats_da,
631 peer);
632 }
633}
634
635
645static void
647 struct GNUNET_TESTBED_Operation *op,
648 void *ca_result,
649 const char *emsg)
650{
651 struct RegexPeer *peer = cls;
652
653 if ((NULL == ca_result) || (NULL != emsg))
654 {
656 "Failed to connect to statistics service on peer %u: %s\n",
657 peer->id, emsg);
658
659 peer->stats_handle = NULL;
660 return;
661 }
662
663 peer->stats_handle = ca_result;
664
665 if (NULL == GNUNET_STATISTICS_get (peer->stats_handle, NULL, NULL,
666 &stats_cb,
667 &stats_iterator, peer))
668 {
670 "Could not get statistics of peer %u!\n", peer->id);
671 }
672}
673
674
681static void
683{
684 struct RegexPeer *peer = &peers[0];
685
686 GNUNET_assert (NULL != peer->peer_handle);
687
688 peer->op_handle =
689 GNUNET_TESTBED_service_connect (NULL,
690 peer->peer_handle,
691 "statistics",
693 peer,
694 &stats_ca,
695 &stats_da,
696 peer);
697}
698
699
700/******************************************************************************/
701/************************ REGEX FIND CONNECTIONS **************************/
702/******************************************************************************/
703
704
710static void
711find_string (void *cls);
712
713
725static void
727 const struct GNUNET_PeerIdentity *id,
728 const struct GNUNET_DHT_PathElement *get_path,
729 unsigned int get_path_length,
730 const struct GNUNET_DHT_PathElement *put_path,
731 unsigned int put_path_length)
732{
733 struct RegexPeer *peer = cls;
734 char output_buffer[512];
735 size_t size;
736
737 if (GNUNET_YES == peer->search_str_matched)
738 {
740 "String %s on peer %u already matched!\n",
741 peer->search_str, peer->id);
742 return;
743 }
744
747
748 if (NULL != peer->timeout)
749 {
751 peer->timeout = NULL;
752 if (GNUNET_NO == in_shutdown)
754 }
755
756 if (NULL == id)
757 {
758 // FIXME not possible right now
760 "String matching timed out for string %s on peer %u (%i/%i)\n",
761 peer->search_str, peer->id, strings_found, num_peers);
763 }
764 else
765 {
767
769 "String %s found on peer %u after %s (%i/%i) (%u||)\n",
770 peer->search_str, peer->id,
773
775
776 if (NULL != data_file)
777 {
778 size =
779 GNUNET_snprintf (output_buffer,
780 sizeof(output_buffer),
781 "%p Peer: %u\n"
782 "%p Search string: %s\n"
783 "%p Search duration: %s\n\n",
784 peer, peer->id,
785 peer, peer->search_str,
786 peer,
788 GNUNET_NO));
789
790 if (size != GNUNET_DISK_file_write (data_file, output_buffer, size))
791 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to write to file!\n");
792 }
793 }
794
795 GNUNET_TESTBED_operation_done (peer->op_handle);
796 peer->op_handle = NULL;
797
799 {
802 "All strings successfully matched in %s\n",
804
805 if (NULL != search_timeout_task)
806 {
808 search_timeout_task = NULL;
809 }
810
811 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Collecting stats.\n");
813 }
814}
815
816
823static void
825{
826 unsigned int i;
827
829 "Finding matches to all strings did not succeed after %s.\n",
831 GNUNET_NO));
833 "Found %i of %i strings\n", strings_found, num_peers);
834
836 "Search timed out after %s."
837 "Collecting stats and shutting down.\n",
839 GNUNET_NO));
840
842 for (i = 0; i < num_peers; i++)
843 {
844 if (NULL != peers[i].op_handle)
845 {
846 GNUNET_TESTBED_operation_done (peers[i].op_handle);
847 peers[i].op_handle = NULL;
848 }
849 }
851}
852
853
860static void
861find_timed_out (void *cls)
862{
863 struct RegexPeer *p = cls;
864
865 p->timeout = NULL;
867 "Searching for string \"%s\" on peer %d timed out.\n",
868 p->search_str,
869 p->id);
870 if (GNUNET_NO == in_shutdown)
872}
873
874
880static void
881find_string (void *cls)
882{
883 unsigned int search_peer = (unsigned int) (long) cls;
884
885 if ((search_peer >= num_peers) ||
887 return;
888
890 "Searching for string \"%s\" on peer %d (%u||)\n",
891 peers[search_peer].search_str,
892 search_peer,
894
895 peers[search_peer].op_handle =
896 GNUNET_TESTBED_service_connect (NULL,
897 peers[search_peer].peer_handle,
898 "dht",
900 &peers[search_peer],
901 &dht_ca,
902 &dht_da,
903 &peers[search_peer]);
904 GNUNET_assert (NULL != peers[search_peer].op_handle);
905 peers[search_peer].timeout
908 &peers[search_peer]);
909}
910
911
919static void
920daemon_started (void *cls,
921 struct GNUNET_TESTBED_Operation *op,
922 const char *emsg)
923{
924 struct RegexPeer *peer = (struct RegexPeer *) cls;
925 unsigned long search_peer;
926 unsigned int i;
927
928 GNUNET_TESTBED_operation_done (peer->daemon_op);
929 peer->daemon_op = NULL;
930 if (NULL != emsg)
931 {
933 "Failed to start/stop daemon at peer %u: %s\n", peer->id, emsg);
934 GNUNET_assert (0);
935 }
936 else
937 {
939 "Daemon %u started successfully\n", peer->id);
940 }
941
942 /* Find a peer to look for a string matching the regex announced */
944 num_peers);
945 for (i = 0; peers[search_peer].search_str != NULL; i++)
946 {
947 search_peer = (search_peer + 1) % num_peers;
948 if (i > num_peers)
949 GNUNET_assert (0); /* we ran out of peers, must be a bug */
950 }
951 peers[search_peer].search_str = search_strings[peer->id];
952 peers[search_peer].search_str_matched = GNUNET_NO;
955 2),
957 (void *) search_peer);
958}
959
960
967static void
968do_announce (void *cls)
969{
970 unsigned int i;
971
972 if (GNUNET_YES == in_shutdown)
973 return;
975 "Starting announce.\n");
976 for (i = 0; i < init_parallel_searches; i++)
977 {
979 " scheduling announce %u\n",
980 i);
982 }
983}
984
985
991static void
993{
994 struct RegexPeer *peer;
995
996 if (GNUNET_YES == in_shutdown)
997 return;
998 if (next_search >= num_peers)
999 {
1000 if (strings_found != num_peers)
1001 {
1002 struct GNUNET_TIME_Relative new_delay;
1003 if (NULL != search_timeout_task)
1008 NULL);
1009 }
1010 return;
1011 }
1012
1013 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting daemon %u\n", next_search);
1014 peer = &peers[next_search];
1015 peer->daemon_op =
1016 GNUNET_TESTBED_peer_manage_service (NULL,
1017 peer->peer_handle,
1018 "regexprofiler",
1020 peer,
1021 1);
1022 next_search++;
1024}
1025
1026
1027static void
1029 struct GNUNET_TESTBED_Operation *op,
1030 void *ca_result,
1031 const char *emsg)
1032{
1033 struct RegexPeer *peer = (struct RegexPeer *) cls;
1034
1035 if ((NULL != emsg) || (NULL == op) || (NULL == ca_result))
1036 {
1037 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "DHT connect failed: %s\n", emsg);
1038 GNUNET_assert (0);
1039 }
1040
1041 GNUNET_assert (NULL != peer->dht_handle);
1042 GNUNET_assert (peer->op_handle == op);
1043 GNUNET_assert (peer->dht_handle == ca_result);
1044
1047 peer->search_str,
1048 &regex_found_handler, peer,
1049 NULL);
1051}
1052
1053
1054static void *
1055dht_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
1056{
1057 struct RegexPeer *peer = cls;
1058
1059 peer->dht_handle = GNUNET_DHT_connect (cfg, 32);
1060
1061 return peer->dht_handle;
1062}
1063
1064
1065static void
1066dht_da (void *cls, void *op_result)
1067{
1068 struct RegexPeer *peer = (struct RegexPeer *) cls;
1069
1070 GNUNET_assert (peer->dht_handle == op_result);
1071
1072 if (NULL != peer->search_handle)
1073 {
1075 peer->search_handle = NULL;
1076 }
1077
1078 if (NULL != peer->dht_handle)
1079 {
1081 peer->dht_handle = NULL;
1082 }
1083}
1084
1085
1099static void
1100test_master (void *cls,
1101 struct GNUNET_TESTBED_RunHandle *h,
1102 unsigned int num_peers_,
1103 struct GNUNET_TESTBED_Peer **testbed_peers,
1104 unsigned int links_succeeded,
1105 unsigned int links_failed)
1106{
1107 unsigned int i;
1108
1109 GNUNET_assert (num_peers_ == num_peers);
1110
1113 "Testbed started in %s\n",
1115
1116 if (NULL != abort_task)
1117 {
1119 abort_task = NULL;
1120 }
1121
1122 for (i = 0; i < num_peers; i++)
1123 {
1124 peers[i].peer_handle = testbed_peers[i];
1125 }
1126 if (GNUNET_NO ==
1127 GNUNET_CONFIGURATION_get_value_yesno (cfg, "DHT", "DISABLE_TRY_CONNECT"))
1128 {
1129 struct GNUNET_TIME_Relative settle_time;
1130
1131 settle_time =
1133 10 * num_peers);
1135 "Waiting for DHT for %s to settle new connections.\n\n",
1137 GNUNET_NO));
1138 GNUNET_SCHEDULER_add_delayed (settle_time, &do_announce, NULL);
1139 }
1140 else
1141 {
1143 }
1146}
1147
1148
1155static void
1157 const struct GNUNET_TESTBED_EventInformation *event)
1158{
1159 switch (event->type)
1160 {
1161 case GNUNET_TESTBED_ET_CONNECT:
1162 printf (".");
1163 break;
1164
1165 case GNUNET_TESTBED_ET_PEER_START:
1166 printf ("#");
1167 break;
1168
1169 default:
1170 break;
1171 }
1172 fflush (stdout);
1173}
1174
1175
1176/******************************************************************************/
1177/*************************** TESTBED PEER SETUP *****************************/
1178/******************************************************************************/
1179
1190static int
1192 uint64_t data_size,
1193 unsigned int str_max)
1194{
1195 char *buf; // Keep track of last string to skip blank lines
1196 unsigned int offset;
1197 unsigned int str_cnt;
1198
1199 buf = data;
1200 offset = 0;
1201 str_cnt = 0;
1202 while ((offset < (data_size - 1)) && (str_cnt < str_max))
1203 {
1204 offset++;
1205 if (((data[offset] == '\n')) &&
1206 (buf != &data[offset]))
1207 {
1208 data[offset] = '\0';
1209 str_cnt++;
1210 buf = &data[offset + 1];
1211 }
1212 else if ((data[offset] == '\n') ||
1213 (data[offset] == '\0'))
1214 buf = &data[offset + 1];
1215 }
1216 return str_cnt;
1217}
1218
1219
1233static int
1235 char ***strings, unsigned int str_cnt)
1236{
1237 uint64_t offset;
1238 uint64_t len;
1239 unsigned int i;
1240
1241 *strings = GNUNET_malloc (sizeof(char *) * str_cnt);
1242 offset = 0;
1243 for (i = 0; i < str_cnt; i++)
1244 {
1245 len = strlen (&data[offset]);
1246 if (offset + len >= data_size)
1247 {
1248 GNUNET_free (*strings);
1249 *strings = NULL;
1250 return GNUNET_SYSERR;
1251 }
1252 if (0 == len) // empty line
1253 {
1254 offset++;
1255 i--;
1256 continue;
1257 }
1258
1259 GNUNET_asprintf (&(*strings)[i],
1260 "%s%s",
1262 &data[offset]);
1263 offset += len + 1;
1264 }
1265 return GNUNET_OK;
1266}
1267
1268
1278static int
1280 char ***strings,
1281 unsigned int limit)
1282{
1283 char *data;
1284 uint64_t filesize;
1285 int str_cnt;
1286
1287 /* Sanity checks */
1288 if (NULL == filename)
1289 {
1290 return GNUNET_SYSERR;
1291 }
1293 {
1295 "Could not find search strings file %s\n", filename);
1296 return GNUNET_SYSERR;
1297 }
1298 if (GNUNET_OK !=
1300 &filesize,
1301 GNUNET_YES,
1302 GNUNET_YES))
1303 {
1305 "Search strings file %s cannot be read.\n",
1306 filename);
1307 return GNUNET_SYSERR;
1308 }
1309 if (0 == filesize)
1310 {
1312 "Search strings file %s is empty.\n",
1313 filename);
1314 return GNUNET_SYSERR;
1315 }
1316
1317 /* Read data into memory */
1318 data = GNUNET_malloc (filesize + 1);
1319 if (filesize != GNUNET_DISK_fn_read (filename,
1320 data,
1321 filesize))
1322 {
1323 GNUNET_free (data);
1325 "Could not read search strings file %s.\n",
1326 filename);
1327 return GNUNET_SYSERR;
1328 }
1329
1330 /* Process buffer and build array */
1331 str_cnt = count_and_separate_strings (data, filesize, limit);
1332 if (GNUNET_OK != create_string_array (data, filesize, strings, str_cnt))
1333 {
1334 str_cnt = GNUNET_SYSERR;
1335 }
1336 GNUNET_free (data);
1337 return str_cnt;
1338}
1339
1340
1349static void
1350run (void *cls,
1351 char *const *args,
1352 const char *cfgfile,
1353 const struct GNUNET_CONFIGURATION_Handle *config)
1354{
1355 unsigned int nsearchstrs;
1356 unsigned int i;
1357 struct GNUNET_TIME_Relative abort_time;
1358
1360
1361 /* Check config */
1362 if (NULL == config)
1363 {
1365 _ ("No configuration file given. Exiting\n"));
1367 return;
1368 }
1370 if (GNUNET_OK !=
1372 "REGEX_PREFIX",
1373 &regex_prefix))
1374 {
1376 "regexprofiler",
1377 "regex_prefix");
1379 return;
1380 }
1381 if (GNUNET_OK !=
1383 "PARALLEL_SEARCHES",
1385 {
1387 "Configuration option \"PARALLEL_SEARCHES\" missing."
1388 " Using default (%d)\n", 10);
1390 }
1391 if (GNUNET_OK !=
1392 GNUNET_CONFIGURATION_get_value_time (cfg, "REGEXPROFILER",
1393 "REANNOUNCE_PERIOD_MAX",
1395 {
1397 "reannounce_period_max not given. Using 10 minutes.\n");
1400 }
1401
1402 /* Check arguments */
1403 if (NULL == policy_dir)
1404 {
1406 _ (
1407 "No policy directory specified on command line. Exiting.\n"));
1408 return;
1409 }
1411 {
1413 _ ("Specified policies directory does not exist. Exiting.\n"));
1415 return;
1416 }
1417 if (0 >= (int) (num_peers = GNUNET_DISK_directory_scan (policy_dir, NULL,
1418 NULL)))
1419 {
1421 _ ("No files found in `%s'\n"),
1422 policy_dir);
1423 return;
1424 }
1426 "POLICY_DIR", policy_dir);
1428 {
1430 _ ("No search strings file given. Exiting.\n"));
1432 return;
1433 }
1434 nsearchstrs = load_search_strings (strings_file,
1436 num_peers);
1437 if (num_peers != nsearchstrs)
1438 {
1440 "Error loading search strings.\n");
1442 "File (%s) does not contain enough strings (%u/%u).\n",
1443 strings_file, nsearchstrs, num_peers);
1445 return;
1446 }
1447 if ((0 == num_peers) || (NULL == search_strings))
1448 {
1450 _ ("Error loading search strings. Exiting.\n"));
1452 return;
1453 }
1454 for (i = 0; i < num_peers; i++)
1456 "search string: %s\n",
1457 search_strings[i]);
1458
1459 /* Check logfile */
1460 if ((NULL != data_filename) &&
1461 (NULL == (data_file =
1468 {
1470 "open",
1472 return;
1473 }
1474
1475 /* Initialize peers */
1476 peers = GNUNET_malloc (sizeof(struct RegexPeer) * num_peers);
1477 for (i = 0; i < num_peers; i++)
1478 peers[i].id = i;
1479
1481 "TESTBED", "OVERLAY_RANDOM_LINKS",
1482 num_peers * 20);
1484 "DHT", "FORCE_NSE",
1485 (long long unsigned)
1486 (log (num_peers) / log (2.0)));
1487 event_mask = 0LL;
1488/* For feedback about the start process activate these and pass master_cb */
1489 event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_START);
1490// event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_STOP);
1491 event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT);
1492// event_mask |= (1LL << GNUNET_TESTBED_ET_DISCONNECT);
1494 GNUNET_TESTBED_run (hosts_file,
1495 cfg,
1496 num_peers,
1497 event_mask,
1499 NULL, /* master_controller_cb cls */
1500 &test_master,
1501 NULL); /* test_master cls */
1502 if (GNUNET_OK !=
1504 "SETUP_TIMEOUT",
1505 &abort_time))
1506 {
1508 "SETUP_TIMEOUT not given. Using 15 minutes.\n");
1509 abort_time =
1511 }
1512 abort_time = GNUNET_TIME_relative_add (abort_time, GNUNET_TIME_UNIT_MINUTES);
1513 abort_task =
1514 GNUNET_SCHEDULER_add_delayed (abort_time,
1515 &do_abort,
1516 (void *) __LINE__);
1518 "setup_timeout: %s\n",
1520}
1521
1522
1530int
1531main (int argc, char *const *argv)
1532{
1535 'o',
1536 "output-file",
1537 "FILENAME",
1538 gettext_noop (
1539 "name of the file for writing statistics"),
1540 &data_filename),
1542 't',
1543 "matching-timeout",
1544 "TIMEOUT",
1545 gettext_noop (
1546 "wait TIMEOUT before ending the experiment"),
1549 'p',
1550 "policy-dir",
1551 "DIRECTORY",
1552 gettext_noop ("directory with policy files"),
1553 &policy_dir),
1555 's',
1556 "strings-file",
1557 "FILENAME",
1558 gettext_noop (
1559 "name of file with input strings"),
1560 &strings_file),
1562 'H',
1563 "hosts-file",
1564 "FILENAME",
1565 gettext_noop (
1566 "name of file with hosts' names"),
1567 &hosts_file),
1568
1570 };
1571 int ret;
1572
1574 ret =
1575 GNUNET_PROGRAM_run (argc, argv,
1576 "gnunet-regex-profiler",
1577 _ ("Profiler for regex"),
1578 options,
1579 &run, NULL);
1580 if (GNUNET_OK != ret)
1581 return ret;
1582 if (GNUNET_OK != result)
1583 return 1;
1584 return 0;
1585}
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
#define gettext_noop(String)
Definition: gettext.h:74
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:143
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:98
static int ret
Final status code.
Definition: gnunet-arm.c:93
static char * data
The data to insert into the dht.
static char * filename
const struct GNUNET_CONFIGURATION_Handle * config
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static size_t data_size
Number of bytes in data.
enum State state
current state of profiling
static unsigned int next_search
Index of peer to start next announce/search.
static char * data_filename
Filename to log statistics to.
static struct GNUNET_SCHEDULER_Task * abort_task
Abort task identifier.
static long long unsigned int init_parallel_searches
How many searches are we going to start in parallel.
static void stats_connect_cb(void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
Function called by testbed once we are connected to stats service.
static int stats_iterator(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
Process statistic values.
static int count_and_separate_strings(char *data, uint64_t data_size, unsigned int str_max)
Process the text buffer counting the non-empty lines and separating them with NULL characters,...
static void stats_cb(void *cls, int success)
Stats callback.
static struct GNUNET_TESTBED_Controller * mc
Handle to the master controller.
static struct GNUNET_TIME_Relative reannounce_period_max
What's the maximum regex reannounce period.
static char * policy_dir
Folder where policy files are stored.
static unsigned int parallel_searches
How many searches are running in parallel.
static struct GNUNET_TIME_Relative prof_time
Duration profiling step has taken.
static void stats_da(void *cls, void *op_result)
Adapter function called to destroy a connection to statistics service.
static void * stats_ca(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Adapter function called to establish a connection to statistics service.
static void test_master(void *cls, struct GNUNET_TESTBED_RunHandle *h, unsigned int num_peers_, struct GNUNET_TESTBED_Peer **testbed_peers, unsigned int links_succeeded, unsigned int links_failed)
Signature of a main function for a testcase.
State
Available states during profiling.
@ STATE_PEERS_CREATING
Creating peers.
@ STATE_SLAVES_STARTING
Starting slaves.
@ STATE_INIT
Initial state.
@ STATE_PEERS_LINKING
Linking peers.
@ STATE_SEARCH_REGEX
Matching strings against announced regexes.
@ STATE_PEERS_STARTING
Starting peers.
@ STATE_PEERS_DESTROYING
Destroying peers; we can do this as the controller takes care of stopping a peer if it is running.
static void do_abort(void *cls)
abort task to run on test timed out
static int in_shutdown
Set when shutting down to avoid making more queries.
static struct GNUNET_TIME_Absolute prof_start_time
The starting time of a profiling step.
static void do_announce(void *cls)
Task to start the daemons on each peer so that the regexes are announced into the DHT.
static struct GNUNET_SCHEDULER_Task * register_hosts_task
Host registration task identifier.
static struct GNUNET_CONFIGURATION_Handle * cfg
Handle to global configuration.
static void do_shutdown(void *cls)
Shutdown nicely.
static uint64_t event_mask
Global event mask for all testbed events.
static char * hosts_file
File with hostnames where to execute the test.
static struct GNUNET_SCHEDULER_Task * search_timeout_task
Search timeout task identifier.
static unsigned int strings_found
Number of strings found in the published regexes.
static int result
Global testing status.
static void announce_next_regex(void *cls)
Start announcing the next regex in the DHT.
static void find_string(void *cls)
Start searching for the next string in the DHT.
static struct GNUNET_TIME_Relative search_timeout_time
Search timeout in seconds.
static char * strings_file
File with the strings to look for.
static void dht_connect_cb(void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
DHT connect callback.
static int load_search_strings(const char *filename, char ***strings, unsigned int limit)
Load search strings from given filename.
static struct GNUNET_TESTBED_ControllerProc * mc_proc
Handle to the master controller process.
static int create_string_array(char *data, uint64_t data_size, char ***strings, unsigned int str_cnt)
Allocate a string array and fill it with the prefixed strings from a pre-processed,...
static void dht_da(void *cls, void *op_result)
Adapter function called to destroy a connection to the DHT service.
static void daemon_started(void *cls, struct GNUNET_TESTBED_Operation *op, const char *emsg)
Callback called when testbed has started the daemon we asked for.
static void * dht_ca(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
DHT connect adapter.
static char ** search_strings
Search strings (num_peers of them).
#define FIND_TIMEOUT
static void do_collect_stats(void *cls)
Task to collect all statistics from all peers, will shutdown the profiler, when done.
static void master_controller_cb(void *cls, const struct GNUNET_TESTBED_EventInformation *event)
Function that will be called whenever something in the testbed changes.
int main(int argc, char *const *argv)
Main function.
static struct GNUNET_TESTBED_HostRegistrationHandle * reg_handle
Host registration handle.
static void search_timed_out(void *cls)
Connect by string timeout task.
static void regex_found_handler(void *cls, const struct GNUNET_PeerIdentity *id, const struct GNUNET_DHT_PathElement *get_path, unsigned int get_path_length, const struct GNUNET_DHT_PathElement *put_path, unsigned int put_path_length)
Method called when we've found a peer that announced a regex that matches our search string.
static char * regex_prefix
Prefix used for regex announcing.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *config)
Main function that will be run by the scheduler.
static unsigned int num_peers
Number of peers to be started by the profiler.
static struct GNUNET_DISK_FileHandle * data_file
File to log statistics to.
static struct RegexPeer * peers
The array of peers; we fill this as the peers are given to us by the testbed.
static void find_timed_out(void *cls)
Search timed out.
static char * subsystem
Set to subsystem that we're going to get stats for (or NULL for all).
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
Constants for network applications operating on top of the CADET service.
API to the DHT service.
void GNUNET_CONFIGURATION_set_value_string(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *value)
Set a configuration value that should be a string.
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_dup(const struct GNUNET_CONFIGURATION_Handle *cfg)
Duplicate an existing configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
void GNUNET_CONFIGURATION_set_value_number(struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long number)
Set a configuration value that should be a number.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
struct GNUNET_DHT_Handle * GNUNET_DHT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int ht_len)
Initialize the connection with the DHT service.
Definition: dht_api.c:1030
void GNUNET_DHT_disconnect(struct GNUNET_DHT_Handle *handle)
Shutdown connection with the DHT service.
Definition: dht_api.c:1053
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1215
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:506
ssize_t GNUNET_DISK_file_write(const struct GNUNET_DISK_FileHandle *h, const void *buffer, size_t n)
Write a buffer to a file.
Definition: disk.c:682
enum GNUNET_GenericReturnValue GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:222
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_test(const char *fil, int is_readable)
Test if fil is a directory and listable.
Definition: disk.c:427
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1289
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:660
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:811
@ GNUNET_DISK_OPEN_TRUNCATE
Truncate file if it exists.
@ GNUNET_DISK_OPEN_CREATE
Create file if it doesn't exist.
@ GNUNET_DISK_OPEN_READWRITE
Open the file for both reading and writing.
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_filename(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a filename (automatically path expanded).
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_relative_time(char shortName, const char *name, const char *argumentHelp, const char *description, struct GNUNET_TIME_Relative *val)
Allow user to specify a struct GNUNET_TIME_Relative (using human-readable "fancy" time).
#define GNUNET_log(kind,...)
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(const struct GNUNET_OS_ProjectData *pd, int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:407
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:567
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1304
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1277
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
struct GNUNET_STATISTICS_GetHandle * GNUNET_STATISTICS_get(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Callback cont, GNUNET_STATISTICS_Iterator proc, void *cls)
Get statistic from the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:438
struct GNUNET_TIME_Relative GNUNET_TIME_relative_saturating_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Saturating multiply relative time by a given factor.
Definition: time.c:533
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:579
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition: time.c:587
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:486
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
void REGEX_INTERNAL_search_cancel(struct REGEX_INTERNAL_Search *h)
Cancel an ongoing regex search in the DHT and free all resources.
struct REGEX_INTERNAL_Search * REGEX_INTERNAL_search(struct GNUNET_DHT_Handle *dht, const char *string, REGEX_INTERNAL_Found callback, void *callback_cls, struct GNUNET_STATISTICS_Handle *stats)
Search for a peer offering a regex matching certain string in the DHT.
library to parse regular expressions into dfa
DLL of operations.
struct DLLOperation * next
The next pointer for DLL.
struct GNUNET_TESTBED_Operation * op
The testbed operation handle.
struct DLLOperation * prev
The prev pointer for DLL.
void * cls
Closure.
Connection to the DHT service.
Definition: dht_api.c:235
A (signed) path tracking a block's flow through the DHT is represented by an array of path elements,...
Handle used to access files (and pipes).
Definition of a command line option.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Handle for the service.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
Struct to keep information of searches of services described by a regex using a user-provided string ...
Peer handles.
int search_str_matched
Set to GNUNET_YES if the peer successfully matched the above search string.
const char * search_str
Peer's search string.
struct GNUNET_TESTBED_Operation * daemon_op
Daemon start.
struct GNUNET_TIME_Absolute prof_start_time
The starting time of a profiling step.
unsigned int id
Peer id.
struct GNUNET_STATISTICS_Handle * stats_handle
Peers's statistics handle.
struct GNUNET_CONFIGURATION_Handle * cfg
Peer configuration handle.
struct GNUNET_TESTBED_Operation * op_handle
Testbed operation handle for DHT.
struct GNUNET_TESTBED_Peer * peer_handle
The actual testbed peer handle.
struct GNUNET_DHT_Handle * dht_handle
Peer's DHT handle.
struct REGEX_INTERNAL_Search * search_handle
Handle to a running regex search.
struct GNUNET_SCHEDULER_Task * timeout
Operation timeout.