/** * @brief Initialise storage of peers * * @param fn_valid_peers filename of the file used to store valid peer ids * @param cadet_h cadet handle * @param own_id own peer identity */ void Peers_initialise (char* fn_valid_peers, struct GNUNET_CADET_Handle *cadet_h, const struct GNUNET_PeerIdentity *own_id) { filename_valid_peers = GNUNET_strdup (fn_valid_peers); cadet_handle = cadet_h; own_identity = own_id; peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); restore_valid_peers (); }
/** * Change length of view * * If size is decreased, peers with higher indices are removed. * * @param len the (maximum) length for the view */ void View_change_len (uint32_t len) { uint32_t i; uint32_t *index; if (GNUNET_CONTAINER_multipeermap_size (mpm) < len) { /* Simply shrink */ /* We might simply clear and free the left over space */ GNUNET_array_grow (array, length, len); } else /* We have to remove elements */ { /* TODO find a way to preserve indices */ for (i = 0; i < len; i++) { index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]); GNUNET_assert (NULL != index); GNUNET_free (index); } GNUNET_array_grow (array, length, len); GNUNET_CONTAINER_multipeermap_destroy (mpm); mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); for (i = 0; i < len; i++) { index = GNUNET_new (uint32_t); *index = i; GNUNET_CONTAINER_multipeermap_put (mpm, &array[i], index, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); } } GNUNET_assert (length == len); }
/** * Intern an peer identity. If the identity is already known, its * reference counter will be increased by one. * * @param pid identity to intern * @return the interned identity. */ GNUNET_PEER_Id GNUNET_PEER_intern (const struct GNUNET_PeerIdentity *pid) { GNUNET_PEER_Id ret; struct PeerEntry *e; unsigned int i; if (NULL == pid) return 0; if (NULL == map) map = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES); e = GNUNET_CONTAINER_multipeermap_get (map, pid); if (NULL != e) { GNUNET_assert (e->rc > 0); e->rc++; return e->pid; } ret = free_list_start; if (ret == size) { GNUNET_array_grow (table, size, size + 16); for (i = ret; i < size; i++) { table[i] = GNUNET_new (struct PeerEntry); table[i]->pid = i + 1; } }
/** * Do pre-calculation for ECC discrete logarithm for small factors. * * @param max maximum value the factor can be * @param mem memory to use (should be smaller than @a max), must not be zero. * @return @a max if dlog failed, otherwise the factor */ struct GNUNET_CRYPTO_EccDlogContext * GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, unsigned int mem) { struct GNUNET_CRYPTO_EccDlogContext *edc; unsigned int K = ((max + (mem-1)) / mem); gcry_mpi_point_t g; struct GNUNET_PeerIdentity key; gcry_mpi_point_t gKi; gcry_mpi_t fact; gcry_mpi_t n; unsigned int i; GNUNET_assert (max < INT32_MAX); edc = GNUNET_new (struct GNUNET_CRYPTO_EccDlogContext); edc->max = max; edc->mem = mem; edc->map = GNUNET_CONTAINER_multipeermap_create (mem * 2, GNUNET_NO); GNUNET_assert (0 == gcry_mpi_ec_new (&edc->ctx, NULL, CURVE)); g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); GNUNET_assert (NULL != g); fact = gcry_mpi_new (0); gKi = gcry_mpi_point_new (0); for (i=0;i<=mem;i++) { gcry_mpi_set_ui (fact, i * K); gcry_mpi_ec_mul (gKi, fact, g, edc->ctx); extract_pk (gKi, edc->ctx, &key); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (edc->map, &key, (void*) (long) i + max, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); } /* negative values */ n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); for (i=1;i<mem;i++) { gcry_mpi_set_ui (fact, i * K); gcry_mpi_sub (fact, n, fact); gcry_mpi_ec_mul (gKi, fact, g, edc->ctx); extract_pk (gKi, edc->ctx, &key); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (edc->map, &key, (void*) (long) max - i, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); } gcry_mpi_release (fact); gcry_mpi_release (n); gcry_mpi_point_release (gKi); gcry_mpi_point_release (g); return edc; }
/** * Create an empty view. * * @param len the maximum length for the view */ void View_create (uint32_t len) { length = len; array = GNUNET_new_array (len, struct GNUNET_PeerIdentity); mpm = GNUNET_CONTAINER_multipeermap_create (len, GNUNET_NO); /* might even be * set to _YES */ }
/** * Start the nodes management */ void GED_nodes_start () { /* Connecting to core service to find partners */ ch = GNUNET_CORE_connect (GED_cfg, NULL, &core_startup_handler, &core_connect_handler, &core_disconnect_handler, &core_receive_handler, GNUNET_NO, NULL, GNUNET_NO, NULL); if (NULL == ch) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Failed to connect to CORE service!\n")); return; } nodes_requested = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); nodes_active = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); nodes_inactive = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO); }
/** * Initialize neighbours subsystem. */ int GSC_NEIGHBOURS_init () { neighbours = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES); transport = GNUNET_TRANSPORT_connect2 (GSC_cfg, &GSC_my_identity, NULL, &handle_transport_receive, &handle_transport_notify_connect, &handle_transport_notify_disconnect, &handle_transport_notify_excess_bw); if (NULL == transport) { GNUNET_CONTAINER_multipeermap_destroy (neighbours); neighbours = NULL; return GNUNET_SYSERR; } return GNUNET_OK; }
/** * Connect to the DV service. * * @param cfg configuration * @param cls closure for callbacks * @param connect_cb function to call on connects * @param distance_cb function to call if distances change * @param disconnect_cb function to call on disconnects * @param message_cb function to call if we receive messages * @return handle to access the service */ struct GNUNET_DV_ServiceHandle * GNUNET_DV_service_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_DV_ConnectCallback connect_cb, GNUNET_DV_DistanceChangedCallback distance_cb, GNUNET_DV_DisconnectCallback disconnect_cb, GNUNET_DV_MessageReceivedCallback message_cb) { struct GNUNET_DV_ServiceHandle *sh; sh = GNUNET_new (struct GNUNET_DV_ServiceHandle); sh->cfg = cfg; sh->cls = cls; sh->connect_cb = connect_cb; sh->distance_cb = distance_cb; sh->disconnect_cb = disconnect_cb; sh->message_cb = message_cb; sh->peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES); reconnect (sh); return sh; }
/** * Connect to the core service. Note that the connection may * complete (or fail) asynchronously. * * @param cfg configuration to use * @param cls closure for the various callbacks that follow (including handlers in the handlers array) * @param init callback to call once we have successfully * connected to the core service * @param connects function to call on peer connect, can be NULL * @param disconnects function to call on peer disconnect / timeout, can be NULL * @param inbound_notify function to call for all inbound messages, can be NULL * @param inbound_hdr_only set to #GNUNET_YES if inbound_notify will only read the * GNUNET_MessageHeader and hence we do not need to give it the full message; * can be used to improve efficiency, ignored if @a inbound_notify is NULLL * @param outbound_notify function to call for all outbound messages, can be NULL * @param outbound_hdr_only set to #GNUNET_YES if outbound_notify will only read the * GNUNET_MessageHeader and hence we do not need to give it the full message * can be used to improve efficiency, ignored if @a outbound_notify is NULLL * @param handlers callbacks for messages we care about, NULL-terminated * @return handle to the core service (only useful for disconnect until 'init' is called); * NULL on error (in this case, init is never called) */ struct GNUNET_CORE_Handle * GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls, GNUNET_CORE_StartupCallback init, GNUNET_CORE_ConnectEventHandler connects, GNUNET_CORE_DisconnectEventHandler disconnects, GNUNET_CORE_MessageCallback inbound_notify, int inbound_hdr_only, GNUNET_CORE_MessageCallback outbound_notify, int outbound_hdr_only, const struct GNUNET_CORE_MessageHandler *handlers) { struct GNUNET_CORE_Handle *h; GNUNET_assert (NULL != cfg); h = GNUNET_new (struct GNUNET_CORE_Handle); h->cfg = cfg; h->cls = cls; h->init = init; h->connects = connects; h->disconnects = disconnects; h->inbound_notify = inbound_notify; h->outbound_notify = outbound_notify; h->inbound_hdr_only = inbound_hdr_only; h->outbound_hdr_only = outbound_hdr_only; h->handlers = handlers; h->hcnt = 0; h->currently_down = GNUNET_YES; h->peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO); if (NULL != handlers) while (handlers[h->hcnt].callback != NULL) h->hcnt++; GNUNET_assert (h->hcnt < (GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct InitMessage)) / sizeof (uint16_t)); LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CORE service\n"); reconnect (h); return h; }
/** * Update the absolute preference and calculate the * new relative preference value. * * @param client the client with this preference * @param peer the peer to change the preference for * @param kind the kind to change the preference * @param score_abs the normalized score */ static void update_preference (struct GNUNET_SERVICE_Client *client, const struct GNUNET_PeerIdentity *peer, enum GNUNET_ATS_PreferenceKind kind, float score_abs) { struct PreferenceClient *c_cur; struct PreferencePeer *p_cur; struct PeerRelative *r_cur; unsigned int i; if (kind >= GNUNET_ATS_PREFERENCE_END) { GNUNET_break(0); return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Client changes preference for peer `%s' for `%s' to %.2f\n", GNUNET_i2s (peer), GNUNET_ATS_print_preference_type (kind), score_abs); /* Find preference client */ for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next) if (client == c_cur->client) break; /* Not found: create new preference client */ if (NULL == c_cur) { c_cur = GNUNET_new (struct PreferenceClient); c_cur->client = client; c_cur->peer2pref = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_NO); for (i = 0; i < GNUNET_ATS_PREFERENCE_END; i++) c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE; GNUNET_CONTAINER_DLL_insert (pc_head, pc_tail, c_cur); }
/** * 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; }
/** * Shutdown connectivity subsystem. */ void GAS_connectivity_init () { connection_requests = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_NO); }
/** * Initialize sessions subsystem. */ void GSC_SESSIONS_init () { sessions = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES); }
/** * Initialize routing subsystem. */ void GDS_ROUTING_init () { routing_table = GNUNET_CONTAINER_multipeermap_create (DHT_MAX_RECENT * 4 / 3, GNUNET_NO); }
/** * Setup CADET internals. * * @param cls closure * @param server the initialized server * @param c configuration to use */ static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (c, "CADET", "RATCHET_MESSAGES", &ratchet_messages)) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, "CADET", "RATCHET_MESSAGES", "needs to be a number"); ratchet_messages = 64; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (c, "CADET", "RATCHET_TIME", &ratchet_time)) { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, "CADET", "RATCHET_TIME", "need delay value"); ratchet_time = GNUNET_TIME_UNIT_HOURS; } my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c); if (NULL == my_private_key) { GNUNET_break (0); GNUNET_SCHEDULER_shutdown (); return; } GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, &my_full_id.public_key); stats = GNUNET_STATISTICS_create ("cadet", c); GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); ats_ch = GNUNET_ATS_connectivity_init (c); /* FIXME: optimize code to allow GNUNET_YES here! */ open_ports = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO); loose_channels = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO); peers = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES); connections = GNUNET_CONTAINER_multishortmap_create (256, GNUNET_YES); GCH_init (c); GCD_init (c); GCO_init (c); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "CADET starting at peer %s\n", GNUNET_i2s (&my_full_id)); }
/** * Start server offering our hostlist. * * @param c configuration to use * @param st statistics handle to use * @param co core handle to use * @param[out] server_ch set to handler for CORE connect events * @param[out] server_dh set to handler for CORE disconnect events * @param advertise #GNUNET_YES if we should advertise our hostlist * @return #GNUNET_OK on success */ int GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_STATISTICS_Handle *st, struct GNUNET_CORE_Handle *co, GNUNET_CORE_ConnectEventHandler *server_ch, GNUNET_CORE_DisconnectEventHandler *server_dh, int advertise) { unsigned long long port; char *hostname; char *ipv4; char *ipv6; size_t size; struct in_addr i4; struct in6_addr i6; struct sockaddr_in v4; struct sockaddr_in6 v6; const struct sockaddr *sa4; const struct sockaddr *sa6; advertising = advertise; if (! advertising) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Advertising not enabled on this hostlist server\n"); } else { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Advertising enabled on this hostlist server\n"); advertisements = GNUNET_CONTAINER_multipeermap_create (8, GNUNET_NO); } cfg = c; stats = st; peerinfo = GNUNET_PEERINFO_connect (cfg); if (NULL == peerinfo) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not access PEERINFO service. Exiting.\n")); return GNUNET_SYSERR; } if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "HOSTLIST", "HTTPPORT", &port)) return GNUNET_SYSERR; if ((0 == port) || (port > UINT16_MAX)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Invalid port number %llu. Exiting.\n"), port); return GNUNET_SYSERR; } if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "EXTERNAL_DNS_NAME", &hostname)) hostname = GNUNET_RESOLVER_local_fqdn_get (); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Hostlist service starts on %s:%llu\n"), hostname, port); if (NULL != hostname) { size = strlen (hostname); if (size + 15 > MAX_URL_LEN) { GNUNET_break (0); } else { GNUNET_asprintf (&hostlist_uri, "http://%s:%u/", hostname, (unsigned int) port); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Address to obtain hostlist: `%s'\n"), hostlist_uri); } GNUNET_free (hostname); } if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV4")) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "BINDTOIP", &ipv4)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV4.\n")); } } else ipv4 = NULL; if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV6")) { if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "BINDTOIP", &ipv6)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV6.\n")); } } else ipv6 = NULL; sa4 = NULL; if (NULL != ipv4) { if (1 == inet_pton (AF_INET, ipv4, &i4)) { memset (&v4, 0, sizeof (v4)); v4.sin_family = AF_INET; v4.sin_addr = i4; v4.sin_port = htons (port); #if HAVE_SOCKADDR_IN_SIN_LEN v4.sin_len = sizeof (v4); #endif sa4 = (const struct sockaddr *) &v4; } else GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("`%s' is not a valid IPv4 address! Ignoring BINDTOIPV4.\n"), ipv4); GNUNET_free (ipv4); } sa6 = NULL; if (NULL != ipv6) { if (1 == inet_pton (AF_INET6, ipv6, &i6)) { memset (&v6, 0, sizeof (v6)); v6.sin6_family = AF_INET6; v6.sin6_addr = i6; v6.sin6_port = htons (port); #if HAVE_SOCKADDR_IN_SIN_LEN v6.sin6_len = sizeof (v6); #endif sa6 = (const struct sockaddr *) &v6; } else GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("`%s' is not a valid IPv6 address! Ignoring BINDTOIPV6.\n"), ipv6); GNUNET_free (ipv6); } daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 | MHD_USE_DEBUG, (uint16_t) port, &accept_policy_callback, NULL, &access_handler_callback, NULL, MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 128, MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 32, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (16 * 1024), MHD_OPTION_SOCK_ADDR, sa6, MHD_OPTION_END); daemon_handle_v4 = MHD_start_daemon (MHD_NO_FLAG | MHD_USE_DEBUG, (uint16_t) port, &accept_policy_callback, NULL, &access_handler_callback, NULL, MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 128, MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 32, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16, MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (16 * 1024), MHD_OPTION_SOCK_ADDR, sa4, MHD_OPTION_END); if ( (NULL == daemon_handle_v6) && (NULL == daemon_handle_v4) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not start hostlist HTTP server on port %u\n"), (unsigned short) port); return GNUNET_SYSERR; } core = co; *server_ch = &connect_handler; *server_dh = &disconnect_handler; if (NULL != daemon_handle_v4) hostlist_task_v4 = prepare_daemon (daemon_handle_v4); if (NULL != daemon_handle_v6) hostlist_task_v6 = prepare_daemon (daemon_handle_v6); notify = GNUNET_PEERINFO_notify (cfg, GNUNET_NO, &process_notify, NULL); return GNUNET_OK; }
/** * 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); }
/** * Initialize ATS subsystem. */ void GST_ats_init () { p2a = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_YES); }
/** * Handle #GNUNET_MESSAGE_TYPE_CORE_INIT request. * * @param cls unused * @param client new client that sent #GNUNET_MESSAGE_TYPE_CORE_INIT * @param message the `struct InitMessage` (presumably) */ static void handle_client_init (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct InitMessage *im; struct InitReplyMessage irm; struct GSC_Client *c; uint16_t msize; const uint16_t *types; uint16_t *wtypes; unsigned int i; /* check that we don't have an entry already */ c = find_client (client); if (NULL != c) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } msize = ntohs (message->size); if (msize < sizeof (struct InitMessage)) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } GNUNET_SERVER_notification_context_add (notifier, client); im = (const struct InitMessage *) message; types = (const uint16_t *) &im[1]; msize -= sizeof (struct InitMessage); c = GNUNET_malloc (sizeof (struct GSC_Client) + msize); c->client_handle = client; c->tcnt = msize / sizeof (uint16_t); c->options = ntohl (im->options); all_client_options |= c->options; c->types = (const uint16_t *) &c[1]; c->connectmap = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_NO); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multipeermap_put (c->connectmap, &GSC_my_identity, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); wtypes = (uint16_t *) & c[1]; for (i = 0; i < c->tcnt; i++) wtypes[i] = ntohs (types[i]); GSC_TYPEMAP_add (wtypes, c->tcnt); GNUNET_CONTAINER_DLL_insert (client_head, client_tail, c); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client connecting to core service is interested in %u message types\n", (unsigned int) c->tcnt); /* send init reply message */ irm.header.size = htons (sizeof (struct InitReplyMessage)); irm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY); irm.reserved = htonl (0); irm.my_identity = GSC_my_identity; send_to_client (c, &irm.header, GNUNET_NO); GSC_SESSIONS_notify_client_about_sessions (c); GNUNET_SERVER_receive_done (client, GNUNET_OK); }
/** * Handle #GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST message. * * @param cls unused * @param client new client that sent a #GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST * @param message the `struct SendMessageRequest` (presumably) */ static void handle_client_send_request (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { const struct SendMessageRequest *req; struct GSC_Client *c; struct GSC_ClientActiveRequest *car; int is_loopback; req = (const struct SendMessageRequest *) message; c = find_client (client); if (NULL == c) { /* client did not send INIT first! */ GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } if (NULL == c->requests) c->requests = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_NO); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client asked for transmission to `%s'\n", GNUNET_i2s (&req->peer)); is_loopback = (0 == memcmp (&req->peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))); if ((! is_loopback) && (GNUNET_YES != GNUNET_CONTAINER_multipeermap_contains (c->connectmap, &req->peer))) { /* neighbour must have disconnected since request was issued, * ignore (client will realize it once it processes the * disconnect notification) */ GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# send requests dropped (disconnected)"), 1, GNUNET_NO); GNUNET_SERVER_receive_done (client, GNUNET_OK); return; } car = GNUNET_CONTAINER_multipeermap_get (c->requests, &req->peer); if (NULL == car) { /* create new entry */ car = GNUNET_new (struct GSC_ClientActiveRequest); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (c->requests, &req->peer, car, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); car->client_handle = c; }
static int testMap (int i) { struct GNUNET_CONTAINER_MultiPeerMap *m; struct GNUNET_PeerIdentity k1; struct GNUNET_PeerIdentity k2; struct GNUNET_CONTAINER_MultiPeerMapIterator *iter; struct GNUNET_PeerIdentity key_ret; const char *ret; int j; CHECK (NULL != (m = GNUNET_CONTAINER_multipeermap_create (i, GNUNET_NO))); memset (&k1, 0, sizeof (k1)); memset (&k2, 1, sizeof (k2)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (m, &k1)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (m, &k2)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_remove (m, &k1, NULL)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_remove (m, &k2, NULL)); CHECK (NULL == GNUNET_CONTAINER_multipeermap_get (m, &k1)); CHECK (NULL == GNUNET_CONTAINER_multipeermap_get (m, &k2)); CHECK (0 == GNUNET_CONTAINER_multipeermap_remove_all (m, &k1)); CHECK (0 == GNUNET_CONTAINER_multipeermap_size (m)); CHECK (0 == GNUNET_CONTAINER_multipeermap_iterate (m, NULL, NULL)); CHECK (0 == GNUNET_CONTAINER_multipeermap_get_multiple (m, &k1, NULL, NULL)); CHECK (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (m, &k1, "v1", GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); CHECK (1 == GNUNET_CONTAINER_multipeermap_size (m)); ret = GNUNET_CONTAINER_multipeermap_get (m, &k1); GNUNET_assert (ret != NULL); CHECK (0 == strcmp ("v1", ret)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_put (m, &k1, "v1", GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); CHECK (1 == GNUNET_CONTAINER_multipeermap_size (m)); CHECK (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (m, &k1, "v2", GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); CHECK (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (m, &k1, "v3", GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); CHECK (3 == GNUNET_CONTAINER_multipeermap_size (m)); CHECK (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (m, &k1, "v3")); CHECK (2 == GNUNET_CONTAINER_multipeermap_size (m)); CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (m, &k1)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (m, &k2)); CHECK (2 == GNUNET_CONTAINER_multipeermap_get_multiple (m, &k1, NULL, NULL)); CHECK (0 == GNUNET_CONTAINER_multipeermap_get_multiple (m, &k2, NULL, NULL)); CHECK (2 == GNUNET_CONTAINER_multipeermap_iterate (m, NULL, NULL)); iter = GNUNET_CONTAINER_multipeermap_iterator_create (m); CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter, &key_ret, (const void **)&ret)); CHECK (0 == memcmp (&key_ret, &k1, sizeof (key_ret))); CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter, &key_ret, (const void **)&ret)); CHECK (0 == memcmp (&key_ret, &k1, sizeof (key_ret))); CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL)); GNUNET_free (iter); CHECK (2 == GNUNET_CONTAINER_multipeermap_remove_all (m, &k1)); for (j = 0; j < 1024; j++) CHECK (GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (m, &k1, "v2", GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); iter = GNUNET_CONTAINER_multipeermap_iterator_create (m); for (j = 0; j < GNUNET_CONTAINER_multipeermap_size (m); j++) CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL)); GNUNET_free (iter); GNUNET_CONTAINER_multipeermap_destroy (m); 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) { struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size (hello, GNUNET_MESSAGE_TYPE_HELLO, struct GNUNET_HELLO_Message, NULL), GNUNET_MQ_handler_end () }; 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_multipeermap_create (target_connection_count * 2, GNUNET_NO); 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) && (NULL == blacklist)) blacklist = GNUNET_TRANSPORT_blacklist (cfg, &blacklist_check, NULL); ats = GNUNET_ATS_connectivity_init (cfg); handle = GNUNET_CORE_connect (cfg, NULL, &core_init, &connect_notify, &disconnect_notify, handlers); GNUNET_SCHEDULER_add_shutdown (&cleaning_task, NULL); if (NULL == handle) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to `%s' service.\n"), "core"); GNUNET_SCHEDULER_shutdown (); return; } }