static int testMap (int i) { struct GNUNET_CONTAINER_MultiHashMap *m; GNUNET_HashCode k1; GNUNET_HashCode k2; const char *ret; int j; CHECK (NULL != (m = GNUNET_CONTAINER_multihashmap_create (i))); memset (&k1, 0, sizeof (k1)); memset (&k2, 1, sizeof (k2)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (m, &k1)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (m, &k2)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_remove (m, &k1, NULL)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_remove (m, &k2, NULL)); CHECK (NULL == GNUNET_CONTAINER_multihashmap_get (m, &k1)); CHECK (NULL == GNUNET_CONTAINER_multihashmap_get (m, &k2)); CHECK (0 == GNUNET_CONTAINER_multihashmap_remove_all (m, &k1)); CHECK (0 == GNUNET_CONTAINER_multihashmap_size (m)); CHECK (0 == GNUNET_CONTAINER_multihashmap_iterate (m, NULL, NULL)); CHECK (0 == GNUNET_CONTAINER_multihashmap_get_multiple (m, &k1, NULL, NULL)); CHECK (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (m, &k1, "v1", GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); CHECK (1 == GNUNET_CONTAINER_multihashmap_size (m)); ret = GNUNET_CONTAINER_multihashmap_get (m, &k1); GNUNET_assert (ret != NULL); CHECK (0 == strcmp ("v1", ret)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_put (m, &k1, "v1", GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE)); CHECK (1 == GNUNET_CONTAINER_multihashmap_size (m)); CHECK (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (m, &k1, "v2", GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); CHECK (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (m, &k1, "v3", GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); CHECK (3 == GNUNET_CONTAINER_multihashmap_size (m)); CHECK (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (m, &k1, "v3")); CHECK (2 == GNUNET_CONTAINER_multihashmap_size (m)); CHECK (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (m, &k1)); CHECK (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (m, &k2)); CHECK (2 == GNUNET_CONTAINER_multihashmap_get_multiple (m, &k1, NULL, NULL)); CHECK (0 == GNUNET_CONTAINER_multihashmap_get_multiple (m, &k2, NULL, NULL)); CHECK (2 == GNUNET_CONTAINER_multihashmap_iterate (m, NULL, NULL)); CHECK (2 == GNUNET_CONTAINER_multihashmap_remove_all (m, &k1)); for (j = 0; j < 1024; j++) CHECK (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (m, &k1, "v2", GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); GNUNET_CONTAINER_multihashmap_destroy (m); return 0; }
/** * Get one of the results for a particular key in the datastore. * * @param cls closure * @param offset offset of the result (modulo num-results); * specific ordering does not matter for the offset * @param key maybe NULL (to match all entries) * @param vhash hash of the value, maybe NULL (to * match all values that have the right key). * Note that for DBlocks there is no difference * betwen key and vhash, but for other blocks * there may be! * @param type entries of which type are relevant? * Use 0 for any type. * @param proc function to call on each matching value; * will be called with NULL if nothing matches * @param proc_cls closure for proc */ static void heap_plugin_get_key (void *cls, uint64_t offset, const struct GNUNET_HashCode *key, const struct GNUNET_HashCode *vhash, enum GNUNET_BLOCK_Type type, PluginDatumProcessor proc, void *proc_cls) { struct Plugin *plugin = cls; struct GetContext gc; gc.plugin = plugin; gc.offset = 0; gc.vhash = vhash; gc.type = type; gc.proc = proc; gc.proc_cls = proc_cls; if (NULL == key) { GNUNET_CONTAINER_multihashmap_iterate (plugin->keyvalue, &count_iterator, &gc); if (0 == gc.offset) { proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } gc.offset = offset % gc.offset; GNUNET_CONTAINER_multihashmap_iterate (plugin->keyvalue, &get_iterator, &gc); } else { GNUNET_CONTAINER_multihashmap_get_multiple (plugin->keyvalue, key, &count_iterator, &gc); if (0 == gc.offset) { proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0); return; } gc.offset = offset % gc.offset; GNUNET_CONTAINER_multihashmap_get_multiple (plugin->keyvalue, key, &get_iterator, &gc); } }
/** * Last task run during shutdown. Disconnects us from * the transport and core. * * @param cls unused, NULL * @param tc scheduler context */ static void add_peer_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { add_task = GNUNET_SCHEDULER_NO_TASK; GNUNET_CONTAINER_multihashmap_iterate (peers, &try_add_peers, NULL); }
/** * Last task run during shutdown. Disconnects us from * the transport and core. * * @param cls unused, NULL * @param tc scheduler context */ static void cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { if (NULL != peerinfo_notify) { GNUNET_PEERINFO_notify_cancel (peerinfo_notify); peerinfo_notify = NULL; } GNUNET_TRANSPORT_disconnect (transport); transport = NULL; if (handle != NULL) { GNUNET_CORE_disconnect (handle); handle = NULL; } whitelist_peers (); if (GNUNET_SCHEDULER_NO_TASK != add_task) { GNUNET_SCHEDULER_cancel (add_task); add_task = GNUNET_SCHEDULER_NO_TASK; } GNUNET_CONTAINER_multihashmap_iterate (peers, &free_peer, NULL); GNUNET_CONTAINER_multihashmap_destroy (peers); peers = NULL; if (stats != NULL) { GNUNET_STATISTICS_destroy (stats, GNUNET_NO); stats = NULL; } }
/** * Core's transmit notify callback to send response * * @param cls the related node * @param bufsize buffer size * @param buf the buffer to copy to * @return bytes passed */ static size_t send_response_cb (void *cls, size_t bufsize, void *buf) { struct Node *n = cls; struct Experimentation_Response msg; size_t c_issuers = GNUNET_CONTAINER_multihashmap_size (valid_issuers); size_t ri_size = c_issuers * sizeof (struct GNUNET_CRYPTO_EddsaPublicKey); size_t msg_size = sizeof (msg); size_t total_size = msg_size + ri_size; struct GNUNET_CRYPTO_EddsaPublicKey *issuers; n->cth = NULL; if (buf == NULL) { /* client disconnected */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client disconnected\n"); return 0; } GNUNET_assert (bufsize >= total_size); msg.msg.size = htons (total_size); msg.msg.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_RESPONSE); msg.capabilities = htonl (GSE_node_capabilities); msg.issuer_count = htonl (c_issuers); memcpy (buf, &msg, msg_size); issuers = (struct GNUNET_CRYPTO_EddsaPublicKey *) buf + msg_size; GNUNET_CONTAINER_multihashmap_iterate (valid_issuers, &append_public_key, &issuers); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending response to peer %s\n", GNUNET_i2s (&n->id)); return total_size; }
/** * Destroy a stream handle. * * @param sh stream to process */ static void destroy_stream_handle (struct StreamHandle *sh) { struct GSF_StreamRequest *sr; while (NULL != (sr = sh->pending_head)) { sr->proc (sr->proc_cls, GNUNET_BLOCK_TYPE_ANY, GNUNET_TIME_UNIT_FOREVER_ABS, 0, NULL); GSF_stream_query_cancel (sr); } GNUNET_CONTAINER_multihashmap_iterate (sh->waiting_map, &free_waiting_entry, sh); if (NULL != sh->wh) GNUNET_STREAM_io_write_cancel (sh->wh); if (NULL != sh->rh) GNUNET_STREAM_io_read_cancel (sh->rh); if (GNUNET_SCHEDULER_NO_TASK != sh->timeout_task) GNUNET_SCHEDULER_cancel (sh->timeout_task); GNUNET_STREAM_close (sh->stream); GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (stream_map, &sh->target.hashPubKey, sh)); GNUNET_CONTAINER_multihashmap_destroy (sh->waiting_map); GNUNET_free (sh); }
/** * Disconnect from the PEERSTORE service. Any pending ITERATE and WATCH requests * will be canceled. * Any pending STORE requests will depend on @e snyc_first flag. * * @param h handle to disconnect * @param sync_first send any pending STORE requests before disconnecting */ void GNUNET_PEERSTORE_disconnect (struct GNUNET_PEERSTORE_Handle *h, int sync_first) { struct GNUNET_PEERSTORE_IterateContext *ic; struct GNUNET_PEERSTORE_StoreContext *sc; LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting.\n"); if (NULL != h->watches) { GNUNET_CONTAINER_multihashmap_iterate (h->watches, &destroy_watch, NULL); GNUNET_CONTAINER_multihashmap_destroy (h->watches); h->watches = NULL; } while (NULL != (ic = h->iterate_head)) { GNUNET_break (0); GNUNET_PEERSTORE_iterate_cancel (ic); } if (NULL != h->store_head) { if (GNUNET_YES == sync_first) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Delaying disconnection due to pending store requests.\n"); h->disconnecting = GNUNET_YES; return; } while (NULL != (sc = h->store_head)) GNUNET_PEERSTORE_store_cancel (sc); } do_disconnect (h); }
/** * Kill a #Slave object * * @param slave the #Slave object */ static void kill_slave (struct Slave *slave) { struct HostRegistration *hr_entry; while (NULL != (hr_entry = slave->hr_dll_head)) { GNUNET_CONTAINER_DLL_remove (slave->hr_dll_head, slave->hr_dll_tail, hr_entry); GNUNET_free (hr_entry); } if (NULL != slave->rhandle) GNUNET_TESTBED_cancel_registration (slave->rhandle); GNUNET_assert (GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_iterate (slave->reghost_map, reghost_free_iterator, slave)); GNUNET_CONTAINER_multihashmap_destroy (slave->reghost_map); if (NULL != slave->controller) GNUNET_TESTBED_controller_disconnect (slave->controller); if (NULL != slave->controller_proc) { LOG_DEBUG ("Stopping a slave\n"); GNUNET_TESTBED_controller_kill_ (slave->controller_proc); } }
/** * Removes any expired block. * * @param plugin the plugin */ static void namecache_expire_blocks (struct Plugin *plugin) { GNUNET_CONTAINER_multihashmap_iterate (plugin->hm, &expire_blocks, plugin); }
/** * Shutdown database connection and associate data * structures. * @param plugin the plugin context (state for this module) */ static void database_shutdown (struct Plugin *plugin) { struct GNUNET_DISK_FileHandle *fh; fh = GNUNET_DISK_file_open (plugin->fn, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE | GNUNET_DISK_OPEN_READWRITE, GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_USER_READ); if (NULL == fh) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to initialize file: %s.\n"), plugin->fn); return; } GNUNET_CONTAINER_multihashmap_iterate (plugin->hm, &store_and_free_entries, fh); GNUNET_CONTAINER_multihashmap_destroy (plugin->hm); GNUNET_DISK_file_close (fh); }
void GAS_addresses_destroy_all () { if (GNUNET_NO == running) return; if (addresses != NULL) GNUNET_CONTAINER_multihashmap_iterate (addresses, &free_address_it, NULL); GNUNET_assert (active_addr_count == 0); }
/** * Handle NOTIFY-message. * * @param cls closure * @param client identification of the client * @param message the actual message */ static void handle_notify (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received\n", "NOTIFY"); GNUNET_SERVER_client_mark_monitor (client); GNUNET_SERVER_notification_context_add (notify_list, client); GNUNET_CONTAINER_multihashmap_iterate (hostmap, &do_notify_entry, client); GNUNET_SERVER_receive_done (client, GNUNET_OK); }
/** * We've gotten a HELLO from another peer. Consider it for * advertising. * * @param hello the HELLO we got */ static void consider_for_advertising (const struct GNUNET_HELLO_Message *hello) { int have_address; struct GNUNET_PeerIdentity pid; struct GNUNET_TIME_Absolute dt; struct GNUNET_HELLO_Message *nh; struct Peer *peer; uint16_t size; if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid)) { GNUNET_break (0); return; } if (0 == memcmp (&pid, &my_identity, sizeof (struct GNUNET_PeerIdentity))) return; /* that's me! */ have_address = GNUNET_NO; GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &address_iterator, &have_address); if (GNUNET_NO == have_address) return; /* no point in advertising this one... */ peer = GNUNET_CONTAINER_multihashmap_get (peers, &pid.hashPubKey); if (NULL == peer) { peer = make_peer (&pid, hello, GNUNET_NO); } else if (peer->hello != NULL) { dt = GNUNET_HELLO_equals (peer->hello, hello, GNUNET_TIME_absolute_get ()); if (dt.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value) return; /* nothing new here */ } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' from peer `%s' for advertising\n", "HELLO", GNUNET_i2s (&pid)); if (peer->hello != NULL) { nh = GNUNET_HELLO_merge (peer->hello, hello); GNUNET_free (peer->hello); peer->hello = nh; } else { size = GNUNET_HELLO_size (hello); peer->hello = GNUNET_malloc (size); memcpy (peer->hello, hello, size); } if (peer->filter != NULL) GNUNET_CONTAINER_bloomfilter_free (peer->filter); setup_filter (peer); /* since we have a new HELLO to pick from, re-schedule all * HELLO requests that are not bound by the HELLO send rate! */ GNUNET_CONTAINER_multihashmap_iterate (peers, &reschedule_hellos, peer); }
/** * Cancel an ongoing regex search in the DHT and free all resources. * * @param h the search context. */ void REGEX_INTERNAL_search_cancel (struct REGEX_INTERNAL_Search *h) { unsigned int i; GNUNET_free (h->description); GNUNET_CONTAINER_multihashmap_iterate (h->dht_get_handles, ®ex_cancel_dht_get, NULL); GNUNET_CONTAINER_multihashmap_iterate (h->dht_get_results, ®ex_free_result, NULL); GNUNET_CONTAINER_multihashmap_destroy (h->dht_get_results); GNUNET_CONTAINER_multihashmap_destroy (h->dht_get_handles); if (0 < h->n_contexts) { for (i = 0; i < h->n_contexts; i++) GNUNET_free (h->contexts[i]); GNUNET_free (h->contexts); } GNUNET_free (h); }
/** * Destroy the whole tree and free all used memory and Peer_Ids * * @param t Tree to be destroyed */ void tree_destroy (struct MeshTunnelTree *t) { #if MESH_TREE_DEBUG GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tree: Destroying tree\n"); #endif tree_node_destroy (t->root); GNUNET_CONTAINER_multihashmap_iterate (t->first_hops, &iterate_free, NULL); GNUNET_CONTAINER_multihashmap_destroy (t->first_hops); GNUNET_free (t); }
/** * Some (significant) input changed, recalculate bandwidth assignment * for all peers. */ static void recalculate_assigned_bw () { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Recalculating bandwidth for all active connections\n"); GNUNET_STATISTICS_update (GSA_stats, "# bandwidth recalculations performed", 1, GNUNET_NO); GNUNET_STATISTICS_set (GSA_stats, "# active addresses", active_addr_count, GNUNET_NO); GNUNET_CONTAINER_multihashmap_iterate (addresses, &update_bw_simple_it, NULL); }
/** * Clean up our state. Called during shutdown. * * @param cls unused * @param tc scheduler task context, unused */ static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_SERVER_notification_context_destroy (notify_list); notify_list = NULL; GNUNET_CONTAINER_multihashmap_iterate (hostmap, &free_host_entry, NULL); GNUNET_CONTAINER_multihashmap_destroy (hostmap); if (stats != NULL) { GNUNET_STATISTICS_destroy (stats, GNUNET_NO); stats = NULL; } }
/** * Handle GET-ALL-message. * * @param cls closure * @param client identification of the client * @param message the actual message */ static void handle_get_all (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { struct GNUNET_SERVER_TransmitContext *tc; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' message received\n", "GET_ALL"); tc = GNUNET_SERVER_transmit_context_create (client); GNUNET_CONTAINER_multihashmap_iterate (hostmap, &add_to_tc, tc); GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END); GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); }
/** * Get all of the keys in the datastore. * * @param cls closure * @param proc function to call on each key * @param proc_cls closure for proc */ static void heap_get_keys (void *cls, PluginKeyProcessor proc, void *proc_cls) { struct Plugin *plugin = cls; struct GetAllContext gac; gac.proc = proc; gac.proc_cls = proc_cls; GNUNET_CONTAINER_multihashmap_iterate (plugin->keyvalue, &return_value, &gac); }
/** * Remove every trail where peer is either next_hop or prev_hop. Also send a * trail teardown message in direction of hop which is not disconnected. * @param peer Peer identity. Trail containing this peer should be removed. */ int GDS_ROUTING_remove_trail_by_peer (const struct GNUNET_PeerIdentity *peer) { int ret; /* No entries in my routing table. */ if (0 == GNUNET_CONTAINER_multihashmap_size(routing_table)) return GNUNET_YES; ret = GNUNET_CONTAINER_multihashmap_iterate (routing_table, &remove_matching_trails, (void *)peer); return ret; }
/** * Clean up @a client handle if we stored any via #handle_link_controllers(), * the given client disconnected. * * @param client the client that is history */ void GST_link_notify_disconnect (struct GNUNET_SERVICE_Client *client) { struct NeighbourConnectCtxt *ncc; struct NeighbourConnectCtxt *nccn; struct LCFContext *lcf; struct LCFContext *lcfn; for (ncc = ncc_head; NULL != ncc; ncc = nccn) { nccn = ncc->next; if (ncc->client == client) cleanup_ncc (ncc); } for (unsigned int i=0;i<GST_slave_list_size;i++) { struct Slave *slave = GST_slave_list[i]; struct LinkControllersContext *lcc; if (NULL == slave) continue; GNUNET_CONTAINER_multihashmap_iterate (slave->reghost_map, &drop_client_entries, client); lcc = slave->lcc; if (NULL == lcc) continue; if (lcc->client == client) { slave->lcc = NULL; GNUNET_free (lcc); } } for (lcf = lcf_head; NULL != lcf; lcf = lcfn) { lcfn = lcf->next; if ( (NULL != lcf) && (client == lcf->client) ) { if (NULL != lcf->op) GNUNET_TESTBED_operation_done (lcf->op); GNUNET_CONTAINER_DLL_remove (lcf_head, lcf_tail, lcf); GNUNET_free (lcf); } } }
/** * Stop the validation subsystem. */ void GST_validation_stop () { struct CheckHelloValidatedContext *chvc; GNUNET_CONTAINER_multihashmap_iterate (validation_map, &cleanup_validation_entry, NULL); GNUNET_CONTAINER_multihashmap_destroy (validation_map); validation_map = NULL; while (NULL != (chvc = chvc_head)) { GNUNET_CONTAINER_DLL_remove (chvc_head, chvc_tail, chvc); GNUNET_free (chvc); } GNUNET_PEERINFO_notify_cancel (pnc); }
/** * Exit point from the plugin. * @param cls our "struct Plugin*" * @return always NULL */ void * libgnunet_plugin_datastore_heap_done (void *cls) { struct GNUNET_DATASTORE_PluginFunctions *api = cls; struct Plugin *plugin = api->cls; GNUNET_CONTAINER_multihashmap_iterate (plugin->keyvalue, &free_value, plugin); GNUNET_CONTAINER_multihashmap_destroy (plugin->keyvalue); GNUNET_CONTAINER_heap_destroy (plugin->by_expiration); GNUNET_CONTAINER_heap_destroy (plugin->by_replication); GNUNET_free (plugin); GNUNET_free (api); return NULL; }
/** * Delete records with the given key * * @param cls closure (internal context for the plugin) * @param sub_system name of sub system * @param peer Peer identity (can be NULL) * @param key entry key string (can be NULL) * @return number of deleted records */ static int peerstore_flat_delete_records (void *cls, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key) { struct Plugin *plugin = cls; plugin->iter_sub_system = sub_system; plugin->iter_peer = peer; plugin->iter_key = key; plugin->deleted_entries = 0; GNUNET_CONTAINER_multihashmap_iterate (plugin->hm, &delete_entries, plugin); return plugin->deleted_entries; }
/** * Try reconnecting to the dht service. * * @param cls a `struct GNUNET_DHT_Handle` * @param tc scheduler context */ static void try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_DHT_Handle *handle = cls; LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with DHT %p\n", handle); handle->retry_time = GNUNET_TIME_STD_BACKOFF (handle->retry_time); handle->reconnect_task = NULL; if (GNUNET_YES != try_connect (handle)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "dht reconnect failed(!)\n"); return; } GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests, &add_request_to_pending, handle); process_pending_messages (handle); }
/** * Shutdown subsystem for non-anonymous file-sharing. */ void GSF_stream_stop () { struct StreamClient *sc; while (NULL != (sc = sc_head)) terminate_stream (sc); if (NULL != listen_socket) { GNUNET_STREAM_listen_close (listen_socket); listen_socket = NULL; } GNUNET_CONTAINER_multihashmap_iterate (stream_map, &release_streams, NULL); GNUNET_CONTAINER_multihashmap_destroy (stream_map); stream_map = NULL; }
/** * We had a serious error, tear down and re-create stream from scratch. * * @param sh stream to reset */ static void reset_stream (struct StreamHandle *sh) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Resetting stream to %s\n", GNUNET_i2s (&sh->target)); if (NULL != sh->rh) GNUNET_STREAM_io_read_cancel (sh->rh); GNUNET_STREAM_close (sh->stream); sh->is_ready = GNUNET_NO; GNUNET_CONTAINER_multihashmap_iterate (sh->waiting_map, &move_to_pending, sh); sh->stream = GNUNET_STREAM_open (GSF_cfg, &sh->target, GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER, &stream_ready_cb, sh, GNUNET_STREAM_OPTION_END); }
/** * Delete expired records (expiry < now) * * @param cls closure (internal context for the plugin) * @param now time to use as reference * @param cont continuation called with the number of records expired * @param cont_cls continuation closure * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and cont is not * called */ static int peerstore_flat_expire_records (void *cls, struct GNUNET_TIME_Absolute now, GNUNET_PEERSTORE_Continuation cont, void *cont_cls) { struct Plugin *plugin = cls; plugin->exp_changes = 0; plugin->iter_now = now; GNUNET_CONTAINER_multihashmap_iterate (plugin->hm, &expire_entries, plugin); if (NULL != cont) { cont (cont_cls, plugin->exp_changes); } return GNUNET_OK; }
/** * Called with any sensor list request received. * * Each time the function must call #GNUNET_CADET_receive_done on the channel * in order to receive the next message. This doesn't need to be immediate: * can be delayed if some processing is done on the message. * * @param cls Closure (set from #GNUNET_CADET_connect). * @param channel Connection to the other end. * @param channel_ctx Place to store local state associated with the channel. * @param message The actual message. * @return #GNUNET_OK to keep the channel open, * #GNUNET_SYSERR to close it (signal serious error). */ static int handle_sensor_list_req (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { struct ClientPeerContext *cp = *channel_ctx; struct GNUNET_MessageHeader *end_msg; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a sensor list request from peer `%s'.\n", GNUNET_i2s (&cp->peerid)); GNUNET_CONTAINER_multihashmap_iterate (sensors, &send_sensor_brief, cp); end_msg = GNUNET_new (struct GNUNET_MessageHeader); end_msg->size = htons (sizeof (struct GNUNET_MessageHeader)); end_msg->type = htons (GNUNET_MESSAGE_TYPE_SENSOR_END); queue_msg (end_msg, cp); GNUNET_CADET_receive_done (channel); return GNUNET_OK; }
/** * Functions with this signature are called whenever a client * is disconnected on the network level. * * @param cls closure (NULL for dht) * @param client identification of the client; NULL * for the last call when the server is destroyed */ static void handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) { struct ClientList *pos; struct PendingMessage *reply; struct ClientMonitorRecord *monitor; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Local client %p disconnects\n", client); pos = find_active_client (client); GNUNET_CONTAINER_DLL_remove (client_head, client_tail, pos); if (pos->transmit_handle != NULL) GNUNET_SERVER_notify_transmit_ready_cancel (pos->transmit_handle); while (NULL != (reply = pos->pending_head)) { GNUNET_CONTAINER_DLL_remove (pos->pending_head, pos->pending_tail, reply); GNUNET_free (reply); } monitor = monitor_head; while (NULL != monitor) { if (monitor->client == pos) { struct ClientMonitorRecord *next; GNUNET_free_non_null (monitor->key); next = monitor->next; GNUNET_CONTAINER_DLL_remove (monitor_head, monitor_tail, monitor); GNUNET_free (monitor); monitor = next; } else monitor = monitor->next; } GNUNET_CONTAINER_multihashmap_iterate (forward_map, &remove_client_records, pos); GNUNET_free (pos); }