-rps: merge duplicate functions
[oweals/gnunet.git] / src / rps / gnunet-service-rps_peers.h
index d1d1302060ea7a0a41f0a18dbbfd565281aab37e..abb5d831a7ab0d7266a3e54b6ac7f10fedef308d 100644 (file)
 */
 
 /**
- * @file rps/gnunet-service-rps_peers.c
+ * @file rps/gnunet-service-rps_peers.h
  * @brief utilities for managing (information about) peers
  * @author Julius Bünger
  */
 #include "gnunet_util_lib.h"
 #include <inttypes.h>
+#include "gnunet_cadet_service.h"
 
 
 /**
- * Peer map to store peers with specialised use-cases (push_list, pull_list,
- * view, ...)
+ * Different flags indicating the status of another peer.
+ */
+enum Peers_PeerFlags
+{
+  /**
+   * If we are waiting for a reply from that peer (sent a pull request).
+   */
+  Peers_PULL_REPLY_PENDING   = 0x01,
+
+  /* IN_OTHER_GOSSIP_LIST = 0x02, unneeded? */
+  /* IN_OWN_SAMPLER_LIST  = 0x04, unneeded? */
+  /* IN_OWN_GOSSIP_LIST   = 0x08, unneeded? */
+
+  /**
+   * We set this bit when we know the peer is online.
+   */
+  Peers_ONLINE               = 0x20,
+
+  /**
+   * We set this bit when we are going to destroy the channel to this peer.
+   * When cleanup_channel is called, we know that we wanted to destroy it.
+   * Otherwise the channel to the other peer was destroyed.
+   */
+  Peers_TO_DESTROY           = 0x40,
+};
+
+/**
+ * Keep track of the status of a channel.
  *
- * It is aimed for use as unordered list-like structures that can be indexed.
- * Main use-case:
+ * This is needed in order to know what to do with a channel when it's
+ * destroyed.
+ */
+enum Peers_ChannelFlags
+{
+  /**
+   * We destroyed the channel because the other peer established a second one.
+   */
+  Peers_CHANNEL_ESTABLISHED_TWICE = 0x1,
+
+  /**
+   * The channel was removed because it was not needed any more. This should be
+   * the sending channel.
+   */
+  Peers_CHANNEL_CLEAN = 0x2,
+};
+
+/**
+ * @brief The role of a channel. Sending or receiving.
+ */
+enum Peers_ChannelRole
+{
+  /**
+   * Channel is used for sending
+   */
+  Peers_CHANNEL_ROLE_SENDING   = 0x01,
+
+  /**
+   * Channel is used for receiving
+   */
+  Peers_CHANNEL_ROLE_RECEIVING = 0x02,
+};
+
+/**
+ * @brief Functions of this type can be used to be stored at a peer for later execution.
  *
- *  permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG,
- *                                         CustomPeerMap_size (peer_map));
- *  for (i = 0; i < some_border; i++)
- *    some_array[i] = *CustomPeerMap_get_peer_by_index (peer_map, permut[i]);
- *  for (i = some_border; i < CustomPeerMap_size (peer_map); i++)
- *    other_array[i-some_border] =
- *      *CustomPeerMap_get_peer_by_index (peer_map, permut[i]);
+ * @param cls closure
+ * @param peer peer to execute function on
+ */
+typedef void (* PeerOp) (void *cls, const struct GNUNET_PeerIdentity *peer);
+
+/**
+ * @brief Iterator over valid peers.
  *
- * This list is expected to
- * - be altered in small steps frequently
- * - be cleared regularily
- * - often being queried whether a peer is contained
- * - alter indices of peers
- * - contain continous indices 0 <= i < len
- * - not contain duplicate peers
+ * @param cls closure
+ * @param peer current public peer id
+ * @return #GNUNET_YES if we should continue to
+ *         iterate,
+ *         #GNUNET_NO if not.
  */
-struct CustomPeerMap;
+typedef int
+(*PeersIterator) (void *cls,
+                  const struct GNUNET_PeerIdentity *peer);
 
+/**
+ * @brief Initialise storage of peers
+ *
+ * @param fn_valid_peers filename of the file used to store valid peer ids
+ * @param cadet_h cadet handle
+ * @param own_id own peer identity
+ */
+void
+Peers_initialise (char* fn_valid_peers,
+                  struct GNUNET_CADET_Handle *cadet_h,
+                  const struct GNUNET_PeerIdentity *own_id);
 
 /**
- * Create an empty peermap.
+ * @brief Delete storage of peers that was created with #Peers_initialise ()
+ */
+void
+Peers_terminate ();
+
+
+/**
+ * @brief Get all currently known, valid peer ids.
  *
- * @param len the initial length for the internal maps
+ * @param it function to call on each peer id
+ * @param it_cls extra argument to @a it
+ * @return the number of key value pairs processed,
+ *         #GNUNET_SYSERR if it aborted iteration
+ */
+int
+Peers_get_valid_peers (PeersIterator iterator,
+                       void *it_cls);
+
+/**
+ * @brief Add peer to known peers.
+ *
+ * This function is called on new peer_ids from 'external' sources
+ * (client seed, cadet get_peers(), ...)
  *
- * @return the newly created custom peer map
+ * @param peer the new #GNUNET_PeerIdentity
+ *
+ * @return #GNUNET_YES if peer was inserted
+ *         #GNUNET_NO  otherwise (if peer was already known or
+ *                     peer was #own_identity)
  */
-struct CustomPeerMap *
-CustomPeerMap_create (unsigned int len);
+int
+Peers_insert_peer (const struct GNUNET_PeerIdentity *peer);
 
 /**
- * Get the size of the custom peer map
+ * @brief Try connecting to a peer to see whether it is online
  *
- * @param c_peer_map the custom peer map to look in
+ * If not known yet, insert into known peers
  *
- * @return size of the map
+ * @param peer the peer whose liveliness is to be checked
+ * @return #GNUNET_YES if peer had to be inserted
+ *         #GNUNET_NO  otherwise (if peer was already known or
+ *                     peer was #own_identity)
+ */
+int
+Peers_issue_peer_liveliness_check (const struct GNUNET_PeerIdentity *peer);
+
+/**
+ * @brief Remove unecessary data
+ * 
+ * If the other peer is not intending to send messages, we have messages pending
+ * to be sent to this peer and we are not waiting for a reply, remove the
+ * information about it (its #PeerContext).
+ *
+ * @param peer the peer to clean
+ * @return #GNUNET_YES if peer was removed
+ *         #GNUNET_NO  otherwise
+ */
+int
+Peers_clean_peer (const struct GNUNET_PeerIdentity *peer);
+
+/**
+ * @brief Remove peer
+ * 
+ * @param peer the peer to clean
+ * @return #GNUNET_YES if peer was removed
+ *         #GNUNET_NO  otherwise
  */
 int
-CustomPeerMap_size (const struct CustomPeerMap *c_peer_map);
+Peers_remove_peer (const struct GNUNET_PeerIdentity *peer);
 
 /**
- * Insert peer into the custom peer map
+ * @brief set flags on a given peer.
  *
- * @param c_peer_map the custom peer map to insert peer
- * @param peer the peer to insert
+ * @param peer the peer to set flags on
+ * @param flags the flags
+ */
+void
+Peers_set_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags);
+
+/**
+ * @brief unset flags on a given peer.
  *
- * @return GNUNET_OK if map did not contain peer previously
- *         GNUNET_NO if map did contain peer previously
+ * @param peer the peer to unset flags on
+ * @param flags the flags
+ */
+void
+Peers_unset_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags);
+
+/**
+ * @brief Check whether flags on a peer are set.
+ *
+ * @param peer the peer to check the flag of
+ * @param flags the flags to check
+ *
+ * @return #GNUNET_YES if all given flags are set
+ *         ##GNUNET_NO  otherwise
  */
 int
-CustomPeerMap_put (const struct CustomPeerMap *c_peer_map,
-                   const struct GNUNET_PeerIdentity *peer);
+Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum Peers_PeerFlags flags);
+
 
 /**
- * Check whether custom peer map contains a peer
+ * @brief set flags on a given channel.
  *
- * @param c_peer_map the custom peer map to look in
- * @param peer the peer to check for
+ * @param channel the channel to set flags on
+ * @param flags the flags
+ */
+void
+Peers_set_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags);
+
+/**
+ * @brief unset flags on a given channel.
+ *
+ * @param channel the channel to unset flags on
+ * @param flags the flags
+ */
+void
+Peers_unset_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags);
+
+/**
+ * @brief Check whether flags on a channel are set.
+ *
+ * @param channel the channel to check the flag of
+ * @param flags the flags to check
+ *
+ * @return #GNUNET_YES if all given flags are set
+ *         #GNUNET_NO  otherwise
+ */
+int
+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
+ *         #GNUNET_NO  if peer is not knwon
+ */
+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
  *
- * @return GNUNET_OK if map contains peer
- *         GNUNET_NO  otherwise
+ * This establishes a sending channel
+ *
+ * @param peer the peer to establish channel to
+ */
+void
+Peers_indicate_sending_intention (const struct GNUNET_PeerIdentity *peer);
+
+/**
+ * @brief Check whether other peer has the intention to send/opened channel
+ *        towars us
+ *
+ * @param peer the peer in question
+ *
+ * @return #GNUNET_YES if peer has the intention to send
+ *         #GNUNET_NO  otherwise
  */
 int
-CustomPeerMap_contains_peer (const struct CustomPeerMap *c_peer_map,
-                             const struct GNUNET_PeerIdentity *peer);
+Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer);
+
+/**
+ * Handle the channel a peer opens to us.
+ *
+ * @param cls The closure
+ * @param channel The channel the peer wants to establish
+ * @param initiator The peer's peer ID
+ * @param port The port the channel is being established over
+ * @param options Further options
+ *
+ * @return initial channel context for the channel
+ *         (can be NULL -- that's not an error)
+ */
+void *
+Peers_handle_inbound_channel (void *cls,
+                              struct GNUNET_CADET_Channel *channel,
+                              const struct GNUNET_PeerIdentity *initiator,
+                              uint32_t port,
+                              enum GNUNET_CADET_ChannelOption options);
 
 /**
- * Remove peer from custom peer map
+ * @brief Check whether a sending channel towards the given peer exists
  *
- * @param c_peer_map the custom peer map to remove the peer from
- * @param peer the peer to remove
+ * @param peer the peer to check for
  *
- * @return GNUNET_OK if map contained peer and removed it successfully
- *         GNUNET_NO if map does not contain peer
+ * @return #GNUNET_YES if a sending channel towards that peer exists
+ *         #GNUNET_NO  otherwise
  */
 int
-CustomPeerMap_remove_peer (const struct CustomPeerMap *c_peer_map,
-                           const struct GNUNET_PeerIdentity *peer);
+Peers_check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer);
 
 /**
- * Get a peer by index
+ * @brief check whether the given channel is the sending channel of the given
+ *        peer
  *
- * @param c_peer_map the custom peer map to look in
- * @param index the index of the peer to get
+ * @param peer the peer in question
+ * @param channel the channel to check for
+ * @param role either #Peers_CHANNEL_ROLE_SENDING, or
+ *                    #Peers_CHANNEL_ROLE_RECEIVING
  *
- * @return peer to the corresponding index.
- *         if this index is not known, return NULL
+ * @return #GNUNET_YES if the given chennel is the sending channel of the peer
+ *         #GNUNET_NO  otherwise
  */
-struct GNUNET_PeerIdentity *
-CustomPeerMap_get_peer_by_index (const struct CustomPeerMap *c_peer_map,
-                                 uint32_t index);
+int
+Peers_check_channel_role (const struct GNUNET_PeerIdentity *peer,
+                          const struct GNUNET_CADET_Channel *channel,
+                          enum Peers_ChannelRole role);
 
 /**
- * Remove peer from custom peer map by index
+ * @brief Destroy the send channel of a peer e.g. stop indicating a sending
+ *        intention to another peer
  *
- * @param c_peer_map the custom peer map to remove the peer from
- * @param index the index of the peer to remove
+ * If there is also no channel to receive messages from that peer, remove it
+ * from the peermap.
  *
- * @return GNUNET_OK if map contained peer and removed it successfully
- *         GNUNET_NO if map does not contain (index of) peer
+ * @peer the peer identity of the peer whose sending channel to destroy
+ * @return #GNUNET_YES if channel was destroyed
+ *         #GNUNET_NO  otherwise
  */
 int
-CustomPeerMap_remove_peer_by_index (const struct CustomPeerMap *c_peer_map,
-                                    uint32_t index);
+Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer);
 
 /**
- * Clear the custom peer map
+ * This is called when a channel is destroyed.
  *
- * @param c_peer_map the custom peer map to look in
+ * Removes peer completely from our knowledge if the send_channel was destroyed
+ * Otherwise simply delete the recv_channel
  *
- * @return size of the map
+ * @param cls The closure
+ * @param channel The channel being closed
+ * @param channel_ctx The context associated with this channel
  */
 void
-CustomPeerMap_clear (const struct CustomPeerMap *c_peer_map);
+Peers_cleanup_destroyed_channel (void *cls,
+                                 const struct GNUNET_CADET_Channel *channel,
+                                 void *channel_ctx);
 
 /**
- * Destroy peermap.
+ * @brief Send a message to another peer.
+ *
+ * Keeps track about pending messages so they can be properly removed when the
+ * peer is destroyed.
  *
- * @param c_peer_map the map to destroy
+ * @param peer receeiver of the message
+ * @param ev envelope of the message
+ * @param type type of the message
  */
 void
-CustomPeerMap_destroy (struct CustomPeerMap *c_peer_map);
+Peers_send_message (const struct GNUNET_PeerIdentity *peer,
+                    struct GNUNET_MQ_Envelope *ev,
+                    const char *type);
+
+/**
+ * @brief Schedule a operation on given peer
+ *
+ * Avoids scheduling an operation twice.
+ *
+ * @param peer the peer we want to schedule the operation for once it gets live
+ *
+ * @return #GNUNET_YES if the operation was scheduled
+ *         #GNUNET_NO  otherwise
+ */
+int
+Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer,
+                          const PeerOp peer_op);
 
-/* end of gnunet-service-rps_peers.c */
+/* end of gnunet-service-rps_peers.h */