From: Julius Bünger Date: Thu, 12 May 2016 08:58:24 +0000 (+0000) Subject: rps: keep track of valid peers in peermap X-Git-Tag: initial-import-from-subversion-38251~881 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=9f4d6acdbb43a43b648568dee596320601d04db4;p=oweals%2Fgnunet.git rps: keep track of valid peers in peermap --- diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c index 8f25b269d..8113e40b6 100644 --- a/src/rps/gnunet-service-rps.c +++ b/src/rps/gnunet-service-rps.c @@ -1385,7 +1385,7 @@ handle_peer_pull_reply (void *cls, /* Make sure we 'know' about this peer */ (void) Peers_insert_peer_check_liveliness (&peers[i]); - if (GNUNET_YES == Peers_check_peer_flag (&peers[i], Peers_VALID)) + if (GNUNET_YES == Peers_check_peer_valid (&peers[i])) { CustomPeerMap_put (pull_map, &peers[i]); } @@ -1694,7 +1694,7 @@ do_mal_round (void *cls) * That is one push per round as it will ignore more. */ Peers_insert_peer_check_liveliness (&attacked_peer); - if (GNUNET_YES == Peers_check_peer_flag (&attacked_peer, Peers_VALID)) + if (GNUNET_YES == Peers_check_peer_valid (&attacked_peer)) send_push (&attacked_peer); } @@ -1706,7 +1706,7 @@ do_mal_round (void *cls) if (GNUNET_YES == Peers_check_peer_known (&attacked_peer)) { Peers_insert_peer_check_liveliness (&attacked_peer); - if (GNUNET_YES == Peers_check_peer_flag (&attacked_peer, Peers_VALID)) + if (GNUNET_YES == Peers_check_peer_valid (&attacked_peer)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Goding to send push to attacked peer (%s)\n", @@ -2298,6 +2298,7 @@ run (void *cls, LOG (GNUNET_ERROR_TYPE_DEBUG, "Requesting peers from CADET\n"); GNUNET_CADET_get_peers (cadet_handle, &init_peer_cb, NULL); // TODO send push/pull to each of those peers? + // TODO read stored valid peers from last run peerinfo_notify_handle = GNUNET_PEERINFO_notify (cfg, GNUNET_NO, diff --git a/src/rps/gnunet-service-rps_peers.c b/src/rps/gnunet-service-rps_peers.c index 33430e51f..a6cd1b839 100644 --- a/src/rps/gnunet-service-rps_peers.c +++ b/src/rps/gnunet-service-rps_peers.c @@ -203,6 +203,16 @@ struct PeerContext */ }; +/** + * @brief Hashmap of valid peers. + */ +static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers; + +/** + * @brief Maximum number of valid peers to keep. + * TODO read from config + */ +static uint32_t num_valid_peers_max = UINT32_MAX; /** * Set of all peers to keep track of them. @@ -316,11 +326,113 @@ Peers_check_connected (const struct GNUNET_PeerIdentity *peer) return GNUNET_YES; } +/** + * @brief The closure to #get_rand_peer_iterator. + */ +struct GetRandPeerIteratorCls +{ + /** + * @brief The index of the peer to return. + * Will be decreased until 0. + * Then current peer is returned. + */ + uint32_t index; + + /** + * @brief Pointer to peer to return. + */ + const struct GNUNET_PeerIdentity *peer; +}; + +/** + * @brief Iterator function for #get_random_peer_from_peermap. + * + * Implements #GNUNET_CONTAINER_PeerMapIterator. + * Decreases the index until the index is null. + * Then returns the current peer. + * + * @param cls the #GetRandPeerIteratorCls containing index and peer + * @param peer current peer + * @param value unused + * + * @return #GNUNET_YES if we should continue to + * iterate, + * #GNUNET_NO if not. + */ +static int +get_rand_peer_iterator (void *cls, + const struct GNUNET_PeerIdentity *peer, + void *value) +{ + struct GetRandPeerIteratorCls *iterator_cls = cls; + if (0 >= iterator_cls->index) + { + iterator_cls->peer = peer; + return GNUNET_NO; + } + iterator_cls->index--; + return GNUNET_YES; +} + +/** + * @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) +{ + uint32_t rand_index; + 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; +} + +/** + * @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; +} + /** * @brief Set the peer flag to living and * call the pending operations on this peer. * - * Also sets the #Peers_VALID flag + * Also adds peer to #valid_peers. * * @param peer_ctx the #PeerContext of the peer to set live */ @@ -338,7 +450,7 @@ set_peer_live (struct PeerContext *peer_ctx) } peer = &peer_ctx->peer_id; - set_peer_flag (peer_ctx, Peers_VALID); + (void) add_valid_peer (peer); set_peer_flag (peer_ctx, Peers_ONLINE); LOG (GNUNET_ERROR_TYPE_DEBUG, "Peer %s is live and valid\n", @@ -606,8 +718,11 @@ Peers_initialise (struct GNUNET_CADET_Handle *cadet_h, 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); } +// TODO read stored valid peers + /** * @brief Delete storage of peers that was created with #Peers_initialise () */ @@ -623,8 +738,11 @@ Peers_terminate () "Iteration destroying peers was aborted.\n"); } GNUNET_CONTAINER_multipeermap_destroy (peer_map); + GNUNET_CONTAINER_multipeermap_destroy (valid_peers); } +// TODO store valid peers + /** * @brief Add peer to known peers. * @@ -672,7 +790,7 @@ Peers_insert_peer_check_liveliness (const struct GNUNET_PeerIdentity *peer) return ret; } peer_ctx = get_peer_ctx (peer); - if (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_VALID)) + if (GNUNET_NO == Peers_check_peer_valid (peer)) { check_peer_live (peer_ctx); } @@ -875,6 +993,8 @@ Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags /** * @brief Check whether we have information about the given peer. * + * FIXME probably deprecated. Make this the new _online. + * * @param peer peer in question * * @return #GNUNET_YES if peer is known @@ -886,6 +1006,22 @@ Peers_check_peer_known (const struct GNUNET_PeerIdentity *peer) return GNUNET_CONTAINER_multipeermap_contains (peer_map, peer); } +/** + * @brief Check whether @a peer is actually a peer. + * + * A valid peer is a peer that we know exists eg. we were connected to once. + * + * @param peer peer in question + * + * @return #GNUNET_YES if peer is valid + * #GNUNET_NO if peer is not valid + */ +int +Peers_check_peer_valid (const struct GNUNET_PeerIdentity *peer) +{ + return GNUNET_CONTAINER_multipeermap_contains (valid_peers, peer); +} + /** * @brief Indicate that we want to send to the other peer * diff --git a/src/rps/gnunet-service-rps_peers.h b/src/rps/gnunet-service-rps_peers.h index 06e6fa89e..79db8185b 100644 --- a/src/rps/gnunet-service-rps_peers.h +++ b/src/rps/gnunet-service-rps_peers.h @@ -42,11 +42,6 @@ enum Peers_PeerFlags /* IN_OWN_SAMPLER_LIST = 0x04, unneeded? */ /* IN_OWN_GOSSIP_LIST = 0x08, unneeded? */ - /** - * We set this bit when we can be sure the other peer is/was live. - */ - Peers_VALID = 0x10, - /** * We set this bit when we know the peer is online. */ @@ -236,6 +231,8 @@ Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags /** * @brief Check whether we have information about the given peer. * + * FIXME probably deprecated. Make this the new _online. + * * @param peer peer in question * * @return #GNUNET_YES if peer is known @@ -244,6 +241,19 @@ Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags int Peers_check_peer_known (const struct GNUNET_PeerIdentity *peer); +/** + * @brief Check whether @a peer is actually a peer. + * + * A valid peer is a peer that we know exists eg. we were connected to once. + * + * @param peer peer in question + * + * @return #GNUNET_YES if peer is valid + * #GNUNET_NO if peer is not valid + */ +int +Peers_check_peer_valid (const struct GNUNET_PeerIdentity *peer); + /** * @brief Indicate that we want to send to the other peer * diff --git a/src/rps/test_service_rps_peers.c b/src/rps/test_service_rps_peers.c index f5191facc..264a63e41 100644 --- a/src/rps/test_service_rps_peers.c +++ b/src/rps/test_service_rps_peers.c @@ -93,30 +93,15 @@ check () Peers_insert_peer (&k1); CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_PULL_REPLY_PENDING)); - CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_VALID)); CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_ONLINE)); CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_TO_DESTROY)); - Peers_set_peer_flag (&k1, Peers_VALID); - CHECK (GNUNET_YES == Peers_check_peer_flag (&k1, Peers_VALID)); CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_ONLINE)); - Peers_unset_peer_flag (&k1, Peers_VALID); - CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_VALID)); - Peers_set_peer_flag (&k1, Peers_VALID); Peers_set_peer_flag (&k1, Peers_ONLINE); - CHECK (GNUNET_YES == Peers_check_peer_flag (&k1, Peers_VALID)); CHECK (GNUNET_YES == Peers_check_peer_flag (&k1, Peers_ONLINE)); - CHECK (GNUNET_YES == Peers_check_peer_flag (&k1, - Peers_ONLINE | Peers_VALID)); CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_TO_DESTROY)); - Peers_unset_peer_flag (&k1, Peers_VALID); - CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_VALID)); CHECK (GNUNET_YES == Peers_check_peer_flag (&k1, Peers_ONLINE)); - CHECK (GNUNET_YES == Peers_check_peer_flag (&k1, - Peers_ONLINE | Peers_VALID)); - CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, - Peers_ONLINE & Peers_VALID)); CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_TO_DESTROY)); /* Check send intention */