/** * Remove peer from view * * @param peer the peer to remove * * @return GNUNET_OK if view contained peer and removed it successfully * GNUNET_NO if view does not contain peer */ int View_remove_peer (const struct GNUNET_PeerIdentity *peer) { uint32_t *index; uint32_t *swap_index; uint32_t last_index; if (GNUNET_NO == View_contains_peer (peer)) { return GNUNET_NO; } index = GNUNET_CONTAINER_multipeermap_get (mpm, peer); GNUNET_assert (NULL != index); last_index = View_size () - 1; if (*index < last_index) { /* Fill the 'gap' in the array with the last peer */ array[*index] = array[last_index]; GNUNET_assert (GNUNET_YES == View_contains_peer (&array[last_index])); swap_index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[last_index]); GNUNET_assert (NULL != swap_index); *swap_index = *index; GNUNET_free (index); } GNUNET_CONTAINER_multipeermap_remove_all (mpm, peer); return GNUNET_OK; }
/** * Clear the custom peer map * * @param c_peer_map the custom peer map to look in * * @return size of the map */ void View_clear () { uint32_t i; uint32_t *index; for (i = 0; 0 < View_size (); i++) { /* Need to free indices stored at peers */ GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (mpm, &array[i])); index = GNUNET_CONTAINER_multipeermap_get (mpm, &array[i]); GNUNET_assert (NULL != index); GNUNET_free (index); GNUNET_CONTAINER_multipeermap_remove_all (mpm, &array[i]); } GNUNET_assert (0 == View_size ()); }
/** * @brief Add a given @a peer to valid peers. * * If valid peers are already #num_valid_peers_max, delete a peer previously. * * @param peer the peer that is added to the valid peers. * * @return #GNUNET_YES if no other peer had to be removed * #GNUNET_NO otherwise */ static int add_valid_peer (const struct GNUNET_PeerIdentity *peer) { const struct GNUNET_PeerIdentity *rand_peer; int ret; ret = GNUNET_YES; while (GNUNET_CONTAINER_multipeermap_size (valid_peers) >= num_valid_peers_max) { rand_peer = get_random_peer_from_peermap (valid_peers); GNUNET_CONTAINER_multipeermap_remove_all (valid_peers, rand_peer); ret = GNUNET_NO; } (void) GNUNET_CONTAINER_multipeermap_put (valid_peers, peer, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); return ret; }
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; }
/** * @brief Remove peer * * @param peer the peer to clean * @return #GNUNET_YES if peer was removed * #GNUNET_NO otherwise */ int Peers_remove_peer (const struct GNUNET_PeerIdentity *peer) { struct PeerContext *peer_ctx; if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer)) { return GNUNET_NO; } peer_ctx = get_peer_ctx (peer); set_peer_flag (peer_ctx, Peers_TO_DESTROY); LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to remove peer %s\n", GNUNET_i2s (&peer_ctx->peer_id)); Peers_unset_peer_flag (peer, Peers_ONLINE); GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0); while (NULL != peer_ctx->pending_messages_head) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing unsent %s\n", peer_ctx->pending_messages_head->type); remove_pending_message (peer_ctx->pending_messages_head); } /* If we are still waiting for notification whether this peer is live * cancel the according task */ if (NULL != peer_ctx->liveliness_check_pending) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing pending liveliness check for peer %s\n", GNUNET_i2s (&peer_ctx->peer_id)); // TODO wait until cadet sets mq->cancel_impl //GNUNET_MQ_send_cancel (peer_ctx->liveliness_check_pending->ev); GNUNET_free (peer_ctx->liveliness_check_pending); peer_ctx->liveliness_check_pending = NULL; } if (NULL != peer_ctx->send_channel) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying send channel\n"); GNUNET_CADET_channel_destroy (peer_ctx->send_channel); peer_ctx->send_channel = NULL; } if (NULL != peer_ctx->recv_channel) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying recv channel\n"); GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); peer_ctx->recv_channel = NULL; } if (NULL != peer_ctx->mq) { GNUNET_MQ_destroy (peer_ctx->mq); peer_ctx->mq = NULL; } GNUNET_free (peer_ctx->send_channel_flags); GNUNET_free (peer_ctx->recv_channel_flags); if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, &peer_ctx->peer_id)) { LOG (GNUNET_ERROR_TYPE_WARNING, "removing peer from peer_map failed\n"); } GNUNET_free (peer_ctx); return GNUNET_YES; }