/** * Call this method periodically to scan data/hosts for new hosts. * * @param cls unused * @param tc scheduler context, aborted if reason is shutdown */ static void cron_scan_directory_data_hosts (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { static unsigned int retries; unsigned int count; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; count = 0; if (GNUNET_SYSERR == GNUNET_DISK_directory_create (networkIdDirectory)) { GNUNET_SCHEDULER_add_delayed_with_priority (DATA_HOST_FREQ, GNUNET_SCHEDULER_PRIORITY_IDLE, &cron_scan_directory_data_hosts, NULL); return; } GNUNET_DISK_directory_scan (networkIdDirectory, &hosts_directory_scan_callback, &count); if ((0 == count) && (0 == (++retries & 31))) GNUNET_log (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, _("Still no peers found in `%s'!\n"), networkIdDirectory); GNUNET_SCHEDULER_add_delayed_with_priority (DATA_HOST_FREQ, GNUNET_SCHEDULER_PRIORITY_IDLE, &cron_scan_directory_data_hosts, NULL); }
/** * Iterate over the expired items stored in the datastore. * Delete all expired items; once we have processed all * expired items, re-schedule the "delete_expired" task. * * @param cls not used * @param key key for the content * @param size number of bytes in data * @param data content stored * @param type type of the content * @param priority priority of the content * @param anonymity anonymity-level for the content * @param expiration expiration time for the content * @param uid unique identifier for the datum; * maybe 0 if no unique identifier is available * * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue * (continue on call to "next", of course), * GNUNET_NO to delete the item and continue (if supported) */ static int expired_processor (void *cls, const struct GNUNET_HashCode * key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, uint64_t uid) { struct GNUNET_TIME_Absolute now; if (key == NULL) { expired_kill_task = GNUNET_SCHEDULER_add_delayed_with_priority (MAX_EXPIRE_DELAY, GNUNET_SCHEDULER_PRIORITY_IDLE, &delete_expired, NULL); return GNUNET_SYSERR; } now = GNUNET_TIME_absolute_get (); if (expiration.abs_value_us > now.abs_value_us) { /* finished processing */ expired_kill_task = GNUNET_SCHEDULER_add_delayed_with_priority (MAX_EXPIRE_DELAY, GNUNET_SCHEDULER_PRIORITY_IDLE, &delete_expired, NULL); return GNUNET_SYSERR; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting content `%s' of type %u that expired %s ago\n", GNUNET_h2s (key), type, GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_difference (expiration, now), GNUNET_YES)); min_expiration = now; GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes expired"), size, GNUNET_YES); GNUNET_CONTAINER_bloomfilter_remove (filter, key); expired_kill_task = GNUNET_SCHEDULER_add_delayed_with_priority (MIN_EXPIRE_DELAY, GNUNET_SCHEDULER_PRIORITY_IDLE, &delete_expired, NULL); return GNUNET_NO; }
/** * Find our proof of work. * * @param cls closure (unused) */ static void find_proof (void *cls) { #define ROUND_SIZE 10 uint64_t counter; char buf[sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + sizeof (uint64_t)] GNUNET_ALIGN; struct GNUNET_HashCode result; unsigned int i; proof_task = NULL; GNUNET_memcpy (&buf[sizeof (uint64_t)], &my_identity, sizeof (struct GNUNET_PeerIdentity)); i = 0; counter = my_proof; while ((counter != UINT64_MAX) && (i < ROUND_SIZE)) { GNUNET_memcpy (buf, &counter, sizeof (uint64_t)); pow_hash (buf, sizeof (buf), &result); if (nse_work_required <= count_leading_zeroes (&result)) { my_proof = counter; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Proof of work found: %llu!\n", (unsigned long long) GNUNET_ntohll (counter)); write_proof (); setup_flood_message (estimate_index, current_timestamp); return; } counter++; i++; } if (my_proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing proofs currently at %llu\n", (unsigned long long) counter); /* remember progress every 100 rounds */ my_proof = counter; write_proof (); } else { my_proof = counter; } proof_task = GNUNET_SCHEDULER_add_delayed_with_priority (proof_find_delay, GNUNET_SCHEDULER_PRIORITY_IDLE, &find_proof, NULL); }
/** * Find our proof of work. * * @param cls closure (unused) * @param tc task context */ static void find_proof (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { #define ROUND_SIZE 10 uint64_t counter; char buf[sizeof (struct GNUNET_CRYPTO_EddsaPublicKey) + sizeof (uint64_t)] GNUNET_ALIGN; struct GNUNET_HashCode result; unsigned int i; struct GNUNET_TIME_Absolute timestamp; struct GNUNET_TIME_Relative elapsed; if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) { write_proof (); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got Proof of Work %llu\n", proof); proof_task = NULL; memcpy (&buf[sizeof (uint64_t)], &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); i = 0; counter = proof; timestamp = GNUNET_TIME_absolute_get (); while ((counter != UINT64_MAX) && (i < ROUND_SIZE)) { memcpy (buf, &counter, sizeof (uint64_t)); pow_hash (buf, sizeof (buf), &result); if (nse_work_required <= count_leading_zeroes (&result)) { proof = counter; FPRINTF (stdout, "Proof of work found: %llu!\n", (unsigned long long) proof); write_proof (); return; } counter++; i++; } elapsed = GNUNET_TIME_absolute_get_duration (timestamp); elapsed = GNUNET_TIME_relative_divide (elapsed, ROUND_SIZE); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Current: %llu [%s/proof]\n", (unsigned long long) counter, GNUNET_STRINGS_relative_time_to_string (elapsed, 0)); if (proof / (100 * ROUND_SIZE) < counter / (100 * ROUND_SIZE)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing proofs currently at %llu\n", (unsigned long long) counter); /* remember progress every 100 rounds */ proof = counter; write_proof (); } else { proof = counter; } proof_task = GNUNET_SCHEDULER_add_delayed_with_priority (proof_find_delay, GNUNET_SCHEDULER_PRIORITY_IDLE, &find_proof, NULL); }
/** * Testbed setup * * @param cls closure * @param server the initialized server * @param cfg configuration to use */ static void testbed_run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg) { static const struct GNUNET_SERVER_MessageHandler message_handlers[] = { {&handle_init, NULL, GNUNET_MESSAGE_TYPE_TESTBED_INIT, 0}, {&handle_add_host, NULL, GNUNET_MESSAGE_TYPE_TESTBED_ADD_HOST, 0}, {&GST_handle_link_controllers, NULL, GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS, sizeof (struct GNUNET_TESTBED_ControllerLinkRequest)}, {&GST_handle_peer_create, NULL, GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER, 0}, {&GST_handle_peer_destroy, NULL, GNUNET_MESSAGE_TYPE_TESTBED_DESTROY_PEER, sizeof (struct GNUNET_TESTBED_PeerDestroyMessage)}, {&GST_handle_peer_start, NULL, GNUNET_MESSAGE_TYPE_TESTBED_START_PEER, sizeof (struct GNUNET_TESTBED_PeerStartMessage)}, {&GST_handle_peer_stop, NULL, GNUNET_MESSAGE_TYPE_TESTBED_STOP_PEER, sizeof (struct GNUNET_TESTBED_PeerStopMessage)}, {&GST_handle_peer_get_config, NULL, GNUNET_MESSAGE_TYPE_TESTBED_GET_PEER_INFORMATION, sizeof (struct GNUNET_TESTBED_PeerGetConfigurationMessage)}, {&GST_handle_overlay_connect, NULL, GNUNET_MESSAGE_TYPE_TESTBED_OVERLAY_CONNECT, sizeof (struct GNUNET_TESTBED_OverlayConnectMessage)}, {&GST_handle_remote_overlay_connect, NULL, GNUNET_MESSAGE_TYPE_TESTBED_REMOTE_OVERLAY_CONNECT, 0}, {&GST_handle_manage_peer_service, NULL, GNUNET_MESSAGE_TYPE_TESTBED_MANAGE_PEER_SERVICE, 0}, {&handle_slave_get_config, NULL, GNUNET_MESSAGE_TYPE_TESTBED_GET_SLAVE_CONFIGURATION, sizeof (struct GNUNET_TESTBED_SlaveGetConfigurationMessage)}, {&GST_handle_shutdown_peers, NULL, GNUNET_MESSAGE_TYPE_TESTBED_SHUTDOWN_PEERS, sizeof (struct GNUNET_TESTBED_ShutdownPeersMessage)}, {&GST_handle_peer_reconfigure, NULL, GNUNET_MESSAGE_TYPE_TESTBED_RECONFIGURE_PEER, 0}, {&GST_handle_barrier_init, NULL, GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_INIT, 0}, {&GST_handle_barrier_cancel, NULL, GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_CANCEL, 0}, {&GST_handle_barrier_status, NULL, GNUNET_MESSAGE_TYPE_TESTBED_BARRIER_STATUS, 0}, {NULL, NULL, 0, 0} }; char *logfile; unsigned long long num; LOG_DEBUG ("Starting testbed\n"); if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, "TESTBED", "LOG_FILE", &logfile)) { GNUNET_break (GNUNET_OK == GNUNET_log_setup ("testbed", "DEBUG", logfile)); GNUNET_free (logfile); } GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "TESTBED", "CACHE_SIZE", &num)); GST_cache_init ((unsigned int) num); GST_connection_pool_init ((unsigned int) num); GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "TESTBED", "MAX_OPEN_FDS", &num)); GST_opq_openfds = GNUNET_TESTBED_operation_queue_create_ (OPERATION_QUEUE_TYPE_FIXED, (unsigned int) num); GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg, "TESTBED", "OPERATION_TIMEOUT", (struct GNUNET_TIME_Relative *) &GST_timeout)); GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, "testbed", "HOSTNAME", &hostname)); GST_config = GNUNET_CONFIGURATION_dup (cfg); GNUNET_SERVER_add_handlers (server, message_handlers); GNUNET_SERVER_disconnect_notify (server, &client_disconnect_cb, NULL); shutdown_task_id = GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_SCHEDULER_PRIORITY_IDLE, &shutdown_task, NULL); LOG_DEBUG ("Testbed startup complete\n"); GST_stats_init (GST_config); GST_barriers_init (GST_config); }
/** * Task run whenever it is time to restart a child that died. * * @param cls closure, always NULL * @param tc context */ static void delayed_restart_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct ServiceList *sl; struct GNUNET_TIME_Relative lowestRestartDelay; struct ServiceListeningInfo *sli; child_restart_task = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; GNUNET_assert (GNUNET_NO == in_shutdown); lowestRestartDelay = GNUNET_TIME_UNIT_FOREVER_REL; /* check for services that need to be restarted due to * configuration changes or because the last restart failed */ for (sl = running_head; NULL != sl; sl = sl->next) { if (NULL != sl->proc) continue; /* service is currently not running */ if (GNUNET_TIME_absolute_get_remaining (sl->restart_at).rel_value == 0) { /* restart is now allowed */ if (sl->is_default) { /* process should run by default, start immediately */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Restarting service `%s'.\n"), sl->name); start_process (sl); } else { /* process is run on-demand, ensure it is re-started if there is demand */ for (sli = sl->listen_head; NULL != sli; sli = sli->next) if (GNUNET_SCHEDULER_NO_TASK == sli->accept_task) { /* accept was actually paused, so start it again */ sli->accept_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, sli->listen_socket, &accept_connection, sli); } } } else { /* update calculation for earliest time to reactivate a service */ lowestRestartDelay = GNUNET_TIME_relative_min (lowestRestartDelay, GNUNET_TIME_absolute_get_remaining (sl->restart_at)); } } if (lowestRestartDelay.rel_value != GNUNET_TIME_UNIT_FOREVER_REL.rel_value) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Will restart process in %llums\n", (unsigned long long) lowestRestartDelay.rel_value); child_restart_task = GNUNET_SCHEDULER_add_delayed_with_priority (lowestRestartDelay, GNUNET_SCHEDULER_PRIORITY_IDLE, &delayed_restart_task, NULL); } }