/** * Test our plugin's configuration (NAT traversal, etc.). * * @param cfg configuration to test */ static void do_test_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg) { char *plugins; char *tok; unsigned long long bnd_port; unsigned long long adv_port; struct TestContext *tc; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "transport", "plugins", &plugins)) { FPRINTF (stderr, "%s", _ ("No transport plugins configured, peer will never communicate\n")); ret = 4; return; } for (tok = strtok (plugins, " "); tok != NULL; tok = strtok (NULL, " ")) { char section[12 + strlen (tok)]; GNUNET_snprintf (section, sizeof (section), "transport-%s", tok); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, section, "PORT", &bnd_port)) { FPRINTF (stderr, _("No port configured for plugin `%s', cannot test it\n"), tok); continue; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, section, "ADVERTISED_PORT", &adv_port)) adv_port = bnd_port; if (NULL == resolver) resolver = GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, NULL, NULL, "gnunet-service-resolver", "gnunet-service-resolver", NULL); resolver_users++; GNUNET_RESOLVER_connect (cfg); tc = GNUNET_malloc (sizeof (struct TestContext)); tc->name = GNUNET_strdup (tok); tc->tst = GNUNET_NAT_test_start (cfg, (0 == strcasecmp (tok, "udp")) ? GNUNET_NO : GNUNET_YES, (uint16_t) bnd_port, (uint16_t) adv_port, &result_callback, tc); if (NULL == tc->tst) { display_test_result (tc, GNUNET_SYSERR); continue; } tc->tsk = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &fail_timeout, tc); } GNUNET_free (plugins); }
/** * Try to connect to a service configured to use a SOCKS5 proxy. * * @param service_name name of service to connect to * @param cfg configuration to use * @return Connection handle that becomes usable when the handshake completes. * NULL if SOCKS not configured or not configured properly */ struct GNUNET_CONNECTION_Handle * GNUNET_SOCKS_do_connect (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_SOCKS_Handshake *ih; struct GNUNET_CONNECTION_Handle *socks5; /* *proxied */ char *host0,*host1,*user,*pass; unsigned long long port0,port1; if (GNUNET_YES != GNUNET_SOCKS_check_service (service_name, cfg)) return NULL; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "SOCKSPORT", &port0)) port0 = 9050; /* A typical Tor client should usually try port 9150 for the TBB too, but * GNUnet can probably assume a system Tor installation. */ if (port0 > 65535 || port0 <= 0) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Attempting to use invalid port %d as SOCKS proxy for service `%s'.\n"), port0, service_name); return NULL; } if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port1)) || (port1 > 65535) || (port1 <= 0) || (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME", &host1))) { LOG (GNUNET_ERROR_TYPE_WARNING, _ ("Attempting to proxy service `%s' to invalid port %d or hostname `%s'.\n"), service_name,port1,host1); return NULL; } /* Appeared to still work after host0 corrupted, so either test case is broken, or this whole routine is not being called. */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "SOCKSHOST", &host0)) host0 = NULL; socks5 = GNUNET_CONNECTION_create_from_connect (cfg, (host0 != NULL)? host0:"127.0.0.1", port0); GNUNET_free_non_null (host0); /* Sets to NULL if they do not exist */ (void) GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "SOCKSUSER", &user); (void) GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "SOCKSPASS", &pass); ih = GNUNET_SOCKS_init_handshake(user,pass); if (NULL != user) GNUNET_free (user); if (NULL != pass) GNUNET_free (pass); GNUNET_SOCKS_set_handshake_destination (ih,host1,port1); GNUNET_free (host1); return GNUNET_SOCKS_run_handshake(ih,socks5); }
/** * Main function that will be run. * * @param cls closure * @param args remaining command-line arguments * @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param c configuration */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { static struct GNUNET_CORE_MessageHandler handlers[] = { {&handle_encrypted_hello, GNUNET_MESSAGE_TYPE_HELLO, 0}, {NULL, 0, 0} }; unsigned long long opt; cfg = c; stats = GNUNET_STATISTICS_create ("topology", cfg); friends_only = GNUNET_CONFIGURATION_get_value_yesno (cfg, "TOPOLOGY", "FRIENDS-ONLY"); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "TOPOLOGY", "MINIMUM-FRIENDS", &opt)) opt = 0; minimum_friend_count = (unsigned int) opt; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "TOPOLOGY", "TARGET-CONNECTION-COUNT", &opt)) opt = 16; target_connection_count = (unsigned int) opt; peers = GNUNET_CONTAINER_multihashmap_create (target_connection_count * 2, GNUNET_NO); if ((friends_only == GNUNET_YES) || (minimum_friend_count > 0)) read_friends_file (cfg); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Topology would like %u connections with at least %u friends\n", target_connection_count, minimum_friend_count); if ((friend_count < minimum_friend_count) && (blacklist == NULL)) blacklist = GNUNET_TRANSPORT_blacklist (cfg, &blacklist_check, NULL); transport = GNUNET_TRANSPORT_connect (cfg, NULL, NULL, NULL, NULL, NULL); handle = GNUNET_CORE_connect (cfg, NULL, &core_init, &connect_notify, &disconnect_notify, NULL, GNUNET_NO, NULL, GNUNET_NO, handlers); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task, NULL); if (NULL == transport) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to `%s' service.\n"), "transport"); GNUNET_SCHEDULER_shutdown (); return; } if (NULL == handle) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to `%s' service.\n"), "core"); GNUNET_SCHEDULER_shutdown (); return; } }
/** * Try connecting to the server using UNIX domain sockets. * * @param service_name name of service to connect to * @param cfg configuration to use * @return GNUNET_OK if the configuration is valid, GNUNET_SYSERR if not */ static int test_service_configuration (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg) { int ret = GNUNET_SYSERR; char *hostname = NULL; unsigned long long port; #if AF_UNIX char *unixpath = NULL; if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) ret = GNUNET_OK; GNUNET_free_non_null (unixpath); #endif if ( (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port)) && (port <= 65535) && (0 != port) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME", &hostname)) && (0 != strlen (hostname)) ) ret = GNUNET_OK; GNUNET_free_non_null (hostname); return ret; }
/** * Process dht requests. * * @param cls closure * @param server the initialized server * @param c configuration to use */ static void run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c) { unsigned long long _track_topology; GDS_cfg = c; GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); GDS_stats = GNUNET_STATISTICS_create ("dht", GDS_cfg); GDS_ROUTING_init (); GDS_NSE_init (); GDS_DATACACHE_init (); GDS_CLIENTS_init (server); if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (c, "xdht", "track_toplogy", &_track_topology)) { track_topology = (unsigned int) _track_topology; } if (GNUNET_OK != GDS_NEIGHBOURS_init ()) { shutdown_task (NULL, NULL); return; } GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); }
/** * Entry point for the plugin. * * @param cls the "struct GNUNET_DATASTORE_PluginEnvironment*" * @return our "struct Plugin*" */ void * libgnunet_plugin_datastore_heap_init (void *cls) { struct GNUNET_DATASTORE_PluginEnvironment *env = cls; struct GNUNET_DATASTORE_PluginFunctions *api; struct Plugin *plugin; unsigned long long esize; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (env->cfg, "datastore-heap", "HASHMAPSIZE", &esize)) esize = 128 * 1024; plugin = GNUNET_malloc (sizeof (struct Plugin)); plugin->env = env; plugin->keyvalue = GNUNET_CONTAINER_multihashmap_create (esize, GNUNET_YES); plugin->by_expiration = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); plugin->by_replication = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX); api = GNUNET_malloc (sizeof (struct GNUNET_DATASTORE_PluginFunctions)); api->cls = plugin; api->estimate_size = &heap_plugin_estimate_size; api->put = &heap_plugin_put; api->update = &heap_plugin_update; api->get_key = &heap_plugin_get_key; api->get_replication = &heap_plugin_get_replication; api->get_expiration = &heap_plugin_get_expiration; api->get_zero_anonymity = &heap_plugin_get_zero_anonymity; api->drop = &heap_plugin_drop; api->get_keys = &heap_get_keys; GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "heap", _("Heap database running\n")); return api; }
/** * Initialize the DHT subsystem. * * @param c Configuration. */ void GCD_init (const struct GNUNET_CONFIGURATION_Handle *c) { LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n"); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c, "CADET", "DHT_REPLICATION_LEVEL", &dht_replication_level)) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, "CADET", "DHT_REPLICATION_LEVEL", "USING DEFAULT"); dht_replication_level = 3; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (c, "CADET", "ID_ANNOUNCE_TIME", &id_announce_time)) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "CADET", "ID_ANNOUNCE_TIME", "MISSING"); GNUNET_SCHEDULER_shutdown (); return; } dht_handle = GNUNET_DHT_connect (c, 64); if (NULL == dht_handle) { GNUNET_break (0); } announce_delay = GNUNET_TIME_UNIT_SECONDS; announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, NULL); get_requests = GNUNET_CONTAINER_multihashmap32_create (32); }
/** * Core handler for p2p hostlist advertisements */ static int ad_arrive_handler (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message) { char *hostname; char *expected_uri; unsigned long long port; const struct GNUNET_MessageHeader *incoming; const char *end; if (-1 == GNUNET_CONFIGURATION_get_value_number (adv_peer.cfg, "HOSTLIST", "HTTPPORT", &port)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not read advertising server's configuration\n"); return GNUNET_SYSERR; } if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (adv_peer.cfg, "HOSTLIST", "EXTERNAL_DNS_NAME", &hostname)) hostname = GNUNET_RESOLVER_local_fqdn_get (); GNUNET_asprintf (&expected_uri, "http://%s:%u/", hostname != NULL ? hostname : "localhost", (unsigned int) port); incoming = (const struct GNUNET_MessageHeader *) message; end = (const char *) &incoming[1]; if ('\0' != end[ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - 1]) { GNUNET_break (0); GNUNET_free (expected_uri); GNUNET_free_non_null (hostname); return GNUNET_SYSERR; } current_adv_uri = GNUNET_strdup (end); if (0 == strcmp (expected_uri, current_adv_uri)) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Received hostlist advertisement with URI `%s' as expected\n", current_adv_uri); adv_arrived = GNUNET_YES; adv_sent = GNUNET_YES; } else GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Expected URI `%s' and received URI `%s' differ\n", expected_uri, current_adv_uri); GNUNET_free (expected_uri); GNUNET_free_non_null (hostname); return GNUNET_OK; }
/** * Initialize subsystem for non-anonymous file-sharing. */ void GSF_stream_start () { stream_map = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES); if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_number (GSF_cfg, "fs", "MAX_STREAM_CLIENTS", &sc_count_max)) { listen_socket = GNUNET_STREAM_listen (GSF_cfg, GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER, &accept_cb, NULL, GNUNET_STREAM_OPTION_END); } }
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { ok = 1; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons based on config file %s\n", cfgfile); if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", &test_directory)) { ok = 404; return; } if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", &num_peers)) num_peers = DEFAULT_NUM_PEERS; main_cfg = cfg; peers_left = num_peers; GNUNET_assert (num_peers > 0 && num_peers < (unsigned int) -1); /* For this specific test we only really want a CLIQUE topology as the * overlay allowed topology, and a RING topology as the underlying connection * allowed topology. So we will expect only num_peers * 2 connections to * work, and (num_peers * (num_peers - 1)) - (num_peers * 2) to fail. */ expected_connections = num_peers * (num_peers - 1); expected_failed_connections = expected_connections - (num_peers * 2); /* Set up a task to end testing if peer start fails */ die_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5), &end_badly, "didn't start all daemons in reasonable amount of time!!!"); pg = GNUNET_TESTING_daemons_start (cfg, peers_left, peers_left, peers_left, TIMEOUT, NULL, NULL, &peers_started_callback, NULL, NULL, NULL, NULL); }
/** * Configure plugin * * @param plugin the plugin handle * @return GNUNET_OK on success, GNUNET_SYSERR on failure */ static int client_configure_plugin (struct HTTP_Client_Plugin *plugin) { unsigned long long max_connections; /* Optional parameters */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name, "MAX_CONNECTIONS", &max_connections)) max_connections = 128; plugin->max_connections = max_connections; GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, _("Maximum number of connections is %u\n"), plugin->max_connections); return GNUNET_OK; }
/** * Determine our external IPv4 address and port using an external STUN server * * @param ah auto setup context */ static void test_stun (struct GNUNET_NAT_AutoHandle *ah) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Running STUN test\n"); /* Get port from the configuration */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (ah->cfg, "transport-udp", "PORT", &port)) { port = 2086; } //Lets create the socket lsock4 = bind_v4 (); if (NULL == lsock4) { GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind"); next_phase(ah); return; } else { //Lets call our function now when it accepts ltask4 = GNUNET_SCHEDULER_add_read_net (NAT_SERVER_TIMEOUT, lsock4, &do_udp_read, ah); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "STUN service listens on port %u\n", port); if (GNUNET_NO == GNUNET_NAT_stun_make_request (stun_server, stun_port, lsock4, &request_callback, NULL)) { /*An error happened*/ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "STUN error, stopping\n"); stop_stun (); next_phase (ah); } }
/** * run: load configuration options and schedule test to run (start peergroup) * @param cls closure * @param args argv * @param cfgfile configuration file name (can be NULL) * @param cfg configuration handle */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_TESTING_Host *hosts; ok = GNUNET_NO; total_connections = 0; failed_connections = 0; testing_cfg = GNUNET_CONFIGURATION_dup (cfg); GNUNET_log_setup ("test_testing_2dtorus", #if VERBOSE "DEBUG", #else "WARNING", #endif NULL); #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Starting daemons.\n"); GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing", "use_progressbars", "YES"); #endif if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing", "num_peers", &num_peers)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Option TESTING:NUM_PEERS is required!\n"); return; } hosts = GNUNET_TESTING_hosts_load (testing_cfg); pg = GNUNET_TESTING_peergroup_start (testing_cfg, num_peers, TIMEOUT, &connect_cb, &peergroup_ready, NULL, hosts); GNUNET_assert (pg != NULL); shutdown_handle = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); }
/** * Initialize NSE subsystem. */ void GDS_NSE_init () { unsigned long long hops; if ( (GNUNET_YES == GNUNET_CONFIGURATION_have_value (GDS_cfg, "dht", "FORCE_NSE")) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (GDS_cfg, "dht", "FORCE_NSE", &hops)) ) { log_of_network_size_estimate = (double) hops; return; } nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL); }
/** * Function called with th test result to see if the resolver is * running. * * @param cls closure with our configuration * @param result #GNUNET_YES if the resolver is running */ static void resolver_test_task (void *cls, int result) { struct GNUNET_CONFIGURATION_Handle *cfg = cls; if (GNUNET_YES != result) { FPRINTF (stderr, _("Trying to connect to remote host, but service `%s' is not running\n"), "resolver"); return; } /* connect to a remote host */ if (0 == remote_port) { if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, "statistics", "PORT", &remote_port)) { FPRINTF (stderr, _("A port is required to connect to host `%s'\n"), remote_host); return; } } else if (65535 <= remote_port) { FPRINTF (stderr, _("A port has to be between 1 and 65535 to connect to host `%s'\n"), remote_host); return; } /* Manipulate configuration */ GNUNET_CONFIGURATION_set_value_string (cfg, "statistics", "UNIXPATH", ""); GNUNET_CONFIGURATION_set_value_string (cfg, "statistics", "HOSTNAME", remote_host); GNUNET_CONFIGURATION_set_value_number (cfg, "statistics", "PORT", remote_port); GNUNET_SCHEDULER_add_now (&main_task, cfg); }
/** * Main function that will be run by the scheduler. * * @param cls closure * @param args remaining command-line arguments * @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param cfg configuration */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *config) { struct GNUNET_CRYPTO_EddsaPrivateKey *pk; char *pids; cfg = config; /* load proof of work */ if (NULL == pwfn) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &pwfn)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE"); GNUNET_SCHEDULER_shutdown (); return; } } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Proof of Work file: %s\n", pwfn); if ( (GNUNET_YES != GNUNET_DISK_file_test (pwfn)) || (sizeof (proof) != GNUNET_DISK_fn_read (pwfn, &proof, sizeof (proof)))) proof = 0; /* load private key */ if (NULL == pkfn) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "PEER", "PRIVATE_KEY", &pkfn)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "PEER", "PRIVATE_KEY"); return; } } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Private Key file: %s\n", pkfn); if (NULL == (pk = GNUNET_CRYPTO_eddsa_key_create_from_file (pkfn))) { FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), pkfn); GNUNET_free (pkfn); return; } GNUNET_free (pkfn); GNUNET_CRYPTO_eddsa_key_get_public (pk, &pub); GNUNET_free (pk); pids = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Peer ID: %s\n", pids); GNUNET_free (pids); /* get target bit amount */ if (0 == nse_work_required) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS", &nse_work_required)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS"); GNUNET_SCHEDULER_shutdown (); return; } if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS", _("Value is too large.\n")); GNUNET_SCHEDULER_shutdown (); return; } else if (0 == nse_work_required) { write_proof (); GNUNET_SCHEDULER_shutdown (); return; } } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Bits: %llu\n", nse_work_required); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Delay between tries: %s\n", GNUNET_STRINGS_relative_time_to_string (proof_find_delay, 1)); GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, &find_proof, NULL); }
/** * Test if the service is running. If we are given a UNIXPATH or a local address, * we do this NOT by trying to connect to the service, but by trying to BIND to * the same port. If the BIND fails, we know the service is running. * * @param service name of the service to wait for * @param cfg configuration to use * @param timeout how long to wait at most * @param task task to run if service is running * (reason will be "PREREQ_DONE" (service running) * or "TIMEOUT" (service not known to be running)) * @param task_cls closure for task */ void GNUNET_CLIENT_service_test (const char *service, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TIME_Relative timeout, GNUNET_SCHEDULER_Task task, void *task_cls) { char *hostname; unsigned long long port; struct GNUNET_NETWORK_Handle *sock; struct GNUNET_CLIENT_Connection *client; LOG (GNUNET_ERROR_TYPE_DEBUG, "Testing if service `%s' is running.\n", service); #ifdef AF_UNIX { /* probe UNIX support */ struct sockaddr_un s_un; size_t slen; char *unixpath; unixpath = NULL; if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) /* We have a non-NULL unixpath, does that mean it's valid? */ { if (strlen (unixpath) >= sizeof (s_un.sun_path)) { LOG (GNUNET_ERROR_TYPE_WARNING, _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath, (unsigned long long) sizeof (s_un.sun_path)); unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); LOG (GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath); } } if (NULL != unixpath) { sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); if (NULL != sock) { memset (&s_un, 0, sizeof (s_un)); s_un.sun_family = AF_UNIX; slen = strlen (unixpath) + 1; if (slen >= sizeof (s_un.sun_path)) slen = sizeof (s_un.sun_path) - 1; memcpy (s_un.sun_path, unixpath, slen); s_un.sun_path[slen] = '\0'; slen = sizeof (struct sockaddr_un); #if LINUX s_un.sun_path[0] = '\0'; #endif #if HAVE_SOCKADDR_IN_SIN_LEN s_un.sun_len = (u_char) slen; #endif if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_un, slen)) { /* failed to bind => service must be running */ GNUNET_free (unixpath); (void) GNUNET_NETWORK_socket_close (sock); GNUNET_SCHEDULER_add_continuation (task, task_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); return; } (void) GNUNET_NETWORK_socket_close (sock); /* let's try IP */ } } GNUNET_free_non_null (unixpath); } #endif hostname = NULL; if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, service, "PORT", &port)) || (port > 65535) || (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME", &hostname))) { /* UNIXPATH failed (if possible) AND IP failed => error */ service_test_error (task, task_cls); return; } if (0 == strcmp ("localhost", hostname) #if !LINUX && 0 #endif ) { /* can test using 'bind' */ struct sockaddr_in s_in; memset (&s_in, 0, sizeof (s_in)); #if HAVE_SOCKADDR_IN_SIN_LEN s_in.sin_len = sizeof (struct sockaddr_in); #endif s_in.sin_family = AF_INET; s_in.sin_port = htons (port); sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); if (NULL != sock) { if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in, sizeof (s_in))) { /* failed to bind => service must be running */ GNUNET_free (hostname); (void) GNUNET_NETWORK_socket_close (sock); GNUNET_SCHEDULER_add_continuation (task, task_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); return; } (void) GNUNET_NETWORK_socket_close (sock); } } if (0 == strcmp ("ip6-localhost", hostname) #if !LINUX && 0 #endif ) { /* can test using 'bind' */ struct sockaddr_in6 s_in6; memset (&s_in6, 0, sizeof (s_in6)); #if HAVE_SOCKADDR_IN_SIN_LEN s_in6.sin6_len = sizeof (struct sockaddr_in6); #endif s_in6.sin6_family = AF_INET6; s_in6.sin6_port = htons (port); sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0); if (NULL != sock) { if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in6, sizeof (s_in6))) { /* failed to bind => service must be running */ GNUNET_free (hostname); (void) GNUNET_NETWORK_socket_close (sock); GNUNET_SCHEDULER_add_continuation (task, task_cls, GNUNET_SCHEDULER_REASON_PREREQ_DONE); return; } (void) GNUNET_NETWORK_socket_close (sock); } } if (((0 == strcmp ("localhost", hostname)) || (0 == strcmp ("ip6-localhost", hostname))) #if !LINUX && 0 #endif ) { /* all binds succeeded => claim service not running right now */ GNUNET_free_non_null (hostname); service_test_error (task, task_cls); return; } GNUNET_free_non_null (hostname); /* non-localhost, try 'connect' method */ client = GNUNET_CLIENT_connect (service, cfg); if (NULL == client) { LOG (GNUNET_ERROR_TYPE_INFO, _("Could not connect to service `%s', must not be running.\n"), service); service_test_error (task, task_cls); return; } client->test_cb = task; client->test_cb_cls = task_cls; client->test_deadline = GNUNET_TIME_relative_to_absolute (timeout); if (NULL == GNUNET_CLIENT_notify_transmit_ready (client, sizeof (struct GNUNET_MessageHeader), timeout, GNUNET_YES, &write_test, client)) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failure to transmit request to service `%s'\n"), service); service_test_error (task, task_cls); GNUNET_CLIENT_disconnect (client); return; } }
/** * Try to connect to the service. * * @param service_name name of service to connect to * @param cfg configuration to use * @param attempt counter used to alternate between IP and UNIX domain sockets * @return NULL on error */ static struct GNUNET_CONNECTION_Handle * do_connect (const char *service_name, const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int attempt) { struct GNUNET_CONNECTION_Handle *connection; char *hostname; unsigned long long port; connection = NULL; if (0 == (attempt % 2)) { /* on even rounds, try UNIX first */ connection = try_unixpath (service_name, cfg); if (NULL != connection) return connection; } if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT")) { if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port)) || (port > 65535) || (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME", &hostname))) { LOG (GNUNET_ERROR_TYPE_WARNING, _ ("Could not determine valid hostname and port for service `%s' from configuration.\n"), service_name); return NULL; } if (0 == strlen (hostname)) { GNUNET_free (hostname); LOG (GNUNET_ERROR_TYPE_WARNING, _("Need a non-empty hostname for service `%s'.\n"), service_name); return NULL; } } else { /* unspecified means 0 (disabled) */ port = 0; hostname = NULL; } if (0 == port) { /* if port is 0, try UNIX */ connection = try_unixpath (service_name, cfg); if (NULL != connection) return connection; LOG (GNUNET_ERROR_TYPE_DEBUG, "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n", service_name); GNUNET_free_non_null (hostname); return NULL; } connection = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port); GNUNET_free (hostname); return connection; }
static int configure_plugin (struct Plugin *plugin) { int res = GNUNET_OK; /* Use IPv4? */ if (GNUNET_CONFIGURATION_have_value (plugin->env->cfg, plugin->name, "USE_IPv4")) { plugin->ipv4 = GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name, "USE_IPv4"); } else plugin->ipv4 = GNUNET_YES; /* Use IPv6? */ if (GNUNET_CONFIGURATION_have_value (plugin->env->cfg, plugin->name, "USE_IPv6")) { plugin->ipv6 = GNUNET_CONFIGURATION_get_value_yesno (plugin->env->cfg, plugin->name, "USE_IPv6"); } else plugin->ipv6 = GNUNET_YES; if ((plugin->ipv4 == GNUNET_NO) && (plugin->ipv6 == GNUNET_NO)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, _ ("Neither IPv4 nor IPv6 are enabled! Fix in configuration\n"), plugin->name); res = GNUNET_SYSERR; } /* Reading port number from config file */ unsigned long long port; if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name, "PORT", &port)) || (port > 65535)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, _("Port is required! Fix in configuration\n"), plugin->name); res = GNUNET_SYSERR; goto fail; } plugin->port = port; plugin->client_only = GNUNET_NO; if (plugin->port == 0) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, _("Port 0, client only mode\n")); plugin->client_only = GNUNET_YES; } char *bind4_address = NULL; if ((plugin->ipv4 == GNUNET_YES) && (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name, "BINDTO", &bind4_address))) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Binding %s plugin to specific IPv4 address: `%s'\n", plugin->protocol, bind4_address); plugin->server_addr_v4 = GNUNET_malloc (sizeof (struct sockaddr_in)); if (1 != inet_pton (AF_INET, bind4_address, &plugin->server_addr_v4->sin_addr)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, _ ("Specific IPv4 address `%s' for plugin %s in configuration file is invalid! Binding to all addresses!\n"), bind4_address, plugin->protocol); GNUNET_free (plugin->server_addr_v4); plugin->server_addr_v4 = NULL; } else { plugin->server_addr_v4->sin_family = AF_INET; plugin->server_addr_v4->sin_port = htons (plugin->port); } GNUNET_free (bind4_address); } char *bind6_address = NULL; if ((plugin->ipv6 == GNUNET_YES) && (GNUNET_YES == GNUNET_CONFIGURATION_get_value_string (plugin->env->cfg, plugin->name, "BINDTO6", &bind6_address))) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, "Binding %s plugin to specific IPv6 address: `%s'\n", plugin->protocol, bind6_address); plugin->server_addr_v6 = GNUNET_malloc (sizeof (struct sockaddr_in6)); if (1 != inet_pton (AF_INET6, bind6_address, &plugin->server_addr_v6->sin6_addr)) { GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, _ ("Specific IPv6 address `%s' for plugin %s in configuration file is invalid! Binding to all addresses!\n"), bind6_address, plugin->protocol); GNUNET_free (plugin->server_addr_v6); plugin->server_addr_v6 = NULL; } else { plugin->server_addr_v6->sin6_family = AF_INET6; plugin->server_addr_v6->sin6_port = htons (plugin->port); } GNUNET_free (bind6_address); } /* Optional parameters */ unsigned long long maxneigh; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (plugin->env->cfg, plugin->name, "MAX_CONNECTIONS", &maxneigh)) maxneigh = 128; plugin->max_connections = maxneigh; fail: return res; }
/** * Process GNS requests. * * @param cls closure) * @param server the initialized server * @param c configuration to use */ static void run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c) { GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Initializing GNS\n"); char* keyfile; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey; unsigned long long max_parallel_bg_queries = 0; unsigned long long default_lookup_timeout_secs = 0; int ignore_pending = GNUNET_NO; static const struct GNUNET_SERVER_MessageHandler handlers[] = { {&handle_shorten, NULL, GNUNET_MESSAGE_TYPE_GNS_SHORTEN, 0}, {&handle_lookup, NULL, GNUNET_MESSAGE_TYPE_GNS_LOOKUP, 0}, {&handle_get_authority, NULL, GNUNET_MESSAGE_TYPE_GNS_GET_AUTH, 0} }; GNS_cfg = c; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c, "gns", "ZONEKEY", &keyfile)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No private key for root zone specified!\n"); GNUNET_SCHEDULER_shutdown (); return; } GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Using keyfile %s for root zone.\n", keyfile); zone_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); GNUNET_CRYPTO_rsa_key_get_public (zone_key, &pkey); GNUNET_CRYPTO_short_hash(&pkey, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_hash); GNUNET_free(keyfile); /** * handle to our local namestore */ namestore_handle = GNUNET_NAMESTORE_connect(c); if (NULL == namestore_handle) { //FIXME do error handling; GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to the namestore!\n"); GNUNET_SCHEDULER_shutdown (); return; } auto_import_pkey = GNUNET_NO; if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (c, "gns", "AUTO_IMPORT_PKEY")) { GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Automatic PKEY import is enabled.\n"); auto_import_pkey = GNUNET_YES; } dht_max_update_interval = GNUNET_GNS_DHT_MAX_UPDATE_INTERVAL; if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (c, "gns", "ZONE_PUT_INTERVAL", &dht_max_update_interval)) { GNUNET_log(GNUNET_ERROR_TYPE_INFO, "DHT zone update interval: %d\n", dht_max_update_interval); } max_record_put_interval = 1; if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (c, "gns", "RECORD_PUT_INTERVAL", &max_record_put_interval)) { GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Record put interval: %d\n", max_record_put_interval); } if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (c, "gns", "MAX_PARALLEL_BACKGROUND_QUERIES", &max_parallel_bg_queries)) { GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Number of allowed parallel background queries: %d\n", max_parallel_bg_queries); } if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (c, "gns", "AUTO_IMPORT_CONFIRMATION_REQ")) { GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Auto import requires user confirmation\n"); ignore_pending = GNUNET_YES; } if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(c, "gns", "DEFAULT_LOOKUP_TIMEOUT", &default_lookup_timeout_secs)) { GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Default lookup timeout: %ds\n", default_lookup_timeout_secs); default_lookup_timeout = GNUNET_TIME_relative_multiply( GNUNET_TIME_UNIT_SECONDS, default_lookup_timeout_secs); } /** * handle to the dht */ dht_handle = GNUNET_DHT_connect(c, //max_parallel_bg_queries); //FIXME get ht_len from cfg 1024); if (NULL == dht_handle) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not connect to DHT!\n"); } if (gns_resolver_init(namestore_handle, dht_handle, zone_hash, max_parallel_bg_queries, ignore_pending) == GNUNET_SYSERR) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Unable to initialize resolver!\n"); GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); return; } if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (c, "gns", "HIJACK_DNS")) { GNUNET_log(GNUNET_ERROR_TYPE_INFO, "DNS hijacking enabled... connecting to service.\n"); if (gns_interceptor_init(zone_hash, zone_key, c) == GNUNET_SYSERR) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to enable the dns interceptor!\n"); } } /** * Schedule periodic put * for our records * We have roughly an hour for all records; */ record_put_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1); zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_start, NULL); GNUNET_SERVER_add_handlers (server, handlers); //FIXME //GNUNET_SERVER_disconnect_notify (server, // &client_disconnect_notification, // NULL); nc = GNUNET_SERVER_notification_context_create (server, 1); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); }
/** * Process sensordashboard requests. * * @param cls closure * @param server the initialized server * @param cfg configuration to use */ static void run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg) { static const struct GNUNET_SERVER_MessageHandler handlers[] = { {NULL, NULL, 0, 0} }; static struct GNUNET_CADET_MessageHandler cadet_handlers[] = { {&handle_sensor_reading, GNUNET_MESSAGE_TYPE_SENSOR_READING, 0}, {&handle_sensor_list_req, GNUNET_MESSAGE_TYPE_SENSOR_LIST_REQ, sizeof (struct GNUNET_MessageHeader)}, {&handle_sensor_full_req, GNUNET_MESSAGE_TYPE_SENSOR_FULL_REQ, sizeof (struct GNUNET_MessageHeader)}, {&handle_anomaly_report, GNUNET_MESSAGE_TYPE_SENSOR_ANOMALY_REPORT, sizeof (struct GNUNET_MessageHeader) + sizeof (struct GNUNET_SENSOR_crypto_pow_block) + sizeof (struct GNUNET_SENSOR_AnomalyReportMessage)}, {NULL, 0, 0} }; static uint32_t cadet_ports[] = { GNUNET_APPLICATION_TYPE_SENSORDASHBOARD, GNUNET_APPLICATION_TYPE_SENSORUPDATE, GNUNET_APPLICATION_TYPE_END }; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "SENSOR", "SENSOR_DIR", &sensor_dir)) sensor_dir = GNUNET_SENSOR_get_default_sensor_dir (); sensors = GNUNET_SENSOR_load_all_sensors (sensor_dir); GNUNET_assert (NULL != sensors); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "sensor-reporting", "POW_MATCHING_BITS", &pow_matching_bits)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "sensor-reporting", "POW_MATCHING_BITS"); GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); return; } if (pow_matching_bits > sizeof (struct GNUNET_HashCode)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Matching bits value too large (%d > %d).\n", pow_matching_bits, sizeof (struct GNUNET_HashCode)); GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); return; } cadet = GNUNET_CADET_connect (cfg, NULL, &cadet_channel_created, &cadet_channel_destroyed, cadet_handlers, cadet_ports); if (NULL == cadet) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to `%s' service.\n"), "CADET"); GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); return; } peerstore = GNUNET_PEERSTORE_connect (cfg); if (NULL == peerstore) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to `%s' service.\n"), "PEERSTORE"); GNUNET_SCHEDULER_add_now (&cleanup_task, NULL); return; } GNUNET_SERVER_add_handlers (server, handlers); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task, NULL); }
/** * Initiate transport service. * * @param cls closure * @param server the initialized server * @param c configuration to use */ static void run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c) { char *keyfile; struct GNUNET_CRYPTO_EddsaPrivateKey *pk; long long unsigned int max_fd_cfg; int max_fd_rlimit; int max_fd; int friend_only; /* setup globals */ GST_cfg = c; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c, "PEER", "PRIVATE_KEY", &keyfile)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Transport service is lacking key configuration settings. Exiting.\n")); GNUNET_SCHEDULER_shutdown (); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (c, "transport", "HELLO_EXPIRATION", &hello_expiration)) { hello_expiration = GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION; } GST_server = server; pk = GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile); GNUNET_free (keyfile); GNUNET_assert (NULL != pk); GST_my_private_key = pk; GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg); GST_peerinfo = GNUNET_PEERINFO_connect (GST_cfg); GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key, &GST_my_identity.public_key); GNUNET_assert(NULL != GST_my_private_key); GNUNET_log(GNUNET_ERROR_TYPE_INFO, "My identity is `%4s'\n", GNUNET_i2s_full (&GST_my_identity)); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); if (NULL == GST_peerinfo) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Could not access PEERINFO service. Exiting.\n")); GNUNET_SCHEDULER_shutdown (); return; } max_fd_rlimit = 0; max_fd_cfg = 0; #if HAVE_GETRLIMIT struct rlimit r_file; if (0 == getrlimit (RLIMIT_NOFILE, &r_file)) { max_fd_rlimit = r_file.rlim_cur; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Maximum number of open files was: %u/%u\n", r_file.rlim_cur, r_file.rlim_max); } max_fd_rlimit = (9 * max_fd_rlimit) / 10; /* Keep 10% for rest of transport */ #endif GNUNET_CONFIGURATION_get_value_number (GST_cfg, "transport", "MAX_FD", &max_fd_cfg); if (max_fd_cfg > max_fd_rlimit) max_fd = max_fd_cfg; else max_fd = max_fd_rlimit; if (max_fd < DEFAULT_MAX_FDS) max_fd = DEFAULT_MAX_FDS; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Limiting number of sockets to %u: validation %u, neighbors: %u\n", max_fd, (max_fd / 3), (max_fd / 3) * 2); friend_only = GNUNET_CONFIGURATION_get_value_yesno (GST_cfg, "topology", "FRIENDS-ONLY"); if (GNUNET_SYSERR == friend_only) friend_only = GNUNET_NO; /* According to topology defaults */ /* start subsystems */ GST_blacklist_start (GST_server, GST_cfg, &GST_my_identity); GST_is = GNUNET_ATS_scanner_init (); GST_ats_connect = GNUNET_ATS_connectivity_init (GST_cfg); GST_ats = GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, NULL); GST_ats_init (); GST_manipulation_init (); GST_plugins_load (&GST_manipulation_recv, &plugin_env_address_change_notification, &plugin_env_session_start, &plugin_env_session_end); GST_hello_start (friend_only, &process_hello_update, NULL); GST_neighbours_start ((max_fd / 3) * 2); GST_clients_start (GST_server); GST_validation_start ((max_fd / 3)); }
/** * Test if the service is running. If we are given a UNIXPATH or a * local address, we do this NOT by trying to connect to the service, * but by trying to BIND to the same port. If the BIND fails, we know * the service is running. * * @param service name of the service to wait for * @param cfg configuration to use * @param timeout how long to wait at most * @param cb function to call with the result * @param cb_cls closure for @a cb * @return handle to cancel the test */ struct GNUNET_CLIENT_TestHandle * GNUNET_CLIENT_service_test (const char *service, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TIME_Relative timeout, GNUNET_CLIENT_TestResultCallback cb, void *cb_cls) { struct GNUNET_CLIENT_TestHandle *th; char *hostname; unsigned long long port; struct GNUNET_NETWORK_Handle *sock; th = GNUNET_new (struct GNUNET_CLIENT_TestHandle); th->cb = cb; th->cb_cls = cb_cls; th->test_deadline = GNUNET_TIME_relative_to_absolute (timeout); LOG (GNUNET_ERROR_TYPE_DEBUG, "Testing if service `%s' is running.\n", service); #ifdef AF_UNIX { /* probe UNIX support */ struct sockaddr_un s_un; char *unixpath; int abstract; unixpath = NULL; if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, service, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath))) /* We have a non-NULL unixpath, does that mean it's valid? */ { if (strlen (unixpath) >= sizeof (s_un.sun_path)) { LOG (GNUNET_ERROR_TYPE_WARNING, _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath, (unsigned long long) sizeof (s_un.sun_path)); unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath); LOG (GNUNET_ERROR_TYPE_INFO, _("Using `%s' instead\n"), unixpath); } } #ifdef LINUX abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg, "TESTING", "USE_ABSTRACT_SOCKETS"); #else abstract = GNUNET_NO; #endif if ((NULL != unixpath) && (GNUNET_YES != abstract)) { if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (unixpath)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "mkdir", unixpath); } if (NULL != unixpath) { sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0); if (NULL != sock) { memset (&s_un, 0, sizeof (s_un)); s_un.sun_family = AF_UNIX; strncpy (s_un.sun_path, unixpath, sizeof (s_un.sun_path) - 1); if (GNUNET_YES == abstract) s_un.sun_path[0] = '\0'; #if HAVE_SOCKADDR_IN_SIN_LEN s_un.sun_len = (u_char) sizeof (struct sockaddr_un); #endif if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_un, sizeof (struct sockaddr_un))) { /* failed to bind => service must be running */ GNUNET_free (unixpath); (void) GNUNET_NETWORK_socket_close (sock); service_test_report (th, GNUNET_YES); return th; } (void) GNUNET_NETWORK_socket_close (sock); /* let's try IP */ } } GNUNET_free_non_null (unixpath); } #endif hostname = NULL; if ((GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, service, "PORT", &port)) || (port > 65535) || (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME", &hostname))) { /* UNIXPATH failed (if possible) AND IP failed => error */ service_test_report (th, GNUNET_SYSERR); return th; } if (0 == strcmp ("localhost", hostname) #if !LINUX && 0 #endif ) { /* can test using 'bind' */ struct sockaddr_in s_in; memset (&s_in, 0, sizeof (s_in)); #if HAVE_SOCKADDR_IN_SIN_LEN s_in.sin_len = sizeof (struct sockaddr_in); #endif s_in.sin_family = AF_INET; s_in.sin_port = htons (port); sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0); if (NULL != sock) { if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in, sizeof (s_in))) { /* failed to bind => service must be running */ GNUNET_free (hostname); (void) GNUNET_NETWORK_socket_close (sock); service_test_report (th, GNUNET_YES); return th; } (void) GNUNET_NETWORK_socket_close (sock); } } if (0 == strcmp ("ip6-localhost", hostname) #if !LINUX && 0 #endif ) { /* can test using 'bind' */ struct sockaddr_in6 s_in6; memset (&s_in6, 0, sizeof (s_in6)); #if HAVE_SOCKADDR_IN_SIN_LEN s_in6.sin6_len = sizeof (struct sockaddr_in6); #endif s_in6.sin6_family = AF_INET6; s_in6.sin6_port = htons (port); sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0); if (NULL != sock) { if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in6, sizeof (s_in6))) { /* failed to bind => service must be running */ GNUNET_free (hostname); (void) GNUNET_NETWORK_socket_close (sock); service_test_report (th, GNUNET_YES); return th; } (void) GNUNET_NETWORK_socket_close (sock); } } if (((0 == strcmp ("localhost", hostname)) || (0 == strcmp ("ip6-localhost", hostname))) #if !LINUX && 0 #endif ) { /* all binds succeeded => claim service not running right now */ GNUNET_free_non_null (hostname); service_test_report (th, GNUNET_NO); return th; } GNUNET_free_non_null (hostname); /* non-localhost, try 'connect' method */ th->client = GNUNET_CLIENT_connect (service, cfg); if (NULL == th->client) { LOG (GNUNET_ERROR_TYPE_INFO, _("Could not connect to service `%s', configuration broken.\n"), service); service_test_report (th, GNUNET_SYSERR); return th; } th->th = GNUNET_CLIENT_notify_transmit_ready (th->client, sizeof (struct GNUNET_MessageHeader), timeout, GNUNET_YES, &write_test, th); if (NULL == th->th) { LOG (GNUNET_ERROR_TYPE_WARNING, _("Failure to transmit request to service `%s'\n"), service); service_test_report (th, GNUNET_SYSERR); return th; } return th; }
/** * Load and initialize all plugins. The respective functions will be * invoked by the plugins when the respective events happen. The * closure will be set to a 'const char*' containing the name of the * plugin that caused the call. * * @param recv_cb function to call when data is received * @param address_cb function to call when our public addresses changed * @param session_start_cb function to call when a session was created * @param session_end_cb function to call when a session was terminated * @param address_type_cb function to call when a address type is requested */ void GST_plugins_load (GNUNET_TRANSPORT_PluginReceiveCallback recv_cb, GNUNET_TRANSPORT_AddressNotification address_cb, GNUNET_TRANSPORT_SessionStart session_start_cb, GNUNET_TRANSPORT_SessionEnd session_end_cb) { struct TransportPlugin *plug; struct TransportPlugin *next; unsigned long long tneigh; char *libname; char *plugs; char *pos; int fail; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (GST_cfg, "TRANSPORT", "NEIGHBOUR_LIMIT", &tneigh)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Transport service is lacking NEIGHBOUR_LIMIT option.\n")); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (GST_cfg, "TRANSPORT", "PLUGINS", &plugs)) return; GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting transport plugins `%s'\n"), plugs); for (pos = strtok (plugs, " "); pos != NULL; pos = strtok (NULL, " ")) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' transport plugin\n"), pos); GNUNET_asprintf (&libname, "libgnunet_plugin_transport_%s", pos); plug = GNUNET_new (struct TransportPlugin); plug->short_name = GNUNET_strdup (pos); plug->lib_name = libname; plug->env.cfg = GST_cfg; plug->env.my_identity = &GST_my_identity; plug->env.get_our_hello = &GST_hello_get; plug->env.cls = plug->short_name; plug->env.receive = recv_cb; plug->env.notify_address = address_cb; plug->env.session_start = session_start_cb; plug->env.session_end = session_end_cb; plug->env.get_address_type = &plugin_env_address_to_type; plug->env.update_address_distance = &plugin_env_update_distance; plug->env.max_connections = tneigh; plug->env.stats = GST_stats; GNUNET_CONTAINER_DLL_insert (plugins_head, plugins_tail, plug); } GNUNET_free (plugs); next = plugins_head; while (NULL != next) { plug = next; next = plug->next; plug->api = GNUNET_PLUGIN_load (plug->lib_name, &plug->env); if (NULL == plug->api) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to load transport plugin for `%s'\n"), plug->lib_name); GNUNET_CONTAINER_DLL_remove (plugins_head, plugins_tail, plug); GNUNET_free (plug->short_name); GNUNET_free (plug->lib_name); GNUNET_free (plug); continue; } fail = GNUNET_NO; if (NULL == plug->api->address_pretty_printer) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "address_pretty_printer", plug->lib_name); } if (NULL == plug->api->address_to_string) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "address_to_string", plug->lib_name); } if (NULL == plug->api->string_to_address) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "string_to_address", plug->lib_name); } if (NULL == plug->api->check_address) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "check_address", plug->lib_name); } if (NULL == plug->api->get_session) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "get_session", plug->lib_name); } if (NULL == plug->api->get_network) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "get_network", plug->lib_name); } if (NULL == plug->api->send) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "send", plug->lib_name); } if (NULL == plug->api->disconnect_peer) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "disconnect_peer", plug->lib_name); } if (NULL == plug->api->disconnect_session) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "disconnect_session", plug->lib_name); } if (NULL == plug->api->query_keepalive_factor) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "query_keepalive_factor", plug->lib_name); } if (NULL == plug->api->update_session_timeout) { fail = GNUNET_YES; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Missing function `%s' in transport plugin for `%s'\n"), "update_session_timeout", plug->lib_name); } if (GNUNET_YES == fail) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Did not load plugin `%s' due to missing functions\n"), plug->lib_name); GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api)); GNUNET_CONTAINER_DLL_remove (plugins_head, plugins_tail, plug); GNUNET_free (plug->short_name); GNUNET_free (plug->lib_name); GNUNET_free (plug); } } }
static int testConfig () { char *c; unsigned long long l; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "test", "b", &c)) return 1; if (0 != strcmp ("b", c)) { FPRINTF (stderr, "Got `%s'\n", c); GNUNET_free (c); return 2; } GNUNET_free (c); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "test", "five", &l)) { GNUNET_break (0); return 3; } if (5 != l) { GNUNET_break (0); return 4; } GNUNET_CONFIGURATION_set_value_string (cfg, "more", "c", "YES"); if (GNUNET_NO == GNUNET_CONFIGURATION_get_value_yesno (cfg, "more", "c")) { GNUNET_break (0); return 5; } GNUNET_CONFIGURATION_set_value_number (cfg, "NUMBERS", "TEN", 10); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "NUMBERS", "TEN", &c)) { GNUNET_break (0); return 6; } if (0 != strcmp (c, "10")) { GNUNET_free (c); GNUNET_break (0); return 7; } GNUNET_free (c); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "last", "test", &c)) { GNUNET_break (0); return 8; } #ifndef MINGW if (0 != strcmp (c, "/hello/world")) #else #define HI "\\hello\\world" if (strstr (c, HI) != c + strlen (c) - strlen (HI)) #endif { GNUNET_break (0); GNUNET_free (c); return 9; } GNUNET_free (c); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_size (cfg, "last", "size", &l)) { GNUNET_break (0); return 10; } if (l != 512 * 1024) { GNUNET_break (0); return 11; } return 0; }
/** * Main function that will be run. * * @param cls closure * @param args remaining command-line arguments * @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param c configuration */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { char *dbfile; struct WhiteListRow *wl_head; struct WhiteListRow *wl_entry; struct GNUNET_PeerIdentity identity; struct GNUNET_ATS_Properties prop; struct GNUNET_TIME_Relative delay; unsigned long long pid; unsigned int nrows; int ret; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c, "TESTBED", "PEERID", &pid)) { GNUNET_break (0); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c, "TESTBED-UNDERLAY", "DBFILE", &dbfile)) { GNUNET_break (0); return; } if (SQLITE_OK != (ret = sqlite3_open_v2 (dbfile, &db, SQLITE_OPEN_READONLY, NULL))) { if (NULL != db) { LOG_SQLITE (db, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite_open_v2"); GNUNET_break (SQLITE_OK == sqlite3_close (db)); } else LOG (GNUNET_ERROR_TYPE_ERROR, "Cannot open sqlite file %s\n", dbfile); GNUNET_free (dbfile); return; } DEBUG ("Opened database %s\n", dbfile); GNUNET_free (dbfile); dbfile = NULL; wl_head = NULL; if (GNUNET_OK != load_keys (c)) goto close_db; transport = GNUNET_TRANSPORT_connect (c, NULL, NULL, NULL, NULL, NULL); if (NULL == transport) { GNUNET_break (0); return; } /* read and process whitelist */ nrows = 0; wl_head = NULL; nrows = db_read_whitelist (db, pid, &wl_head); if ((GNUNET_SYSERR == nrows) || (0 == nrows)) { GNUNET_TRANSPORT_disconnect (transport); goto close_db; } map = GNUNET_CONTAINER_multipeermap_create (nrows, GNUNET_NO); while (NULL != (wl_entry = wl_head)) { wl_head = wl_entry->next; delay.rel_value_us = wl_entry->latency; memset (&prop, 0, sizeof (prop)); GNUNET_assert (GNUNET_OK == get_identity (wl_entry->id, &identity)); GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (map, &identity, &identity, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); DEBUG ("Setting %u ms latency to peer `%s'\n", wl_entry->latency, GNUNET_i2s (&identity)); GNUNET_TRANSPORT_set_traffic_metric (transport, &identity, &prop, delay, delay); GNUNET_free (wl_entry); } bh = GNUNET_TRANSPORT_blacklist (c, &check_access, NULL); shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_shutdown, NULL); close_db: GNUNET_break (SQLITE_OK == sqlite3_close (db)); return; }
/** * Load and initialize all plugins. The respective functions will be * invoked by the plugins when the respective events happen. The * closure will be set to a 'const char*' containing the name of the * plugin that caused the call. * * @param recv_cb function to call when data is received * @param address_cb function to call when our public addresses changed * @param session_end_cb function to call when a session was terminated * @param address_type_cb function to call when a address type is requested */ void GST_plugins_load (GNUNET_TRANSPORT_PluginReceiveCallback recv_cb, GNUNET_TRANSPORT_AddressNotification address_cb, GNUNET_TRANSPORT_SessionEnd session_end_cb, GNUNET_TRANSPORT_AddressToType address_type_cb) { struct TransportPlugin *plug; struct TransportPlugin *next; unsigned long long tneigh; char *libname; char *plugs; char *pos; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (GST_cfg, "TRANSPORT", "NEIGHBOUR_LIMIT", &tneigh)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Transport service is lacking NEIGHBOUR_LIMIT option.\n")); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (GST_cfg, "TRANSPORT", "PLUGINS", &plugs)) return; GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Starting transport plugins `%s'\n"), plugs); for (pos = strtok (plugs, " "); pos != NULL; pos = strtok (NULL, " ")) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' transport plugin\n"), pos); GNUNET_asprintf (&libname, "libgnunet_plugin_transport_%s", pos); plug = GNUNET_malloc (sizeof (struct TransportPlugin)); plug->short_name = GNUNET_strdup (pos); plug->lib_name = libname; plug->env.cfg = GST_cfg; plug->env.my_identity = &GST_my_identity; plug->env.get_our_hello = &GST_hello_get; plug->env.cls = plug->short_name; plug->env.receive = recv_cb; plug->env.notify_address = address_cb; plug->env.session_end = session_end_cb; plug->env.get_address_type = address_type_cb; plug->env.max_connections = tneigh; plug->env.stats = GST_stats; GNUNET_CONTAINER_DLL_insert (plugins_head, plugins_tail, plug); } GNUNET_free (plugs); next = plugins_head; while (next != NULL) { plug = next; next = plug->next; plug->api = GNUNET_PLUGIN_load (plug->lib_name, &plug->env); if (plug->api == NULL) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to load transport plugin for `%s'\n"), plug->lib_name); GNUNET_CONTAINER_DLL_remove (plugins_head, plugins_tail, plug); GNUNET_free (plug->short_name); GNUNET_free (plug->lib_name); GNUNET_free (plug); } } }
/** * 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); }
/** * Signature of the event handler function called by the * respective event controller. * * @param cls closure * @param event information about the event */ static void event_cb (void *cls, const struct GNUNET_TESTBED_EventInformation *event) { struct GNUNET_TESTBED_RunHandle *rc = cls; struct RunContextOperation *rcop; if (RC_INIT == rc->state) { switch (event->type) { case GNUNET_TESTBED_ET_OPERATION_FINISHED: rcop = event->op_cls; if (NULL != event->details.operation_finished.emsg) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Linking controllers failed. Exiting")); GNUNET_SCHEDULER_shutdown (); } else rc->reg_hosts++; GNUNET_assert (event->op == rcop->op); remove_rcop (rc, rcop); GNUNET_TESTBED_operation_done (rcop->op); GNUNET_free (rcop); if (rc->reg_hosts == rc->num_hosts) { rc->state = RC_LINKED; create_peers (rc); } return; default: GNUNET_break (0); GNUNET_SCHEDULER_shutdown (); return; } } if (GNUNET_TESTBED_ET_OPERATION_FINISHED != event->type) goto call_cc; if (NULL == (rcop = search_rcop (rc, event->op))) goto call_cc; remove_rcop (rc, rcop); GNUNET_TESTBED_operation_done (rcop->op); GNUNET_free (rcop); if ( (GNUNET_NO == rc->shutdown) && (NULL != event->details.operation_finished.emsg) ) { LOG (GNUNET_ERROR_TYPE_ERROR, "A operation has failed with error: %s\n", event->details.operation_finished.emsg); GNUNET_SCHEDULER_shutdown (); return; } GNUNET_assert (GNUNET_YES == rc->shutdown); switch (rc->state) { case RC_LINKED: case RC_PEERS_CREATED: case RC_READY: rc->state = RC_PEERS_SHUTDOWN; GNUNET_free_non_null (rc->peers); rc->peers = NULL; DEBUG ("Peers shut down in %s\n", prof_time (rc)); GNUNET_SCHEDULER_shutdown (); break; default: GNUNET_assert (0); } return; call_cc: if ((0 != (rc->event_mask & (1LL << event->type))) && (NULL != rc->cc)) rc->cc (rc->cc_cls, event); if (GNUNET_TESTBED_ET_PEER_START != event->type) return; if (NULL == (rcop = search_rcop (rc, event->op))) /* Not our operation */ return; remove_rcop (rc, rcop); GNUNET_TESTBED_operation_done (rcop->op); GNUNET_free (rcop); rc->peer_count++; if (rc->peer_count < rc->num_peers) return; DEBUG ("%u peers started in %s\n", rc->num_peers, prof_time (rc)); if (GNUNET_TESTBED_TOPOLOGY_NONE != rc->topology) { switch (rc->topology) { case GNUNET_TESTBED_TOPOLOGY_NONE: GNUNET_assert (0); case GNUNET_TESTBED_TOPOLOGY_ERDOS_RENYI: case GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD_RING: case GNUNET_TESTBED_TOPOLOGY_SMALL_WORLD: rc->topology_operation = GNUNET_TESTBED_overlay_configure_topology (NULL, rc->num_peers, rc->peers, &rc->num_oc, &topology_completion_callback, rc, rc->topology, rc->random_links, GNUNET_TESTBED_TOPOLOGY_OPTION_END); break; case GNUNET_TESTBED_TOPOLOGY_FROM_FILE: GNUNET_assert (NULL != rc->topo_file); rc->topology_operation = GNUNET_TESTBED_overlay_configure_topology (NULL, rc->num_peers, rc->peers, &rc->num_oc, &topology_completion_callback, rc, rc->topology, rc->topo_file, GNUNET_TESTBED_TOPOLOGY_OPTION_END); break; case GNUNET_TESTBED_TOPOLOGY_SCALE_FREE: { unsigned long long number; unsigned int cap; GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (rc->cfg, TESTBED_CONFIG_SECTION, SCALE_FREE_CAP, &number)); cap = (unsigned int) number; GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (rc->cfg, TESTBED_CONFIG_SECTION, SCALE_FREE_M, &number)); rc->topology_operation = GNUNET_TESTBED_overlay_configure_topology (NULL, rc->num_peers, rc->peers, &rc->num_oc, &topology_completion_callback, rc, rc->topology, cap, /* uint16_t */ (unsigned int) number, /* uint8_t */ GNUNET_TESTBED_TOPOLOGY_OPTION_END); } break; default: rc->topology_operation = GNUNET_TESTBED_overlay_configure_topology (NULL, rc->num_peers, rc->peers, &rc->num_oc, &topology_completion_callback, rc, rc->topology, GNUNET_TESTBED_TOPOLOGY_OPTION_END); } if (NULL == rc->topology_operation) LOG (GNUNET_ERROR_TYPE_WARNING, "Not generating a topology. Check number of peers\n"); else { DEBUG ("Creating overlay topology\n"); rc->pstart_time = GNUNET_TIME_absolute_get (); return; } } rc->state = RC_READY; call_master (rc); }
/** * Handle network size estimate clients. * * @param cls closure * @param c configuration to use * @param service the initialized service */ static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service) { struct GNUNET_MQ_MessageHandler core_handlers[] = { GNUNET_MQ_hd_fixed_size (p2p_estimate, GNUNET_MESSAGE_TYPE_NSE_P2P_FLOOD, struct GNUNET_NSE_FloodMessage, NULL), GNUNET_MQ_handler_end () }; char *proof; struct GNUNET_CRYPTO_EddsaPrivateKey *pk; cfg = c; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "INTERVAL", &gnunet_nse_interval)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "INTERVAL"); GNUNET_SCHEDULER_shutdown (); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, "NSE", "WORKDELAY", &proof_find_delay)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKDELAY"); GNUNET_SCHEDULER_shutdown (); return; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS", &nse_work_required)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS"); GNUNET_SCHEDULER_shutdown (); return; } if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS", _("Value is too large.\n")); GNUNET_SCHEDULER_shutdown (); return; } #if ENABLE_NSE_HISTOGRAM { char *histogram_dir; char *histogram_fn; if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "HISTOGRAM_DIR", &histogram_dir)) { GNUNET_assert (0 < GNUNET_asprintf (&histogram_fn, "%s/timestamps", histogram_dir)); GNUNET_free (histogram_dir); histogram = GNUNET_BIO_write_open (histogram_fn); if (NULL == histogram) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Unable to open histogram file `%s'\n", histogram_fn); GNUNET_free (histogram_fn); } logger_test = GNUNET_CLIENT_service_test ("testbed-logger", cfg, GNUNET_TIME_UNIT_SECONDS, &status_cb, NULL); } #endif GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); pk = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg); GNUNET_assert (NULL != pk); my_private_key = pk; GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_identity.public_key); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE", "PROOFFILE", &proof)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "PROOFFILE"); GNUNET_free (my_private_key); my_private_key = NULL; GNUNET_SCHEDULER_shutdown (); return; } if ((GNUNET_YES != GNUNET_DISK_file_test (proof)) || (sizeof (my_proof) != GNUNET_DISK_fn_read (proof, &my_proof, sizeof (my_proof)))) my_proof = 0; GNUNET_free (proof); proof_task = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, &find_proof, NULL); peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES); nc = GNUNET_notification_context_create (1); /* Connect to core service and register core handlers */ core_api = GNUNET_CORE_connect (cfg, /* Main configuration */ NULL, /* Closure passed to functions */ &core_init, /* Call core_init once connected */ &handle_core_connect, /* Handle connects */ &handle_core_disconnect, /* Handle disconnects */ core_handlers); /* Register these handlers */ if (NULL == core_api) { GNUNET_SCHEDULER_shutdown (); return; } stats = GNUNET_STATISTICS_create ("nse", cfg); }