/** * Recalculate preference for a specific ATS property * * @param c the preference client * @param kind the preference kind * @return the result */ static void recalculate_relative_preferences (struct PreferenceClient *c, enum GNUNET_ATS_PreferenceKind kind) { struct UpdateContext uc; /* For this client: sum of absolute preference values for this preference */ uc.kind = kind; uc.pc = c; c->f_abs_sum[kind] = 0.0; /* For all peers: calculate sum of absolute preferences */ GNUNET_CONTAINER_multipeermap_iterate (c->peer2pref, &update_abs_sum, &uc); LOG (GNUNET_ERROR_TYPE_DEBUG, "Client has sum of total preferences for %s of %.3f\n", GNUNET_ATS_print_preference_type (kind), c->f_abs_sum[kind]); /* For all peers: calculate relative preference */ GNUNET_CONTAINER_multipeermap_iterate (c->peer2pref, &update_rel_sum, &uc); }
/** * Task run to terminate the testcase. * * @param cls NULL * @param tc unused */ static void end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { if (0 != ret) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test failed at stage %u %s\n", off, (NULL != test_commands[off].label) ? test_commands[off].label : ""); if (NULL != interpreter_task) { GNUNET_SCHEDULER_cancel (interpreter_task); interpreter_task = NULL; } if (NULL != sched_ats) { GNUNET_ATS_scheduling_done (sched_ats); sched_ats = NULL; } if (NULL != con_ats) { GNUNET_ATS_connectivity_done (con_ats); con_ats = NULL; } if (NULL != perf_ats) { GNUNET_ATS_performance_done (perf_ats); perf_ats = NULL; } if (NULL != p2asd) { GNUNET_CONTAINER_multipeermap_iterate (p2asd, &free_asd, NULL); GNUNET_CONTAINER_multipeermap_destroy (p2asd); p2asd = NULL; } if (NULL != p2aid) { GNUNET_CONTAINER_multipeermap_iterate (p2aid, &free_aid, NULL); GNUNET_CONTAINER_multipeermap_destroy (p2aid); p2aid = NULL; } }
/** * Update and normalize atsi performance information * * @param address the address to update */ void GAS_normalization_update_property (struct ATS_Address *address) { const struct GNUNET_ATS_Properties *prop = &address->properties; struct PropertyRange range; LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating properties for peer `%s'\n", GNUNET_i2s (&address->peer)); GAS_plugin_solver_lock (); update_avg (prop->delay.rel_value_us, &address->norm_delay); update_avg (prop->distance, &address->norm_distance); update_avg (prop->utilization_in, &address->norm_utilization_in); update_avg (prop->utilization_in, &address->norm_utilization_out); init_range (&range); GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, &find_min_max_it, &range); if (0 != memcmp (&range, &property_range, sizeof (struct PropertyRange))) { /* limits changed, (re)normalize all addresses */ property_range = range; GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, &normalize_address, NULL); GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses, ¬ify_change, NULL); } else { /* renormalize just this one address */ normalize_address (NULL, &address->peer, address); notify_change (NULL, &address->peer, address); } GAS_plugin_solver_unlock (); }
/** * Unregister a client (which may have been a connectivity client, * but this is not assured). * * @param client handle of the (now dead) client */ void GAS_connectivity_remove_client (struct GNUNET_SERVER_Client *client) { GNUNET_CONTAINER_multipeermap_iterate (connection_requests, &free_matching_requests, client); }
/** * Reduce absolute preferences since they got old. * * @param cls unused */ static void preference_aging (void *cls) { struct AgeContext ac; aging_task = NULL; GAS_plugin_solver_lock (); ac.values_to_update = 0; for (ac.cur_client = pc_head; NULL != ac.cur_client; ac.cur_client = ac.cur_client->next) GNUNET_CONTAINER_multipeermap_iterate (ac.cur_client->peer2pref, &age_values, &ac); GAS_plugin_solver_unlock (); if (ac.values_to_update > 0) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Rescheduling aging task due to %u elements remaining to age\n", ac.values_to_update); if (NULL == aging_task) aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, &preference_aging, NULL); } else { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No values to age left, not rescheduling aging task\n"); } }
/** * Disconnect from DV service. * * @param sh service handle */ void GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh) { struct GNUNET_DV_TransmitHandle *pos; if (NULL == sh) return; if (NULL != sh->th) { GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th); sh->th = NULL; } while (NULL != (pos = sh->th_head)) { GNUNET_CONTAINER_DLL_remove (sh->th_head, sh->th_tail, pos); GNUNET_free (pos); } if (NULL != sh->client) { GNUNET_CLIENT_disconnect (sh->client); sh->client = NULL; } GNUNET_CONTAINER_multipeermap_iterate (sh->peers, &cleanup_send_cb, sh); GNUNET_CONTAINER_multipeermap_destroy (sh->peers); GNUNET_free (sh); }
/** * Disconnect and then reconnect to the DV service. * * @param sh service handle */ static void reconnect (struct GNUNET_DV_ServiceHandle *sh) { if (NULL != sh->th) { GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th); sh->th = NULL; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from DV service at %p\n", sh->client); if (NULL != sh->client) { GNUNET_CLIENT_disconnect (sh->client); sh->client = NULL; } GNUNET_CONTAINER_multipeermap_iterate (sh->peers, &cleanup_send_cb, sh); LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to DV service\n"); sh->client = GNUNET_CLIENT_connect ("dv", sh->cfg); if (NULL == sh->client) { GNUNET_break (0); return; } sh->th = GNUNET_CLIENT_notify_transmit_ready (sh->client, sizeof (struct GNUNET_MessageHeader), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, &transmit_start, sh); }
/** * Task run in monitor mode when the user presses CTRL-C to abort. * Stops monitoring activity. * * @param cls the 'struct GNUNET_TRANSPORT_PeerIterateContext *' * @param tc scheduler context */ static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_TIME_Relative duration; end = GNUNET_SCHEDULER_NO_TASK; if (GNUNET_SCHEDULER_NO_TASK != op_timeout) { GNUNET_SCHEDULER_cancel (op_timeout); op_timeout = GNUNET_SCHEDULER_NO_TASK; } if (NULL != tc_handle) { GNUNET_TRANSPORT_try_connect_cancel (tc_handle); tc_handle = NULL; } if (NULL != pic) { GNUNET_TRANSPORT_monitor_peers_cancel (pic); pic = NULL; } if (NULL != vic) { GNUNET_TRANSPORT_monitor_validation_entries_cancel (vic); vic = NULL; } if (NULL != th) { GNUNET_TRANSPORT_notify_transmit_ready_cancel (th); th = NULL; } if (NULL != handle) { GNUNET_TRANSPORT_disconnect (handle); handle = NULL; } if (benchmark_send) { duration = GNUNET_TIME_absolute_get_duration (start_time); FPRINTF (stdout, _("Transmitted %llu bytes/s (%llu bytes in %s)\n"), 1000LL * 1000LL * traffic_sent / (1 + duration.rel_value_us), traffic_sent, GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); } if (benchmark_receive) { duration = GNUNET_TIME_absolute_get_duration (start_time); FPRINTF (stdout, _("Received %llu bytes/s (%llu bytes in %s)\n"), 1000LL * 1000LL * traffic_received / (1 + duration.rel_value_us), traffic_received, GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES)); } if (NULL != monitored_peers) { GNUNET_CONTAINER_multipeermap_iterate (monitored_peers, &destroy_it, NULL); GNUNET_CONTAINER_multipeermap_destroy (monitored_peers); monitored_peers = NULL; } }
/** * We have a new client, notify it about all current sessions. * * @param client the new client */ void GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client) { /* notify new client about existing sessions */ GNUNET_CONTAINER_multipeermap_iterate (sessions, ¬ify_client_about_session, client); }
/** * Calculate when we would like to send the next HELLO to this * peer and ask for it. * * @param cls for which peer to schedule the HELLO */ static void schedule_next_hello (void *cls) { struct Peer *pl = cls; struct FindAdvHelloContext fah; struct GNUNET_MQ_Envelope *env; size_t want; struct GNUNET_TIME_Relative delay; struct GNUNET_HashCode hc; pl->hello_delay_task = NULL; GNUNET_assert (NULL != pl->mq); /* find applicable HELLOs */ fah.peer = pl; fah.result = NULL; fah.max_size = GNUNET_SERVER_MAX_MESSAGE_SIZE - 1; fah.next_adv = GNUNET_TIME_UNIT_FOREVER_REL; GNUNET_CONTAINER_multipeermap_iterate (peers, &find_advertisable_hello, &fah); pl->hello_delay_task = GNUNET_SCHEDULER_add_delayed (fah.next_adv, &schedule_next_hello, pl); if (NULL == fah.result) return; delay = GNUNET_TIME_absolute_get_remaining (pl->next_hello_allowed); if (0 != delay.rel_value_us) return; want = GNUNET_HELLO_size (fah.result->hello); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending HELLO with %u bytes", (unsigned int) want); env = GNUNET_MQ_msg_copy (&fah.result->hello->header); GNUNET_MQ_send (pl->mq, env); /* avoid sending this one again soon */ GNUNET_CRYPTO_hash (&pl->pid, sizeof (struct GNUNET_PeerIdentity), &hc); GNUNET_CONTAINER_bloomfilter_add (fah.result->filter, &hc); GNUNET_STATISTICS_update (stats, gettext_noop ("# HELLO messages gossipped"), 1, GNUNET_NO); /* prepare to send the next one */ if (NULL != pl->hello_delay_task) GNUNET_SCHEDULER_cancel (pl->hello_delay_task); pl->next_hello_allowed = GNUNET_TIME_relative_to_absolute (HELLO_ADVERTISEMENT_MIN_FREQUENCY); pl->hello_delay_task = GNUNET_SCHEDULER_add_now (&schedule_next_hello, pl); }
/** * Add peers and schedule connection attempt * * @param cls unused, NULL */ static void add_peer_task (void *cls) { add_task = NULL; GNUNET_CONTAINER_multipeermap_iterate (peers, &try_add_peers, NULL); }
/** * Shutdown connectivity subsystem. */ void GAS_connectivity_done () { GNUNET_CONTAINER_multipeermap_iterate (connection_requests, &free_request, NULL); GNUNET_CONTAINER_multipeermap_destroy (connection_requests); connection_requests = NULL; }
/** * Broadcast an updated typemap message to all neighbours. * Restarts the retransmissions until the typemaps are confirmed. * * @param msg message to transmit */ void GSC_SESSIONS_broadcast_typemap (const struct GNUNET_MessageHeader *msg) { if (NULL == sessions) return; GNUNET_CONTAINER_multipeermap_iterate (sessions, &do_restart_typemap_message, (void *) msg); }
/** * Shutdown ATS subsystem. */ void GST_ats_done () { GNUNET_CONTAINER_multipeermap_iterate (p2a, &destroy_ai_cb, NULL); publish_p2a_stat_update (); GNUNET_CONTAINER_multipeermap_destroy (p2a); p2a = NULL; }
/** * Shutdown sessions subsystem. */ void GSC_SESSIONS_done () { if (NULL != sessions) { GNUNET_CONTAINER_multipeermap_iterate (sessions, &free_session_helper, NULL); GNUNET_CONTAINER_multipeermap_destroy (sessions); sessions = NULL; } }
/** * Cleaup and destroy the map */ static void cleanup_map () { if (NULL != map) { GNUNET_assert (GNUNET_SYSERR != GNUNET_CONTAINER_multipeermap_iterate (map, &iterator, NULL)); GNUNET_CONTAINER_multipeermap_destroy (map); map = NULL; } }
/** * Signature of a function called by ATS with the current bandwidth * and address preferences as determined by ATS. * * @param cls closure, should point to "asc-closure" * @param peer for which we suggest an address, NULL if ATS connection died * @param address suggested address (including peer identity of the peer), * may be NULL to signal disconnect from peer * @param session session to use, NULL to establish a new outgoing session * @param bandwidth_out assigned outbound bandwidth for the connection, * 0 to signal disconnect * @param bandwidth_in assigned inbound bandwidth for the connection, * 0 to signal disconnect */ static void address_suggest_cb (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) { const char *asc_cls = cls; struct AddressSuggestData *asd; GNUNET_break (0 == strcmp (asc_cls, "asc-closure")); if (NULL == peer) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Connection to ATS died, likely a crash!\n"); GNUNET_SCHEDULER_shutdown (); #if 0 /* This is what we should do if we wanted to continue past the ATS crash. */ GNUNET_CONTAINER_multipeermap_iterate (p2asd, &free_asd, NULL); GNUNET_CONTAINER_multipeermap_iterate (p2aid, &free_aid, NULL); #endif return; } asd = find_address_suggestion (peer); if (NULL == asd) { asd = GNUNET_new (struct AddressSuggestData); GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multipeermap_put (p2asd, peer, asd, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); }
/** * Stop the nodes management */ void GED_nodes_stop () { if (NULL != ch) { GNUNET_CORE_disconnect (ch); ch = NULL; } if (NULL != nodes_requested) { GNUNET_CONTAINER_multipeermap_iterate (nodes_requested, &cleanup_node, nodes_requested); update_stats (nodes_requested); GNUNET_CONTAINER_multipeermap_destroy (nodes_requested); nodes_requested = NULL; } if (NULL != nodes_active) { GNUNET_CONTAINER_multipeermap_iterate (nodes_active, &cleanup_node, nodes_active); update_stats (nodes_active); GNUNET_CONTAINER_multipeermap_destroy (nodes_active); nodes_active = NULL; } if (NULL != nodes_inactive) { GNUNET_CONTAINER_multipeermap_iterate (nodes_inactive, &cleanup_node, nodes_inactive); update_stats (nodes_inactive); GNUNET_CONTAINER_multipeermap_destroy (nodes_inactive); nodes_inactive = NULL; } }
/** * @brief Store the peers currently in #valid_peers to disk. */ static void store_valid_peers () { struct GNUNET_DISK_FileHandle *fh; uint32_t number_written_peers; int ret; if (0 == strncmp ("DISABLE", filename_valid_peers, 7)) { return; } ret = GNUNET_DISK_directory_create_for_file (filename_valid_peers); if (GNUNET_SYSERR == ret) { LOG (GNUNET_ERROR_TYPE_WARNING, "Not able to create directory for file `%s'\n", filename_valid_peers); GNUNET_break (0); } else if (GNUNET_NO == ret) { LOG (GNUNET_ERROR_TYPE_WARNING, "Directory for file `%s' exists but is not writable for us\n", filename_valid_peers); GNUNET_break (0); } fh = GNUNET_DISK_file_open (filename_valid_peers, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); if (NULL == fh) { LOG (GNUNET_ERROR_TYPE_WARNING, "Not able to write valid peers to file `%s'\n", filename_valid_peers); return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Writing %u valid peers to disk\n", GNUNET_CONTAINER_multipeermap_size (valid_peers)); number_written_peers = GNUNET_CONTAINER_multipeermap_iterate (valid_peers, store_peer_presistently_iterator, fh); GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); GNUNET_assert (number_written_peers == GNUNET_CONTAINER_multipeermap_size (valid_peers)); }
/** * Update our flood message to be sent (and our timestamps). * * @param cls unused */ static void update_flood_message (void *cls) { struct GNUNET_TIME_Relative offset; unsigned int i; flood_task = NULL; offset = GNUNET_TIME_absolute_get_remaining (next_timestamp); if (0 != offset.rel_value_us) { /* somehow run early, delay more */ flood_task = GNUNET_SCHEDULER_add_delayed (offset, &update_flood_message, NULL); return; } estimate_index = (estimate_index + 1) % HISTORY_SIZE; if (estimate_count < HISTORY_SIZE) estimate_count++; current_timestamp = next_timestamp; next_timestamp = GNUNET_TIME_absolute_add (current_timestamp, gnunet_nse_interval); if ( (current_timestamp.abs_value_us == GNUNET_TIME_absolute_ntoh (next_message.timestamp).abs_value_us) && (get_matching_bits (current_timestamp, &my_identity) < ntohl(next_message.matching_bits)) ) { /* we received a message for this round way early, use it! */ size_estimate_messages[estimate_index] = next_message; size_estimate_messages[estimate_index].hop_count = htonl (1 + ntohl (next_message.hop_count)); } else setup_flood_message (estimate_index, current_timestamp); next_message.matching_bits = htonl (0); /* reset for 'next' round */ hop_count_max = 0; for (i = 0; i < HISTORY_SIZE; i++) hop_count_max = GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count), hop_count_max); GNUNET_CONTAINER_multipeermap_iterate (peers, &schedule_current_round, NULL); flood_task = GNUNET_SCHEDULER_add_at (next_timestamp, &update_flood_message, NULL); }
/** * @brief Delete storage of peers that was created with #Peers_initialise () */ void Peers_terminate () { if (GNUNET_SYSERR == GNUNET_CONTAINER_multipeermap_iterate (peer_map, peermap_clear_iterator, NULL)) { LOG (GNUNET_ERROR_TYPE_WARNING, "Iteration destroying peers was aborted.\n"); } GNUNET_CONTAINER_multipeermap_destroy (peer_map); store_valid_peers (); GNUNET_free (filename_valid_peers); GNUNET_CONTAINER_multipeermap_destroy (valid_peers); }
/** * @brief Get all currently known, valid peer ids. * * @param it function to call on each peer id * @param it_cls extra argument to @a it * @return the number of key value pairs processed, * #GNUNET_SYSERR if it aborted iteration */ int Peers_get_valid_peers (PeersIterator iterator, void *it_cls) { struct PeersIteratorCls *cls; int ret; cls = GNUNET_new (struct PeersIteratorCls); cls->iterator = iterator; cls->cls = it_cls; ret = GNUNET_CONTAINER_multipeermap_iterate (valid_peers, valid_peer_iterator, cls); GNUNET_free (cls); return ret; }
/** * Shutdown neighbours subsystem. */ void GSC_NEIGHBOURS_done () { if (NULL != transport) { GNUNET_TRANSPORT_disconnect (transport); transport = NULL; } if (NULL != neighbours) { GNUNET_CONTAINER_multipeermap_iterate (neighbours, &free_neighbour_helper, NULL); GNUNET_CONTAINER_multipeermap_destroy (neighbours); neighbours = NULL; } }
/** * @brief Get a random peer from @a peer_map * * @param peer_map the peer_map to get the peer from * * @return a random peer */ static const struct GNUNET_PeerIdentity * get_random_peer_from_peermap (const struct GNUNET_CONTAINER_MultiPeerMap *peer_map) { struct GetRandPeerIteratorCls *iterator_cls; const struct GNUNET_PeerIdentity *ret; iterator_cls = GNUNET_new (struct GetRandPeerIteratorCls); iterator_cls->index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CONTAINER_multipeermap_size (peer_map)); (void) GNUNET_CONTAINER_multipeermap_iterate (valid_peers, get_rand_peer_iterator, iterator_cls); ret = iterator_cls->peer; GNUNET_free (iterator_cls); return ret; }
/** * Begin monitoring sessions of a plugin. There can only * be one active monitor per plugin (i.e. if there are * multiple monitors, the transport service needs to * multiplex the generated events over all of them). * * @param cls closure of the plugin * @param sic callback to invoke, NULL to disable monitor; * plugin will being by iterating over all active * sessions immediately and then enter monitor mode * @param sic_cls closure for @a sic */ static void template_plugin_setup_monitor (void *cls, GNUNET_TRANSPORT_SessionInfoCallback sic, void *sic_cls) { struct Plugin *plugin = cls; plugin->sic = sic; plugin->sic_cls = sic_cls; if (NULL != sic) { #if 0 GNUNET_CONTAINER_multipeermap_iterate (NULL /* FIXME */, &send_session_info_iter, plugin); #endif /* signal end of first iteration */ sic (sic_cls, NULL, NULL); } }
/** * Disconnect from the core service. This function can only * be called *after* all pending #GNUNET_CORE_notify_transmit_ready() * requests have been explicitly canceled. * * @param handle connection to core to disconnect */ void GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle) { struct ControlMessage *cm; GNUNET_assert (NULL != handle); LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from CORE service\n"); if (NULL != handle->cth) { GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth); handle->cth = NULL; } while (NULL != (cm = handle->control_pending_head)) { GNUNET_CONTAINER_DLL_remove (handle->control_pending_head, handle->control_pending_tail, cm); if (NULL != cm->th) cm->th->cm = NULL; if (NULL != cm->cont) cm->cont (cm->cont_cls, GNUNET_SYSERR); GNUNET_free (cm); } if (NULL != handle->client) { GNUNET_CLIENT_disconnect (handle->client); handle->client = NULL; } GNUNET_CONTAINER_multipeermap_iterate (handle->peers, &disconnect_and_free_peer_entry, handle); if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (handle->reconnect_task); handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; } GNUNET_CONTAINER_multipeermap_destroy (handle->peers); handle->peers = NULL; GNUNET_break (handle->ready_peer_head == NULL); GNUNET_free (handle); }
/** * Shutdown * * @param cls NULL * @param tc task context from scheduler * @return */ static void do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { shutdown_task = GNUNET_SCHEDULER_NO_TASK; GNUNET_ATS_performance_done (ats); ats = NULL; if (NULL != stmt_insert) { sqlite3_finalize (stmt_insert); stmt_insert = NULL; } GNUNET_break (SQLITE_OK == sqlite3_close (db)); db = NULL; if (NULL != map) { GNUNET_assert (GNUNET_SYSERR != GNUNET_CONTAINER_multipeermap_iterate (map, free_iterator, NULL)); GNUNET_CONTAINER_multipeermap_destroy (map); map = NULL; } }
/** * Last task run during shutdown. Disconnects us from * the transport and core. * * @param cls unused, NULL */ static void cleaning_task (void *cls) { if (NULL != peerinfo_notify) { GNUNET_PEERINFO_notify_cancel (peerinfo_notify); peerinfo_notify = NULL; } if (NULL != handle) { GNUNET_CORE_disconnect (handle); handle = NULL; } whitelist_peers (); if (NULL != add_task) { GNUNET_SCHEDULER_cancel (add_task); add_task = NULL; } if (NULL != oh) { GNUNET_TRANSPORT_offer_hello_cancel (oh); oh = NULL; } GNUNET_CONTAINER_multipeermap_iterate (peers, &free_peer, NULL); GNUNET_CONTAINER_multipeermap_destroy (peers); peers = NULL; if (NULL != ats) { GNUNET_ATS_connectivity_done (ats); ats = NULL; } if (NULL != stats) { GNUNET_STATISTICS_destroy (stats, GNUNET_NO); stats = NULL; } }
/** * Close down any existing connection to the CORE service and * try re-establishing it later. * * @param h our handle */ static void reconnect_later (struct GNUNET_CORE_Handle *h) { struct ControlMessage *cm; struct PeerRecord *pr; GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task); if (NULL != h->cth) { GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth); h->cth = NULL; } if (NULL != h->client) { GNUNET_CLIENT_disconnect (h->client); h->client = NULL; } h->currently_down = GNUNET_YES; GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK); h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->retry_backoff, &reconnect_task, h); while (NULL != (cm = h->control_pending_head)) { GNUNET_CONTAINER_DLL_remove (h->control_pending_head, h->control_pending_tail, cm); if (NULL != cm->th) cm->th->cm = NULL; if (NULL != cm->cont) cm->cont (cm->cont_cls, GNUNET_NO); GNUNET_free (cm); } GNUNET_CONTAINER_multipeermap_iterate (h->peers, &disconnect_and_free_peer_entry, h); while (NULL != (pr = h->ready_peer_head)) GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr); GNUNET_assert (h->control_pending_head == NULL); h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff); }
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; }