/* 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]);
}
* 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);
}
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",
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,
*/
};
+/**
+ * @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.
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
*/
}
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",
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 ()
*/
"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.
*
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);
}
/**
* @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
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
*
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 */