static int check () { void *ret; GNUNET_log_skip (1, GNUNET_NO); ret = GNUNET_PLUGIN_load ("libgnunet_plugin_missing", NULL); GNUNET_log_skip (0, GNUNET_NO); if (ret != NULL) return 1; ret = GNUNET_PLUGIN_load ("libgnunet_plugin_test", "in"); if (ret == NULL) return 1; if (0 != strcmp (ret, "Hello")) return 2; ret = GNUNET_PLUGIN_unload ("libgnunet_plugin_test", "out"); if (ret == NULL) return 3; if (0 != strcmp (ret, "World")) return 4; free (ret); GNUNET_PLUGIN_load_all ("libgnunet_plugin_tes", "in", &test_cb, "test"); return 0; }
/** * 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 cfg configuration to use */ void GPI_plugins_load (const struct GNUNET_CONFIGURATION_Handle *cfg) { struct TransportPlugin *plug; struct TransportPlugin *next; char *libname; char *plugs; char *pos; if (NULL != plugins_head) return; /* already loaded */ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (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 = cfg; plug->env.cls = plug->short_name; 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); } } }
/** * Load the psycstore plugin. * * @param cfg configuration to pass * @return NULL on error */ static struct GNUNET_PSYCSTORE_PluginFunctions * load_plugin (const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_PSYCSTORE_PluginFunctions *ret; char *libname; GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Loading `%s' psycstore plugin\n"), plugin_name); GNUNET_asprintf (&libname, "libgnunet_plugin_psycstore_%s", plugin_name); if (NULL == (ret = GNUNET_PLUGIN_load (libname, (void*) cfg))) { FPRINTF (stderr, "Failed to load plugin `%s'!\n", plugin_name); return NULL; } GNUNET_free (libname); return ret; }
/** * Initialize plugins subsystem. * * @param cfg configuration to use * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load * solver plugin) */ int GAS_plugin_init (const struct GNUNET_CONFIGURATION_Handle *cfg) { char *mode_str; /* Figure out configured solution method */ if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", "MODE", &mode_str)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "No resource assignment method configured, using proportional approach\n"); mode_str = GNUNET_strdup ("proportional"); } env.cls = NULL; env.info_cb = &solver_info_cb; env.bandwidth_changed_cb = &bandwidth_changed_cb; env.get_preferences = &GAS_preference_get_by_peer; env.get_connectivity = &GAS_connectivity_has_peer; env.cfg = cfg; env.stats = GSA_stats; env.addresses = GSA_addresses; env.network_count = GNUNET_ATS_NetworkTypeCount; load_quotas (cfg, env.out_quota, env.in_quota, GNUNET_ATS_NetworkTypeCount); GNUNET_asprintf (&plugin, "libgnunet_plugin_ats_%s", mode_str); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initializing solver `%s'\n", mode_str); GNUNET_free (mode_str); if (NULL == (sf = GNUNET_PLUGIN_load (plugin, &env))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to initialize solver `%s'!\n"), plugin); return GNUNET_SYSERR; } return GNUNET_OK; }
/** * 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); } } }
/** * 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); } } }
/** * Create a data cache. * * @param cfg configuration to use * @param section section in the configuration that contains our options * @return handle to use to access the service */ struct GNUNET_DATACACHE_Handle * GNUNET_DATACACHE_create (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section) { unsigned int bf_size; unsigned long long quota; struct GNUNET_DATACACHE_Handle *ret; char *libname; char *name; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_size (cfg, section, "QUOTA", "a)) { LOG (GNUNET_ERROR_TYPE_ERROR, _("No `%s' specified for `%s' in configuration!\n"), "QUOTA", section); return NULL; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, section, "DATABASE", &name)) { LOG (GNUNET_ERROR_TYPE_ERROR, _("No `%s' specified for `%s' in configuration!\n"), "DATABASE", section); return NULL; } bf_size = quota / 32; /* 8 bit per entry, 1 bit per 32 kb in DB */ ret = GNUNET_malloc (sizeof (struct GNUNET_DATACACHE_Handle)); if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF")) { if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_yesno (cfg, section, "DISABLE_BF_RC")) { ret->bloom_name = GNUNET_DISK_mktemp ("gnunet-datacachebloom"); } if (NULL != ret->bloom_name) { ret->filter = GNUNET_CONTAINER_bloomfilter_load (ret->bloom_name, quota / 1024, /* 8 bit per entry in DB, expect 1k entries */ 5); } if (NULL == ret->filter) { ret->filter = GNUNET_CONTAINER_bloomfilter_init (NULL, bf_size, 5); /* approx. 3% false positives at max use */ } } ret->stats = GNUNET_STATISTICS_create ("datacache", cfg); ret->section = GNUNET_strdup (section); ret->env.cfg = cfg; ret->env.delete_notify = &env_delete_notify; ret->env.section = ret->section; ret->env.cls = ret; ret->env.delete_notify = &env_delete_notify; ret->env.quota = quota; LOG (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' datacache plugin\n"), name); GNUNET_asprintf (&libname, "libgnunet_plugin_datacache_%s", name); ret->short_name = name; ret->lib_name = libname; ret->api = GNUNET_PLUGIN_load (libname, &ret->env); if (ret->api == NULL) { LOG (GNUNET_ERROR_TYPE_ERROR, _("Failed to load datacache plugin for `%s'\n"), name); GNUNET_DATACACHE_destroy (ret); return NULL; } return ret; }