X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fregex%2Fgnunet-regex-profiler.c;h=638f1a1a43bd2cc1d78eb39d013df1e82fa756d9;hb=f119c5a88b06a05349f311c27f27be9a2760bf3f;hp=fbf410bad172a6bc81c1c05086769808e3a27373;hpb=dd5bdc8f33925604912901f1bde6f4f8652a9585;p=oweals%2Fgnunet.git diff --git a/src/regex/gnunet-regex-profiler.c b/src/regex/gnunet-regex-profiler.c index fbf410bad..638f1a1a4 100644 --- a/src/regex/gnunet-regex-profiler.c +++ b/src/regex/gnunet-regex-profiler.c @@ -31,13 +31,13 @@ #include "platform.h" #include "gnunet_applications.h" #include "gnunet_util_lib.h" -#include "gnunet_regex_lib.h" +#include "regex_internal_lib.h" #include "gnunet_arm_service.h" #include "gnunet_dht_service.h" #include "gnunet_testbed_service.h" -#define FIND_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90) -#define SEARCHES_IN_PARALLEL 10 +#define FIND_TIMEOUT \ + GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 90) /** * DLL of operations @@ -130,17 +130,7 @@ struct RegexPeer struct GNUNET_TESTBED_Peer *peer_handle; /** - * Host on which the peer is running. - */ - struct GNUNET_TESTBED_Host *host_handle; - - /** - * Filename of the peer's policy file. - */ - char *policy_file; - - /** - * Peers search string. + * Peer's search string. */ const char *search_str; @@ -152,11 +142,6 @@ struct RegexPeer */ int search_str_matched; - /** - * Peer's ARM handle. - */ - struct GNUNET_ARM_Handle *arm_handle; - /** * Peer's DHT handle. */ @@ -165,10 +150,10 @@ struct RegexPeer /** * Handle to a running regex search. */ - struct GNUNET_REGEX_search_handle *search_handle; + struct REGEX_INTERNAL_Search *search_handle; /** - * Testbed operation handle for the ARM and DHT services. + * Testbed operation handle for DHT. */ struct GNUNET_TESTBED_Operation *op_handle; @@ -177,11 +162,6 @@ struct RegexPeer */ struct GNUNET_STATISTICS_Handle *stats_handle; - /** - * Testbed operation handle for the statistics service. - */ - struct GNUNET_TESTBED_Operation *stats_op_handle; - /** * The starting time of a profiling step. */ @@ -191,19 +171,17 @@ struct RegexPeer * Operation timeout */ GNUNET_SCHEDULER_TaskIdentifier timeout; -}; - -/** - * An array of hosts loaded from the hostkeys file - */ -static struct GNUNET_TESTBED_Host **hosts; + /** + * Deamon start + */ + struct GNUNET_TESTBED_Operation *daemon_op; +}; /** - * Array of peer handles used to pass to - * GNUNET_TESTBED_overlay_configure_topology + * Set when shutting down to avoid making more queries. */ -static struct GNUNET_TESTBED_Peer **peer_handles; +static int in_shutdown; /** * The array of peers; we fill this as the peers are given to us by the testbed @@ -230,26 +208,6 @@ static struct GNUNET_TESTBED_Controller *mc; */ static struct GNUNET_CONFIGURATION_Handle *cfg; -/** - * Head of the operations list - */ -static struct DLLOperation *dll_op_head; - -/** - * Tail of the operations list - */ -static struct DLLOperation *dll_op_tail; - -/** - * Peer linking - topology operation - */ -static struct GNUNET_TESTBED_Operation *topology_op; - -/** - * The handle for whether a host is habitable or not - */ -struct GNUNET_TESTBED_HostHabitableCheckHandle **hc_handles; - /** * Abort task identifier */ @@ -285,31 +243,6 @@ static struct GNUNET_TIME_Relative prof_time; */ static unsigned int num_peers; -/** - * Number of hosts in the hosts array - */ -static unsigned int num_hosts; - -/** - * Factor of number of links. num_links = num_peers * linking_factor. - */ -static unsigned int linking_factor; - -/** - * Number of random links to be established between peers - */ -static unsigned int num_links; - -/** - * Number of times we try overlay connect operations - */ -static unsigned int retry_links; - -/** - * Continuous failures during overlay connect operations - */ -static unsigned int cont_fails; - /** * Global testing status */ @@ -326,50 +259,49 @@ enum State state; static char * policy_dir; /** - * Search strings. + * File with hostnames where to execute the test. */ -static char **search_strings; +static char *hosts_file; /** - * Number of search strings. + * File with the strings to look for. */ -static int num_search_strings; +static char *strings_file; /** - * How many searches are running in parallel + * Search strings (num_peers of them). */ -static unsigned int parallel_searches; +static char **search_strings; /** - * Index of peer/string search. + * How many searches are we going to start in parallel */ -static unsigned int peer_cnt; +static long long unsigned int init_parallel_searches; /** - * Number of peers found with search strings. + * How many searches are running in parallel */ -static unsigned int peers_found; +static unsigned int parallel_searches; /** - * Search task identifier + * Number of strings found in the published regexes. */ -static GNUNET_SCHEDULER_TaskIdentifier search_task; +static unsigned int strings_found; /** - * Search timeout task identifier. + * Index of peer to start next announce/search. */ -static GNUNET_SCHEDULER_TaskIdentifier search_timeout_task; +static unsigned int next_search; /** - * Search timeout in seconds. + * Search timeout task identifier. */ -static struct GNUNET_TIME_Relative search_timeout = { 60000 }; +static GNUNET_SCHEDULER_TaskIdentifier search_timeout_task; /** - * How long do we wait before starting the search? - * Default: 1 m. + * Search timeout in seconds. */ -static struct GNUNET_TIME_Relative search_delay = { 60000 }; +static struct GNUNET_TIME_Relative search_timeout_time = { 60000 }; /** * File to log statistics to. @@ -381,42 +313,22 @@ static struct GNUNET_DISK_FileHandle *data_file; */ static char *data_filename; -/** - * Maximal path compression length. - */ -static unsigned int max_path_compression; - /** * Prefix used for regex announcing. We need to prefix the search * strings with it, in order to find something. */ static char * regex_prefix; +/** + * What's the maximum regex reannounce period. + */ +static struct GNUNET_TIME_Relative reannounce_period_max; + /******************************************************************************/ /****************************** DECLARATIONS ********************************/ /******************************************************************************/ - -/** - * Search callback function. - * - * @param cls Closure provided in GNUNET_REGEX_search. - * @param id Peer providing a regex that matches the string. - * @param get_path Path of the get request. - * @param get_path_length Lenght of get_path. - * @param put_path Path of the put request. - * @param put_path_length Length of the put_path. - */ -static void -regex_found_handler (void *cls, - const struct GNUNET_PeerIdentity *id, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_length); - - /** * DHT connect callback. * @@ -469,14 +381,13 @@ stats_connect_cb (void *cls, /** - * Task to collect all statistics from all peers, will shutdown the - * profiler, when done. + * Start announcing the next regex in the DHT. * - * @param cls NULL - * @param tc the task context + * @param cls Index of the next peer in the peers array. + * @param tc TaskContext. */ static void -do_collect_stats (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); +announce_next_regex (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /******************************************************************************/ @@ -493,9 +404,7 @@ do_collect_stats (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); static void do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct DLLOperation *dll_op; struct RegexPeer *peer; - unsigned int nhost; unsigned int peer_cnt; unsigned int search_str_cnt; char output_buffer[512]; @@ -504,14 +413,6 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) shutdown_task = GNUNET_SCHEDULER_NO_TASK; if (GNUNET_SCHEDULER_NO_TASK != abort_task) GNUNET_SCHEDULER_cancel (abort_task); - if (NULL != hc_handles) - { - for (nhost = 0; nhost < num_hosts; nhost++) - if (NULL != hc_handles[nhost]) - GNUNET_TESTBED_is_host_habitable_cancel (hc_handles[nhost]); - GNUNET_free (hc_handles); - hc_handles = NULL; - } if (GNUNET_SCHEDULER_NO_TASK != register_hosts_task) GNUNET_SCHEDULER_cancel (register_hosts_task); @@ -525,10 +426,11 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) size = GNUNET_snprintf (output_buffer, sizeof (output_buffer), - "%p Search string not found: %s (%d)\n%p On peer: %u (%p)\n%p With policy file: %s\n%p After: %s\n", + "%p Search string not found: %s (%d)\n" + "%p On peer: %u (%p)\n" + "%p After: %s\n", peer, peer->search_str, peer->search_str_matched, peer, peer->id, peer, - peer, peer->policy_file, peer, GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); @@ -538,15 +440,13 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (NULL != peers[peer_cnt].op_handle) GNUNET_TESTBED_operation_done (peers[peer_cnt].op_handle); - if (NULL != peers[peer_cnt].stats_op_handle) - GNUNET_TESTBED_operation_done (peers[peer_cnt].stats_op_handle); } if (NULL != data_file) GNUNET_DISK_file_close (data_file); for (search_str_cnt = 0; - search_str_cnt < num_search_strings && NULL != search_strings; + search_str_cnt < num_peers && NULL != search_strings; search_str_cnt++) { GNUNET_free_non_null (search_strings[search_str_cnt]); @@ -555,19 +455,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (NULL != reg_handle) GNUNET_TESTBED_cancel_registration (reg_handle); - if (NULL != topology_op) - GNUNET_TESTBED_operation_done (topology_op); - for (nhost = 0; nhost < num_hosts; nhost++) - if (NULL != hosts[nhost]) - GNUNET_TESTBED_host_destroy (hosts[nhost]); - GNUNET_free_non_null (hosts); - - while (NULL != (dll_op = dll_op_head)) - { - GNUNET_TESTBED_operation_done (dll_op->op); - GNUNET_CONTAINER_DLL_remove (dll_op_head, dll_op_tail, dll_op); - GNUNET_free (dll_op); - } + if (NULL != mc) GNUNET_TESTBED_controller_disconnect (mc); if (NULL != mc_proc) @@ -575,7 +463,7 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (NULL != cfg) GNUNET_CONFIGURATION_destroy (cfg); - GNUNET_SCHEDULER_shutdown (); /* Stop scheduler to shutdown testbed run */ + GNUNET_SCHEDULER_shutdown (); /* Stop scheduler to shutdown testbed run */ } @@ -590,7 +478,7 @@ do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { unsigned long i = (unsigned long) cls; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Aborting %lu...\n", i); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Aborting from line %lu...\n", i); abort_task = GNUNET_SCHEDULER_NO_TASK; result = GNUNET_SYSERR; if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) @@ -700,10 +588,10 @@ stats_cb (void *cls, return; } - GNUNET_assert (NULL != peer->stats_op_handle); + GNUNET_assert (NULL != peer->op_handle); - GNUNET_TESTBED_operation_done (peer->stats_op_handle); - peer->stats_op_handle = NULL; + GNUNET_TESTBED_operation_done (peer->op_handle); + peer->op_handle = NULL; peer_cnt++; peer = &peers[peer_cnt]; @@ -712,18 +600,19 @@ stats_cb (void *cls, { struct GNUNET_TIME_Relative delay = { 100 }; shutdown_task = GNUNET_SCHEDULER_add_delayed (delay, &do_shutdown, NULL); + result = GNUNET_OK; } else { - peer->stats_op_handle = + peer->op_handle = GNUNET_TESTBED_service_connect (NULL, - peer->peer_handle, - "statistics", - &stats_connect_cb, - peer, - &stats_ca, - &stats_da, - peer); + peer->peer_handle, + "statistics", + &stats_connect_cb, + peer, + &stats_ca, + &stats_da, + peer); } } @@ -758,12 +647,12 @@ stats_connect_cb (void *cls, peer->stats_handle = ca_result; if (NULL == GNUNET_STATISTICS_get (peer->stats_handle, NULL, NULL, - GNUNET_TIME_UNIT_FOREVER_REL, - &stats_cb, - &stats_iterator, peer)) + GNUNET_TIME_UNIT_FOREVER_REL, + &stats_cb, + &stats_iterator, peer)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not get statistics of peer %u!\n", peer->id); + "Could not get statistics of peer %u!\n", peer->id); } } @@ -782,15 +671,15 @@ do_collect_stats (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_assert (NULL != peer->peer_handle); - peer->stats_op_handle = + peer->op_handle = GNUNET_TESTBED_service_connect (NULL, - peer->peer_handle, - "statistics", - &stats_connect_cb, - peer, - &stats_ca, - &stats_da, - peer); + peer->peer_handle, + "statistics", + &stats_connect_cb, + peer, + &stats_ca, + &stats_da, + peer); } @@ -806,14 +695,14 @@ do_collect_stats (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param tc TaskContext. */ static void -find_next_string (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); +find_string (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /** * Method called when we've found a peer that announced a regex * that matches our search string. Now get the statistics. * - * @param cls Closure provided in GNUNET_REGEX_search. + * @param cls Closure provided in REGEX_INTERNAL_search. * @param id Peer providing a regex that matches the string. * @param get_path Path of the get request. * @param get_path_length Lenght of get_path. @@ -834,20 +723,21 @@ regex_found_handler (void *cls, if (GNUNET_YES == peer->search_str_matched) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "String %s on peer %u already matched!\n", peer->search_str, peer->id); return; } - peers_found++; + strings_found++; parallel_searches--; if (GNUNET_SCHEDULER_NO_TASK != peer->timeout) { GNUNET_SCHEDULER_cancel (peer->timeout); peer->timeout = GNUNET_SCHEDULER_NO_TASK; - GNUNET_SCHEDULER_add_now (&find_next_string, NULL); + if (GNUNET_NO == in_shutdown) + GNUNET_SCHEDULER_add_now (&announce_next_regex, NULL); } if (NULL == id) @@ -855,21 +745,18 @@ regex_found_handler (void *cls, // FIXME not possible right now GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "String matching timed out for string %s on peer %u (%i/%i)\n", - peer->search_str, peer->id, peers_found, num_search_strings); - - printf ("String matching timed out for string %s on peer %u (%i/%i)\n", - peer->search_str, peer->id, peers_found, num_search_strings); - + peer->search_str, peer->id, strings_found, num_peers); peer->search_str_matched = GNUNET_SYSERR; } else { prof_time = GNUNET_TIME_absolute_get_duration (peer->prof_start_time); - printf ("String %s successfully matched on peer %u after %s (%i/%i) (%u||)\n", - peer->search_str, peer->id, GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO), - peers_found, num_search_strings, parallel_searches); - fflush (stdout); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "String %s found on peer %u after %s (%i/%i) (%u||)\n", + peer->search_str, peer->id, + GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO), + strings_found, num_peers, parallel_searches); peer->search_str_matched = GNUNET_YES; @@ -878,12 +765,10 @@ regex_found_handler (void *cls, size = GNUNET_snprintf (output_buffer, sizeof (output_buffer), - "%p Peer: %u\n%p Host: %s\n%p Policy file: %s\n" - "%p Search string: %s\n%p Search duration: %s\n\n", + "%p Peer: %u\n" + "%p Search string: %s\n" + "%p Search duration: %s\n\n", peer, peer->id, - peer, - GNUNET_TESTBED_host_get_hostname (peer->host_handle), - peer, peer->policy_file, peer, peer->search_str, peer, GNUNET_STRINGS_relative_time_to_string (prof_time, @@ -897,19 +782,20 @@ regex_found_handler (void *cls, GNUNET_TESTBED_operation_done (peer->op_handle); peer->op_handle = NULL; - if (peers_found == num_search_strings) + if (strings_found == num_peers) { prof_time = GNUNET_TIME_absolute_get_duration (prof_start_time); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "All strings successfully matched in %s\n", GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); - printf ("All strings successfully matched.\n"); - fflush (stdout); if (GNUNET_SCHEDULER_NO_TASK != search_timeout_task) + { GNUNET_SCHEDULER_cancel (search_timeout_task); + search_timeout_task = GNUNET_SCHEDULER_NO_TASK; + } - printf ("Collecting stats and shutting down.\n"); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Collecting stats and shutting down.\n"); GNUNET_SCHEDULER_add_now (&do_collect_stats, NULL); } } @@ -923,47 +809,36 @@ regex_found_handler (void *cls, * @param tc the task context */ static void -do_connect_by_string_timeout (void *cls, - const struct GNUNET_SCHEDULER_TaskContext * tc) +search_timed_out (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc) { + unsigned int i; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Finding matches to all strings did not succeed after %s.\n", - GNUNET_STRINGS_relative_time_to_string (search_timeout, GNUNET_NO)); + GNUNET_STRINGS_relative_time_to_string (search_timeout_time, + GNUNET_NO)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Found %i of %i strings\n", peers_found, num_search_strings); + "Found %i of %i strings\n", strings_found, num_peers); - printf ("Search timed out after %s. Collecting stats and shutting down.\n", - GNUNET_STRINGS_relative_time_to_string (search_timeout, GNUNET_NO)); - fflush (stdout); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Search timed out after %s." + "Collecting stats and shutting down.\n", + GNUNET_STRINGS_relative_time_to_string (search_timeout_time, + GNUNET_NO)); + in_shutdown = GNUNET_YES; + for (i = 0; i < num_peers; i++) + { + if (NULL != peers[i].op_handle) + { + GNUNET_TESTBED_operation_done (peers[i].op_handle); + peers[i].op_handle = NULL; + } + } GNUNET_SCHEDULER_add_now (&do_collect_stats, NULL); } -/** - * Connect by string task that is run to search for a string in the - * NFA. It first connects to the mesh service and when a connection is - * established it starts to search for the string. - * - * @param cls NULL - * @param tc the task context - */ -static void -do_connect_by_string (void *cls, - const struct GNUNET_SCHEDULER_TaskContext * tc) -{ - unsigned int i; - - printf ("Starting string search.\n"); - fflush (stdout); - - search_timeout_task = GNUNET_SCHEDULER_add_delayed (search_timeout, - &do_connect_by_string_timeout, NULL); - for (i = 0; i < SEARCHES_IN_PARALLEL; i++) - GNUNET_SCHEDULER_add_now (&find_next_string, NULL); -} - - /** * Search timed out. It might still complete in the future, * but we should start another one. @@ -972,7 +847,7 @@ do_connect_by_string (void *cls, * @param tc TaskContext. */ static void -find_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +find_timed_out (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct RegexPeer *p = cls; @@ -980,216 +855,95 @@ find_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) return; - GNUNET_SCHEDULER_add_now (&find_next_string, NULL); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Searching for string \"%s\" on peer %d timed out.\n", + p->search_str, + p->id); + if (GNUNET_NO == in_shutdown) + GNUNET_SCHEDULER_add_now (&announce_next_regex, NULL); } /** - * Start searching for the next string in the DHT. + * Start searching for a string in the DHT. * * @param cls Index of the next peer in the peers array. * @param tc TaskContext. */ static void -find_next_string (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +find_string (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + unsigned int search_peer = (unsigned int) (long) cls; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) || - peer_cnt >= (num_search_strings - 1)) + search_peer >= num_peers || + GNUNET_YES == in_shutdown) return; - parallel_searches++; - peers[peer_cnt].search_str = search_strings[peer_cnt]; - peers[peer_cnt].search_str_matched = GNUNET_NO; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Searching for string \"%s\" on peer %d with file %s (%u||)\n", - peers[peer_cnt].search_str, - peer_cnt, - peers[peer_cnt].policy_file, + "Searching for string \"%s\" on peer %d (%u||)\n", + peers[search_peer].search_str, + search_peer, parallel_searches); - peers[peer_cnt].op_handle = + peers[search_peer].op_handle = GNUNET_TESTBED_service_connect (NULL, - peers[peer_cnt].peer_handle, + peers[search_peer].peer_handle, "dht", &dht_connect_cb, - &peers[peer_cnt], + &peers[search_peer], &dht_ca, &dht_da, - &peers[peer_cnt]); - peers[peer_cnt].timeout = GNUNET_SCHEDULER_add_delayed (FIND_TIMEOUT, - &find_timeout, - &peers[peer_cnt]); - peer_cnt++; + &peers[search_peer]); + GNUNET_assert (NULL != peers[search_peer].op_handle); + peers[search_peer].timeout = GNUNET_SCHEDULER_add_delayed (FIND_TIMEOUT, + &find_timed_out, + &peers[search_peer]); } -/** - * ARM connect adapter. Opens a connection to the ARM service. - * - * @param cls Closure (peer). - * @param cfg Configuration handle. - * - * @return - */ -static void * -arm_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - struct RegexPeer *peer = cls; - - peer->arm_handle = GNUNET_ARM_connect (cfg, NULL); - - return peer->arm_handle; -} - - -/** - * Adapter function called to destroy a connection to the ARM service. - * - * @param cls Closure (peer). - * @param op_result Service handle returned from the connect adapter. - */ -static void -arm_da (void *cls, void *op_result) -{ - struct RegexPeer *peer = (struct RegexPeer *) cls; - - GNUNET_assert (peer->arm_handle == op_result); - - if (NULL != peer->arm_handle) - { - GNUNET_ARM_disconnect (peer->arm_handle); - peer->arm_handle = NULL; - } -} /** - * Start announcing the next regex in the DHT. + * Callback called when testbed has started the daemon we asked for. * - * @param cls Index of the next peer in the peers array. - * @param tc TaskContext. - */ -void -announce_next_regex (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - - -/** - * Callback function invoked when ARM peration is complete: deamon is started. - * - * @param cls Closure (RegexPeer). - * @param result Outcome of the operation. + * @param cls NULL + * @param op the operation handle + * @param emsg NULL on success; otherwise an error description */ static void -arm_start_cb (void *cls, enum GNUNET_ARM_ProcessStatus result) +daemon_started (void *cls, struct GNUNET_TESTBED_Operation *op, + const char *emsg) { struct RegexPeer *peer = (struct RegexPeer *) cls; - static unsigned int peer_cnt; - unsigned int next_p; + unsigned long search_peer; + unsigned int i; - switch (result) + GNUNET_TESTBED_operation_done (peer->daemon_op); + peer->daemon_op = NULL; + if (NULL != emsg) { - /** - * Service is currently being started (due to client request). - */ - case GNUNET_ARM_PROCESS_STARTING: - GNUNET_TESTBED_operation_done (peer->op_handle); - peer->op_handle = NULL; - - if (peer_cnt < (num_peers - 1)) - { - next_p = (++peer_cnt % num_peers); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply( - GNUNET_TIME_UNIT_MILLISECONDS, - 200), - &announce_next_regex, - (void *) (long) next_p); - } - else - { - printf ("All daemons started. Waiting %s to start string searches\n", - GNUNET_STRINGS_relative_time_to_string (search_delay, - GNUNET_NO)); - fflush (stdout); - GNUNET_SCHEDULER_add_delayed (search_delay, - do_connect_by_string, - NULL); - } - break; - - /** - * Service name is unknown to ARM. - */ - case GNUNET_ARM_PROCESS_UNKNOWN: - /** - * Service is now down (due to client request). - */ - case GNUNET_ARM_PROCESS_DOWN: - /** - * Service is already running. - */ - case GNUNET_ARM_PROCESS_ALREADY_RUNNING: - /** - * Service is already being stopped by some other client. - */ - case GNUNET_ARM_PROCESS_ALREADY_STOPPING: - /** - * Service is already down (no action taken) - */ - case GNUNET_ARM_PROCESS_ALREADY_DOWN: - /** - * ARM is currently being shut down (no more process starts) - */ - case GNUNET_ARM_PROCESS_SHUTDOWN: - /** - * Error in communication with ARM - */ - case GNUNET_ARM_PROCESS_COMMUNICATION_ERROR: - /** - * Timeout in communication with ARM - */ - case GNUNET_ARM_PROCESS_COMMUNICATION_TIMEOUT: - /** - * Failure to perform operation - */ - case GNUNET_ARM_PROCESS_FAILURE: - default: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ARM returned %d\n", result); - GNUNET_abort (); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to start/stop daemon at peer %u: %s\n", peer->id, emsg); + GNUNET_abort (); } -} - - -/** - * ARM connect callback. Called when we are connected to the arm service for - * the peer in 'cls'. If successfull we start the regex deamon to start - * announcing the regex of this peer. - * - * @param cls internal peer id. - * @param op operation handle. - * @param ca_result connect adapter result. - * @param emsg error message. - */ -static void -arm_connect_cb (void *cls, struct GNUNET_TESTBED_Operation *op, - void *ca_result, const char *emsg) -{ - struct RegexPeer *peer = (struct RegexPeer *) cls; - if (NULL != emsg || NULL == op || NULL == ca_result) + /* Find a peer to look for a string matching the regex announced */ + search_peer = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, + num_peers); + for (i = 0; peers[search_peer].search_str != NULL; i++) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ARM connect failed: %s\n", emsg); - GNUNET_abort (); + search_peer = (search_peer + 1) % num_peers; + if (i > num_peers) + GNUNET_abort (); /* we ran out of peers, must be a bug */ } - - GNUNET_assert (NULL != peer->arm_handle); - GNUNET_assert (peer->op_handle == op); - GNUNET_assert (peer->arm_handle == ca_result); - - GNUNET_ARM_start_service (ca_result, "regexprofiler", - GNUNET_OS_INHERIT_STD_NONE, - GNUNET_TIME_UNIT_FOREVER_REL, - &arm_start_cb, - peer); + peers[search_peer].search_str = search_strings[peer->id]; + peers[search_peer].search_str_matched = GNUNET_NO; + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply( + reannounce_period_max, + 2), + &find_string, + (void *) search_peer); } @@ -1203,50 +957,59 @@ arm_connect_cb (void *cls, struct GNUNET_TESTBED_Operation *op, static void do_announce (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - printf ("Starting announce.\n"); - fflush (stdout); + unsigned int i; - /* First connect to arm service, then announce. Next - announce will be in arm_connect_cb */ - peers[0].op_handle = - GNUNET_TESTBED_service_connect (NULL, - peers[0].peer_handle, - "arm", - &arm_connect_cb, - &peers[0], - &arm_ca, - &arm_da, - &peers[0]); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting announce.\n"); + for (i = 0; i < init_parallel_searches; i++) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + " scheduling announce %u\n", + i); + (void) GNUNET_SCHEDULER_add_now (&announce_next_regex, NULL); + } } /** * Start announcing the next regex in the DHT. * - * @param cls Index of the next peer in the peers array. + * @param cls Closure (unused). * @param tc TaskContext. */ -void +static void announce_next_regex (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - long next_p = (long) cls; + struct RegexPeer *peer; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; + if (next_search >= num_peers) + { + if (strings_found != num_peers) + { + struct GNUNET_TIME_Relative new_delay; + if (GNUNET_SCHEDULER_NO_TASK != search_timeout_task) + GNUNET_SCHEDULER_cancel (search_timeout_task); + new_delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15); + search_timeout_task = GNUNET_SCHEDULER_add_delayed (new_delay, + &search_timed_out, + NULL); + } + return; + } - printf ("Starting daemon %ld\n", next_p); - fflush (stdout); - - peers[next_p].op_handle = - GNUNET_TESTBED_service_connect (NULL, - peers[next_p].peer_handle, - "arm", - &arm_connect_cb, - &peers[next_p], - &arm_ca, - &arm_da, - &peers[next_p]); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting daemon %u\n", next_search); + peer = &peers[next_search]; + peer->daemon_op = + GNUNET_TESTBED_peer_manage_service (NULL, + peer->peer_handle, + "regexprofiler", + &daemon_started, + peer, + 1); + next_search++; + parallel_searches++; } /** @@ -1276,7 +1039,7 @@ dht_connect_cb (void *cls, struct GNUNET_TESTBED_Operation *op, GNUNET_assert (peer->dht_handle == ca_result); peer->search_str_matched = GNUNET_NO; - peer->search_handle = GNUNET_REGEX_search (peer->dht_handle, + peer->search_handle = REGEX_INTERNAL_search (peer->dht_handle, peer->search_str, ®ex_found_handler, peer, NULL); @@ -1318,7 +1081,7 @@ dht_da (void *cls, void *op_result) if (NULL != peer->search_handle) { - GNUNET_REGEX_search_cancel (peer->search_handle); + REGEX_INTERNAL_search_cancel (peer->search_handle); peer->search_handle = NULL; } @@ -1330,522 +1093,93 @@ dht_da (void *cls, void *op_result) } -/******************************************************************************/ -/*************************** TESTBED PEER SETUP *****************************/ -/******************************************************************************/ - - /** - * Configure the peer overlay topology. + * Signature of a main function for a testcase. * * @param cls NULL - * @param tc the task context + * @param num_peers_ number of peers in 'peers' + * @param testbed_peers handle to peers run in the testbed. NULL upon timeout (see + * GNUNET_TESTBED_test_run()). + * @param links_succeeded the number of overlay link connection attempts that + * succeeded + * @param links_failed the number of overlay link connection attempts that + * failed */ -static void -do_configure_topology (void *cls, - const struct GNUNET_SCHEDULER_TaskContext * tc) +static void +test_master (void *cls, + unsigned int num_peers_, + struct GNUNET_TESTBED_Peer **testbed_peers, + unsigned int links_succeeded, + unsigned int links_failed) { - /* - if (0 == linking_factor) - linking_factor = 1; - num_links = linking_factor * num_peers; - */ - /* num_links = num_peers - 1; */ - num_links = linking_factor; - - /* Do overlay connect */ - prof_start_time = GNUNET_TIME_absolute_get (); - topology_op = - GNUNET_TESTBED_overlay_configure_topology (NULL, num_peers, peer_handles, - NULL, - NULL, - NULL, - GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI, - num_links, - GNUNET_TESTBED_TOPOLOGY_RETRY_CNT, - (unsigned int) 0, - GNUNET_TESTBED_TOPOLOGY_OPTION_END); - if (NULL == topology_op) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Cannot create topology, op handle was NULL\n"); - GNUNET_assert (0); - } -} + unsigned int i; + GNUNET_assert (num_peers_ == num_peers); -/** - * Functions of this signature are called when a peer has been successfully - * started or stopped. - * - * @param cls the closure from GNUNET_TESTBED_peer_start/stop() - * @param emsg NULL on success; otherwise an error description - */ -static void -peer_churn_cb (void *cls, const char *emsg) -{ - struct DLLOperation *dll_op = cls; - struct GNUNET_TESTBED_Operation *op; - static unsigned int started_peers; - unsigned int peer_cnt; + prof_time = GNUNET_TIME_absolute_get_duration (prof_start_time); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Testbed started in %s\n", + GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); - op = dll_op->op; - GNUNET_CONTAINER_DLL_remove (dll_op_head, dll_op_tail, dll_op); - GNUNET_free (dll_op); - if (NULL != emsg) + if (GNUNET_SCHEDULER_NO_TASK != abort_task) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("An operation has failed while starting peers: %s\n"), emsg); - GNUNET_TESTBED_operation_done (op); - if (GNUNET_SCHEDULER_NO_TASK != abort_task) - GNUNET_SCHEDULER_cancel (abort_task); - abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); - return; + GNUNET_SCHEDULER_cancel (abort_task); + abort_task = GNUNET_SCHEDULER_NO_TASK; } - GNUNET_TESTBED_operation_done (op); - if (++started_peers == num_peers) - { - prof_time = GNUNET_TIME_absolute_get_duration (prof_start_time); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "All peers started successfully in %s\n", - GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); - result = GNUNET_OK; - peer_handles = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_Peer *) * num_peers); - for (peer_cnt = 0; peer_cnt < num_peers; peer_cnt++) - peer_handles[peer_cnt] = peers[peer_cnt].peer_handle; - - state = STATE_PEERS_LINKING; - GNUNET_SCHEDULER_add_now (&do_configure_topology, NULL); + for (i = 0; i < num_peers; i++) + { + peers[i].peer_handle = testbed_peers[i]; } -} - - -/** - * Functions of this signature are called when a peer has been successfully - * created - * - * @param cls the closure from GNUNET_TESTBED_peer_create() - * @param peer the handle for the created peer; NULL on any error during - * creation - * @param emsg NULL if peer is not NULL; else MAY contain the error description - */ -static void -peer_create_cb (void *cls, struct GNUNET_TESTBED_Peer *peer, const char *emsg) -{ - struct DLLOperation *dll_op = cls; - struct RegexPeer *peer_ptr; - static unsigned int created_peers; - unsigned int peer_cnt; - - if (NULL != emsg) + if (GNUNET_NO == + GNUNET_CONFIGURATION_get_value_yesno (cfg, "DHT", "DISABLE_TRY_CONNECT")) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Creating a peer failed. Error: %s\n"), emsg); - GNUNET_TESTBED_operation_done (dll_op->op); - GNUNET_CONTAINER_DLL_remove (dll_op_head, dll_op_tail, dll_op); - GNUNET_free (dll_op); - if (GNUNET_SCHEDULER_NO_TASK != abort_task) - GNUNET_SCHEDULER_cancel (abort_task); - abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); - return; + struct GNUNET_TIME_Relative settle_time; + + settle_time = + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, + 10 * num_peers); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Waiting for DHT for %s to settle new connections.\n\n", + GNUNET_STRINGS_relative_time_to_string(settle_time, GNUNET_NO)); + GNUNET_SCHEDULER_add_delayed (settle_time, &do_announce, NULL); } - - peer_ptr = dll_op->cls; - GNUNET_assert (NULL == peer_ptr->peer_handle); - GNUNET_CONFIGURATION_destroy (peer_ptr->cfg); - peer_ptr->cfg = NULL; - peer_ptr->peer_handle = peer; - GNUNET_TESTBED_operation_done (dll_op->op); - GNUNET_CONTAINER_DLL_remove (dll_op_head, dll_op_tail, dll_op); - GNUNET_free (dll_op); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %i created on host %s\n", - peer_ptr->id, - GNUNET_TESTBED_host_get_hostname (peer_ptr->host_handle)); - - if (++created_peers == num_peers) + else { - prof_time = GNUNET_TIME_absolute_get_duration (prof_start_time); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "All peers created successfully in %s\n", - GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); - /* Now peers are to be started */ - state = STATE_PEERS_STARTING; - prof_start_time = GNUNET_TIME_absolute_get (); - for (peer_cnt = 0; peer_cnt < num_peers; peer_cnt++) - { - dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); - dll_op->op = GNUNET_TESTBED_peer_start (dll_op, - peers[peer_cnt].peer_handle, - &peer_churn_cb, dll_op); - GNUNET_CONTAINER_DLL_insert_tail (dll_op_head, dll_op_tail, dll_op); - } + GNUNET_SCHEDULER_add_now (&do_announce, NULL); } + search_timeout_task = + GNUNET_SCHEDULER_add_delayed (search_timeout_time, &search_timed_out, NULL); } - -/** - * Function called with a filename for each file in the policy directory. Create - * a peer for each filename and update the peer's configuration to include the - * max_path_compression specified as a command line argument as well as the - * policy_file for this peer. The gnunet-service-regexprofiler service is - * automatically started on this peer. The service reads the configurration and - * announces the regexes stored in the policy file 'filename'. - * - * @param cls closure - * @param filename complete filename (absolute path) - * @return GNUNET_OK to continue to iterate, - * GNUNET_SYSERR to abort iteration with error! - */ -static int -policy_filename_cb (void *cls, const char *filename) -{ - static unsigned int peer_cnt; - struct DLLOperation *dll_op; - struct RegexPeer *peer = &peers[peer_cnt]; - - GNUNET_assert (NULL != peer); - - peer->policy_file = GNUNET_strdup (filename); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Creating peer %i on host %s for policy file %s\n", - peer->id, - GNUNET_TESTBED_host_get_hostname (peer->host_handle), - filename); - - /* Set configuration options specific for this peer - (max_path_compression and policy_file */ - peer->cfg = GNUNET_CONFIGURATION_dup (cfg); - GNUNET_CONFIGURATION_set_value_number (peer->cfg, "REGEXPROFILER", - "MAX_PATH_COMPRESSION", - (unsigned long long)max_path_compression); - GNUNET_CONFIGURATION_set_value_string (peer->cfg, "REGEXPROFILER", - "POLICY_FILE", filename); - - dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); - dll_op->cls = &peers[peer_cnt]; - dll_op->op = GNUNET_TESTBED_peer_create (mc, - peer->host_handle, - peer->cfg, - &peer_create_cb, - dll_op); - GNUNET_CONTAINER_DLL_insert_tail (dll_op_head, dll_op_tail, dll_op); - - peer_cnt++; - - return GNUNET_OK; -} - - /** - * Controller event callback. + * Function that will be called whenever something in the testbed changes. * - * @param cls NULL - * @param event the controller event + * @param cls closure, NULL + * @param event information on what is happening */ static void -controller_event_cb (void *cls, - const struct GNUNET_TESTBED_EventInformation *event) +master_controller_cb (void *cls, + const struct GNUNET_TESTBED_EventInformation *event) { - struct DLLOperation *dll_op; - struct GNUNET_TESTBED_Operation *op; - int ret; - - switch (state) + switch (event->type) { - case STATE_SLAVES_STARTING: - switch (event->type) - { - case GNUNET_TESTBED_ET_OPERATION_FINISHED: - { - static unsigned int slaves_started; - unsigned int peer_cnt; - - dll_op = event->details.operation_finished.op_cls; - GNUNET_CONTAINER_DLL_remove (dll_op_head, dll_op_tail, dll_op); - GNUNET_free (dll_op); - op = event->details.operation_finished.operation; - if (NULL != event->details.operation_finished.emsg) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("An operation has failed while starting slaves\n")); - GNUNET_TESTBED_operation_done (op); - if (GNUNET_SCHEDULER_NO_TASK != abort_task) - GNUNET_SCHEDULER_cancel (abort_task); - abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); - return; - } - GNUNET_TESTBED_operation_done (op); - /* Proceed to start peers */ - if (++slaves_started == num_hosts - 1) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "All slaves started successfully\n"); - - state = STATE_PEERS_CREATING; - prof_start_time = GNUNET_TIME_absolute_get (); - - if (-1 == (ret = GNUNET_DISK_directory_scan (policy_dir, - NULL, - NULL))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("No files found in `%s'\n"), - policy_dir); - GNUNET_SCHEDULER_shutdown (); - return; - } - num_peers = (unsigned int) ret; - peers = GNUNET_malloc (sizeof (struct RegexPeer) * num_peers); - - /* Initialize peers */ - for (peer_cnt = 0; peer_cnt < num_peers; peer_cnt++) - { - struct RegexPeer *peer = &peers[peer_cnt]; - peer->id = peer_cnt; - peer->policy_file = NULL; - /* Do not start peers on hosts[0] (master controller) */ - peer->host_handle = hosts[1 + (peer_cnt % (num_hosts -1))]; - peer->dht_handle = NULL; - peer->search_handle = NULL; - peer->stats_handle = NULL; - peer->stats_op_handle = NULL; - peer->search_str = NULL; - peer->search_str_matched = GNUNET_NO; - } - - GNUNET_DISK_directory_scan (policy_dir, - &policy_filename_cb, - NULL); - } - } - break; - default: - GNUNET_assert (0); - } - break; - case STATE_PEERS_STARTING: - switch (event->type) - { - case GNUNET_TESTBED_ET_OPERATION_FINISHED: - /* Control reaches here when peer start fails */ - case GNUNET_TESTBED_ET_PEER_START: - /* we handle peer starts in peer_churn_cb */ - break; - default: - GNUNET_assert (0); - } + case GNUNET_TESTBED_ET_CONNECT: + printf("."); break; - case STATE_PEERS_LINKING: - switch (event->type) - { - static unsigned int established_links; - case GNUNET_TESTBED_ET_OPERATION_FINISHED: - /* Control reaches here when a peer linking operation fails */ - if (NULL != event->details.operation_finished.emsg) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("An operation has failed while linking\n")); - printf ("F%u ", retry_links); - fflush (stdout); - retry_links++; - } - /* We do no retries, consider this link as established */ - /* break; */ - case GNUNET_TESTBED_ET_CONNECT: - { - char output_buffer[512]; - size_t size; - - if (0 == established_links) - printf ("Establishing links ."); - else - { - printf ("."); - fflush (stdout); - } - if (++established_links == num_links) - { - fflush (stdout); - prof_time = GNUNET_TIME_absolute_get_duration (prof_start_time); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%u links established in %s\n", - num_links, - GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); - prof_time = GNUNET_TIME_relative_divide(prof_time, num_links); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Average of %s per connection\n", - GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO)); - result = GNUNET_OK; - GNUNET_free (peer_handles); - - if (NULL != data_file) - { - size = - GNUNET_snprintf (output_buffer, - sizeof (output_buffer), - "# of peers: %u\n# of links established: %u\n" - "Time to establish links: %s\nLinking failures: %u\n" - "path compression length: %u\n# of search strings: %u\n", - num_peers, - (established_links - cont_fails), - GNUNET_STRINGS_relative_time_to_string (prof_time, GNUNET_NO), - cont_fails, - max_path_compression, - num_search_strings); - - if (size != GNUNET_DISK_file_write (data_file, output_buffer, size)) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to write to file!\n"); - } - - printf ("\nWaiting %s before starting to announce.\n", - GNUNET_STRINGS_relative_time_to_string (search_delay, GNUNET_NO)); - fflush (stdout); - - state = STATE_SEARCH_REGEX; - - search_task = GNUNET_SCHEDULER_add_delayed (search_delay, - &do_announce, NULL); - } - } - break; - default: - GNUNET_assert (0); - } - break; - case STATE_SEARCH_REGEX: - { - /* Handled in service connect callback */ + case GNUNET_TESTBED_ET_PEER_START: + printf("#"); break; - } default: - switch (state) - { - case STATE_PEERS_CREATING: - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to create peer\n"); - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unexpected controller_cb with state %i!\n", state); - } - GNUNET_assert (0); - } -} - - -/** - * Task to register all hosts available in the global host list. - * - * @param cls NULL - * @param tc the scheduler task context - */ -static void -register_hosts (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - - -/** - * Callback which will be called to after a host registration succeeded or failed - * - * @param cls the closure - * @param emsg the error message; NULL if host registration is successful - */ -static void -host_registration_completion (void *cls, const char *emsg) -{ - reg_handle = NULL; - if (NULL != emsg) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Host registration failed for a host. Error: %s\n"), emsg); - if (GNUNET_SCHEDULER_NO_TASK != abort_task) - GNUNET_SCHEDULER_cancel (abort_task); - abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); - return; - } - register_hosts_task = GNUNET_SCHEDULER_add_now (®ister_hosts, NULL); -} - - -/** - * Task to register all hosts available in the global host list. - * - * @param cls NULL - * @param tc the scheduler task context - */ -static void -register_hosts (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct DLLOperation *dll_op; - static unsigned int reg_host; - unsigned int slave; - - register_hosts_task = GNUNET_SCHEDULER_NO_TASK; - if (reg_host == num_hosts - 1) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "All hosts successfully registered\n"); - /* Start slaves */ - state = STATE_SLAVES_STARTING; - for (slave = 1; slave < num_hosts; slave++) - { - dll_op = GNUNET_malloc (sizeof (struct DLLOperation)); - dll_op->op = GNUNET_TESTBED_controller_link (dll_op, - mc, - hosts[slave], - hosts[0], - cfg, - GNUNET_YES); - GNUNET_CONTAINER_DLL_insert_tail (dll_op_head, dll_op_tail, dll_op); - } - return; + break; } - reg_handle = GNUNET_TESTBED_register_host (mc, hosts[++reg_host], - host_registration_completion, - NULL); + fflush(stdout); } -/** - * Callback to signal successfull startup of the controller process. - * - * @param cls the closure from GNUNET_TESTBED_controller_start() - * @param config the configuration with which the controller has been started; - * NULL if status is not GNUNET_OK - * @param status GNUNET_OK if the startup is successfull; GNUNET_SYSERR if not, - * GNUNET_TESTBED_controller_stop() shouldn't be called in this case - */ -static void -status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *config, int status) -{ - if (GNUNET_SCHEDULER_NO_TASK != abort_task) - GNUNET_SCHEDULER_cancel (abort_task); - if (GNUNET_OK != status) - { - mc_proc = NULL; - printf("Oh, dear!\n"); - abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); - return; - } - event_mask = 0; - event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_START); - event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_STOP); - event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT); - event_mask |= (1LL << GNUNET_TESTBED_ET_DISCONNECT); - event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); - mc = GNUNET_TESTBED_controller_connect (config, hosts[0], event_mask, - &controller_event_cb, NULL); - if (NULL == mc) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Unable to connect to master controller -- Check config\n")); - abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); - return; - } - register_hosts_task = GNUNET_SCHEDULER_add_now (®ister_hosts, NULL); - abort_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &do_abort, (void*) __LINE__); -} +/******************************************************************************/ +/*************************** TESTBED PEER SETUP *****************************/ +/******************************************************************************/ /** @@ -1920,52 +1254,6 @@ load_search_strings (const char *filename, char ***strings, unsigned int limit) } -/** - * Callbacks of this type are called by GNUNET_TESTBED_is_host_habitable to - * inform whether the given host is habitable or not. The Handle returned by - * GNUNET_TESTBED_is_host_habitable() is invalid after this callback is called - * - * @param cls NULL - * @param host the host whose status is being reported; will be NULL if the host - * given to GNUNET_TESTBED_is_host_habitable() is NULL - * @param status GNUNET_YES if it is habitable; GNUNET_NO if not - */ -static void -host_habitable_cb (void *cls, const struct GNUNET_TESTBED_Host *host, int status) -{ - struct GNUNET_TESTBED_HostHabitableCheckHandle **hc_handle = cls; - static unsigned int hosts_checked; - - *hc_handle = NULL; - if (GNUNET_NO == status) - { - if ((NULL != host) && (NULL != GNUNET_TESTBED_host_get_hostname (host))) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Host %s cannot start testbed\n"), - GNUNET_TESTBED_host_get_hostname (host)); - else - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Testbed cannot be started on localhost\n")); - GNUNET_SCHEDULER_cancel (abort_task); - abort_task = GNUNET_SCHEDULER_add_now (&do_abort, (void*) __LINE__); - return; - } - hosts_checked++; - /* printf (_("\rChecked %u hosts"), hosts_checked); */ - /* fflush (stdout); */ - if (hosts_checked < num_hosts) - return; - /* printf (_("\nAll hosts can start testbed. Creating peers\n")); */ - GNUNET_free (hc_handles); - hc_handles = NULL; - mc_proc = - GNUNET_TESTBED_controller_start (GNUNET_TESTBED_host_get_hostname - (hosts[0]), - hosts[0], - cfg, - status_cb, - NULL); -} - - /** * Main function that will be run by the scheduler. * @@ -1978,69 +1266,108 @@ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *config) { - unsigned int nhost; unsigned int nsearchstrs; + unsigned int i; + struct GNUNET_TIME_Relative abort_time; + + in_shutdown = GNUNET_NO; - if (NULL == args[0]) + /* Check config */ + if (NULL == config) { - fprintf (stderr, _("No hosts-file specified on command line. Exiting.\n")); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("No configuration file given. Exiting\n")); + shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); return; } - if (NULL == args[1]) + cfg = GNUNET_CONFIGURATION_dup (config); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, "REGEXPROFILER", + "REGEX_PREFIX", + ®ex_prefix)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Configuration option \"regex_prefix\" missing. Exiting\n")); + shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); + return; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (cfg, "REGEXPROFILER", + "PARALLEL_SEARCHES", + &init_parallel_searches)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Configuration option \"PARALLEL_SEARCHES\" missing." + " Using default (%d)\n", 10); + init_parallel_searches = 10; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (cfg, "REGEXPROFILER", + "REANNOUNCE_PERIOD_MAX", + &reannounce_period_max)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "reannounce_period_max not given. Using 10 minutes.\n"); + reannounce_period_max = + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 10); + } + + /* Check arguments */ + if (NULL == policy_dir) { - fprintf (stderr, _("No policy directory specified on command line. Exiting.\n")); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("No policy directory specified on command line. Exiting.\n")); return; } - num_hosts = GNUNET_TESTBED_hosts_load_from_file (args[0], config, &hosts); - if (0 == num_hosts) + if (GNUNET_YES != GNUNET_DISK_directory_test (policy_dir, GNUNET_YES)) { - fprintf (stderr, _("No hosts loaded. Need at least one host\n")); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Specified policies directory does not exist. Exiting.\n")); + shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); return; } - printf (_("Checking whether given hosts can start testbed. Please wait\n")); - hc_handles = GNUNET_malloc (sizeof (struct - GNUNET_TESTBED_HostHabitableCheckHandle *) - * num_hosts); - for (nhost = 0; nhost < num_hosts; nhost++) + if (-1 == (num_peers = GNUNET_DISK_directory_scan (policy_dir, NULL, NULL))) { - hc_handles[nhost] = GNUNET_TESTBED_is_host_habitable (hosts[nhost], config, - &host_habitable_cb, - &hc_handles[nhost]); - if (NULL == hc_handles[nhost]) - { - int i; - - GNUNET_break (0); - for (i = 0; i <= nhost; i++) - if (NULL != hc_handles[i]) - GNUNET_TESTBED_is_host_habitable_cancel (hc_handles[i]); - GNUNET_free (hc_handles); - hc_handles = NULL; - break; - } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("No files found in `%s'\n"), + policy_dir); + return; } - if (num_hosts != nhost) + GNUNET_CONFIGURATION_set_value_string (cfg, "REGEXPROFILER", + "POLICY_DIR", policy_dir); + if (GNUNET_YES != GNUNET_DISK_file_test (strings_file)) { - fprintf (stderr, _("Exiting\n")); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("No search strings file given. Exiting.\n")); shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); return; } - if (NULL == config) + nsearchstrs = load_search_strings (strings_file, + &search_strings, + num_peers); + if (num_peers != nsearchstrs) { - fprintf (stderr, _("No configuration file given. Exiting\n")); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error loading search strings.\n"); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "File (%s) does not contain enough strings (%u/%u).\n", + strings_file, nsearchstrs, num_peers); shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); return; } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (config, "REGEXPROFILER", "REGEX_PREFIX", - ®ex_prefix)) + if (0 >= num_peers || NULL == search_strings) { - fprintf (stderr, _("Configuration option (regex_prefix) missing. Exiting\n")); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Error loading search strings. Exiting.\n")); shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); return; } + for (i = 0; i < num_peers; i++) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "search string: %s\n", + search_strings[i]); + /* Check logfile */ if ( (NULL != data_filename) && (NULL == (data_file = GNUNET_DISK_file_open (data_filename, @@ -2049,43 +1376,54 @@ run (void *cls, char *const *args, const char *cfgfile, GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE))) ) + { GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", data_filename); - if (GNUNET_YES != GNUNET_DISK_directory_test (args[1], GNUNET_YES)) - { - fprintf (stderr, _("Specified policies directory does not exist. Exiting.\n")); - shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - return; - } - policy_dir = args[1]; - if (GNUNET_YES != GNUNET_DISK_file_test (args[2])) - { - fprintf (stderr, _("No search strings file given. Exiting.\n")); - shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); return; } - nsearchstrs = load_search_strings (args[2], &search_strings, num_search_strings); - if (num_search_strings != nsearchstrs) + + /* Initialize peers */ + peers = GNUNET_malloc (sizeof (struct RegexPeer) * num_peers); + for (i = 0; i < num_peers; i++) { - num_search_strings = nsearchstrs; - fprintf (stderr, _("Error loading search strings. Given file does not contain enough strings. Exiting.\n")); - shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - return; + peers[i].id = i; } - if (0 >= num_search_strings || NULL == search_strings) + + GNUNET_CONFIGURATION_set_value_number (cfg, + "TESTBED", "OVERLAY_RANDOM_LINKS", + num_peers * 20); + GNUNET_CONFIGURATION_set_value_number (cfg, + "DHT", "FORCE_NSE", + (long long unsigned) + (log (num_peers) / log (2.0))); + event_mask = 0LL; +/* For feedback about the start process activate these and pass master_cb */ + event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_START); +// event_mask |= (1LL << GNUNET_TESTBED_ET_PEER_STOP); + event_mask |= (1LL << GNUNET_TESTBED_ET_CONNECT); +// event_mask |= (1LL << GNUNET_TESTBED_ET_DISCONNECT); + prof_start_time = GNUNET_TIME_absolute_get (); + GNUNET_TESTBED_run (hosts_file, + cfg, + num_peers, + event_mask, + &master_controller_cb, + NULL, /* master_controller_cb cls */ + &test_master, + NULL); /* test_master cls */ + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (cfg, "TESTBED", + "SETUP_TIMEOUT", + &abort_time)) { - fprintf (stderr, _("Error loading search strings. Exiting.\n")); - shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL); - return; + abort_time = + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15); } - unsigned int i; - for (i = 0; i < num_search_strings; i++) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "search string: %s\n", search_strings[i]); - cfg = GNUNET_CONFIGURATION_dup (config); + abort_time = GNUNET_TIME_relative_add (abort_time, GNUNET_TIME_UNIT_MINUTES); abort_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 5), &do_abort, + GNUNET_SCHEDULER_add_delayed (abort_time, + &do_abort, (void*) __LINE__); } @@ -2101,38 +1439,33 @@ int main (int argc, char *const *argv) { static const struct GNUNET_GETOPT_CommandLineOption options[] = { - {'d', "details", "FILENAME", + {'o', "output-file", "FILENAME", gettext_noop ("name of the file for writing statistics"), - 1, &GNUNET_GETOPT_set_string, &data_filename}, - {'n', "num-links", "COUNT", - gettext_noop ("create COUNT number of random links between peers"), - GNUNET_YES, &GNUNET_GETOPT_set_uint, &linking_factor }, + GNUNET_YES, &GNUNET_GETOPT_set_string, &data_filename}, {'t', "matching-timeout", "TIMEOUT", - gettext_noop ("wait TIMEOUT before considering a string match as failed"), - GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &search_timeout }, - {'s', "search-delay", "DELAY", - gettext_noop ("wait DELAY before starting string search"), - GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &search_delay }, - {'a', "num-search-strings", "COUNT", - gettext_noop ("number of search strings to read from search strings file"), - GNUNET_YES, &GNUNET_GETOPT_set_uint, &num_search_strings }, - {'p', "max-path-compression", "MAX_PATH_COMPRESSION", - gettext_noop ("maximum path compression length"), - 1, &GNUNET_GETOPT_set_uint, &max_path_compression}, + gettext_noop ("wait TIMEOUT before ending the experiment"), + GNUNET_YES, &GNUNET_GETOPT_set_relative_time, &search_timeout_time}, + {'p', "policy-dir", "DIRECTORY", + gettext_noop ("directory with policy files"), + GNUNET_YES, &GNUNET_GETOPT_set_filename, &policy_dir}, + {'s', "strings-file", "FILENAME", + gettext_noop ("name of file with input strings"), + GNUNET_YES, &GNUNET_GETOPT_set_filename, &strings_file}, + {'H', "hosts-file", "FILENAME", + gettext_noop ("name of file with hosts' names"), + GNUNET_YES, &GNUNET_GETOPT_set_filename, &hosts_file}, GNUNET_GETOPT_OPTION_END }; int ret; if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) return 2; - result = GNUNET_SYSERR; ret = GNUNET_PROGRAM_run (argc, argv, - "gnunet-regex-profiler [OPTIONS] hosts-file policy-dir search-strings-file", + "gnunet-regex-profiler", _("Profiler for regex"), options, &run, NULL); - if (GNUNET_OK != ret) return ret; if (GNUNET_OK != result)