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; }
/** * Recusively mark peer and children as disconnected, notify client * * @param tree Tree this node belongs to * @param parent Node to be clean, potentially with children * @param cb Callback to use to notify about disconnected peers. * @param cbcls Closure for cb. */ static void tree_mark_peers_disconnected (struct MeshTunnelTree *tree, struct MeshTunnelTreeNode *parent, MeshTreeCallback cb, void *cbcls) { struct GNUNET_PeerIdentity *pi; struct GNUNET_PeerIdentity id; struct MeshTunnelTreeNode *n; for (n = parent->children_head; NULL != n; n = n->next) { tree_mark_peers_disconnected (tree, n, cb, cbcls); } if (MESH_PEER_READY == parent->status) { if (NULL != cb) cb (cbcls, parent->peer); parent->status = MESH_PEER_RECONNECTING; } /* Remove and free info about first hop */ GNUNET_PEER_resolve (parent->peer, &id); pi = GNUNET_CONTAINER_multihashmap_get (tree->first_hops, &id.hashPubKey); GNUNET_CONTAINER_multihashmap_remove_all (tree->first_hops, &id.hashPubKey); if (NULL != pi) GNUNET_free (pi); }
static int expire_blocks (void *cls, const struct GNUNET_HashCode *key, void *value) { struct Plugin *plugin = cls; struct FlatFileEntry *entry = value; struct GNUNET_TIME_Absolute now; struct GNUNET_TIME_Absolute expiration; now = GNUNET_TIME_absolute_get (); expiration = GNUNET_TIME_absolute_ntoh (entry->block->expiration_time); if (0 == GNUNET_TIME_absolute_get_difference (now, expiration).rel_value_us) { GNUNET_CONTAINER_multihashmap_remove_all (plugin->hm, key); } return GNUNET_YES; }
/** * Cache a block in the datastore. * * @param cls closure (internal context for the plugin) * @param block block to cache * @return #GNUNET_OK on success, else #GNUNET_SYSERR */ static int namecache_cache_block (void *cls, const struct GNUNET_GNSRECORD_Block *block) { struct Plugin *plugin = cls; struct GNUNET_HashCode query; struct FlatFileEntry *entry; size_t block_size; namecache_expire_blocks (plugin); GNUNET_CRYPTO_hash (&block->derived_key, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), &query); block_size = ntohl (block->purpose.size) + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) + sizeof (struct GNUNET_CRYPTO_EcdsaSignature); if (block_size > 64 * 65536) { GNUNET_break (0); return GNUNET_SYSERR; } entry = GNUNET_malloc (sizeof (struct FlatFileEntry)); entry->block = GNUNET_malloc (block_size); memcpy (entry->block, block, block_size); GNUNET_CONTAINER_multihashmap_remove_all (plugin->hm, &query); if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (plugin->hm, &query, entry, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) { GNUNET_free (entry); GNUNET_break (0); return GNUNET_SYSERR; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Caching block under derived key `%s'\n", GNUNET_h2s_full (&query)); return GNUNET_OK; }