gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnunet] branch master updated (c6f178907 -> 9b6545e5f)


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated (c6f178907 -> 9b6545e5f)
Date: Fri, 29 Dec 2017 15:42:19 +0100

This is an automated email from the git hooks/post-receive script.

julius-buenger pushed a change to branch master
in repository gnunet.

    from c6f178907 Merge branch 'master' of gn:gnunet
     new f2b64da6f refactor rps code
     new a8b68db5e rps: flagging channels while destruction
     new 9b6545e5f rps: move handlers struct

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/rps/.gitignore                 |    1 -
 src/rps/Makefile.am                |    9 -
 src/rps/gnunet-service-rps.c       | 1776 +++++++++++++++++++++++++++++++++++-
 src/rps/gnunet-service-rps_peers.c | 1701 ----------------------------------
 src/rps/gnunet-service-rps_peers.h |  437 ---------
 src/rps/rps.h                      |   96 ++
 src/rps/test_service_rps_peers.c   |  137 ---
 7 files changed, 1850 insertions(+), 2307 deletions(-)
 delete mode 100644 src/rps/gnunet-service-rps_peers.c
 delete mode 100644 src/rps/gnunet-service-rps_peers.h
 delete mode 100644 src/rps/test_service_rps_peers.c

diff --git a/src/rps/.gitignore b/src/rps/.gitignore
index e45356eda..c8068912b 100644
--- a/src/rps/.gitignore
+++ b/src/rps/.gitignore
@@ -9,7 +9,6 @@ test_rps_seed_big
 test_rps_seed_request
 test_rps_single_req
 test_service_rps_custommap
-test_service_rps_peers
 test_service_rps_sampler_elem
 test_service_rps_view
 test_rps_churn
diff --git a/src/rps/Makefile.am b/src/rps/Makefile.am
index 68424557b..de3469254 100644
--- a/src/rps/Makefile.am
+++ b/src/rps/Makefile.am
@@ -49,7 +49,6 @@ endif
 gnunet_service_rps_SOURCES = \
  gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \
  gnunet-service-rps_sampler.h gnunet-service-rps_sampler.c \
- gnunet-service-rps_peers.h gnunet-service-rps_peers.c \
  gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \
  gnunet-service-rps_view.h gnunet-service-rps_view.c \
  rps-test_util.h rps-test_util.c \
@@ -73,7 +72,6 @@ if HAVE_TESTING
 check_PROGRAMS = \
  test_service_rps_view \
  test_service_rps_custommap \
- test_service_rps_peers \
  test_service_rps_sampler_elem \
  test_rps_malicious_1 \
  test_rps_malicious_2 \
@@ -106,13 +104,6 @@ test_service_rps_view_SOURCES = \
   test_service_rps_view.c
 test_service_rps_view_LDADD = $(top_builddir)/src/util/libgnunetutil.la
 
-test_service_rps_peers_SOURCES = \
-  gnunet-service-rps_peers.h gnunet-service-rps_peers.c \
-  test_service_rps_peers.c
-test_service_rps_peers_LDADD = \
-  $(top_builddir)/src/util/libgnunetutil.la \
-  $(top_builddir)/src/cadet/libgnunetcadet.la
-
 test_service_rps_custommap_SOURCES = \
   gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \
   test_service_rps_custommap.c
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index bea3df233..ec70075cf 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -33,7 +33,6 @@
 #include "rps-test_util.h"
 #include "gnunet-service-rps_sampler.h"
 #include "gnunet-service-rps_custommap.h"
-#include "gnunet-service-rps_peers.h"
 #include "gnunet-service-rps_view.h"
 
 #include <math.h>
@@ -66,6 +65,1728 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
 static struct GNUNET_PeerIdentity own_identity;
 
 
+
+/***********************************************************************
+ * Old gnunet-service-rps_peers.c
+***********************************************************************/
+
+/**
+ * Set a peer flag of given peer context.
+ */
+#define set_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) |= (mask))
+
+/**
+ * Get peer flag of given peer context.
+ */
+#define check_peer_flag_set(peer_ctx, mask)\
+  ((peer_ctx->peer_flags) & (mask) ? GNUNET_YES : GNUNET_NO)
+
+/**
+ * Unset flag of given peer context.
+ */
+#define unset_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) &= ~(mask))
+
+/**
+ * Set a channel flag of given channel context.
+ */
+#define set_channel_flag(channel_flags, mask) ((*channel_flags) |= (mask))
+
+/**
+ * Get channel flag of given channel context.
+ */
+#define check_channel_flag_set(channel_flags, mask)\
+  ((*channel_flags) & (mask) ? GNUNET_YES : GNUNET_NO)
+
+/**
+ * Unset flag of given channel context.
+ */
+#define unset_channel_flag(channel_flags, mask) ((*channel_flags) &= ~(mask))
+
+
+
+/**
+ * Pending operation on peer consisting of callback and closure
+ *
+ * When an operation cannot be executed right now this struct is used to store
+ * the callback and closure for later execution.
+ */
+struct PeerPendingOp
+{
+  /**
+   * Callback
+   */
+  PeerOp op;
+
+  /**
+   * Closure
+   */
+  void *op_cls;
+};
+
+/**
+ * List containing all messages that are yet to be send
+ *
+ * This is used to keep track of all messages that have not been sent yet. When
+ * a peer is to be removed the pending messages can be removed properly.
+ */
+struct PendingMessage
+{
+  /**
+   * DLL next, prev
+   */
+  struct PendingMessage *next;
+  struct PendingMessage *prev;
+
+  /**
+   * The envelope to the corresponding message
+   */
+  struct GNUNET_MQ_Envelope *ev;
+
+  /**
+   * The corresponding context
+   */
+  struct PeerContext *peer_ctx;
+
+  /**
+   * The message type
+   */
+  const char *type;
+};
+
+/**
+ * Struct used to keep track of other peer's status
+ *
+ * This is stored in a multipeermap.
+ * It contains information such as cadet channels, a message queue for sending,
+ * status about the channels, the pending operations on this peer and some 
flags
+ * about the status of the peer itself. (live, valid, ...)
+ */
+struct PeerContext
+{
+  /**
+   * Message queue open to client
+   */
+  struct GNUNET_MQ_Handle *mq;
+
+  /**
+   * Channel open to client.
+   */
+  struct GNUNET_CADET_Channel *send_channel;
+
+  /**
+   * Flags to the sending channel
+   */
+  uint32_t *send_channel_flags;
+
+  /**
+   * Channel open from client.
+   */
+  struct GNUNET_CADET_Channel *recv_channel; // unneeded?
+
+  /**
+   * Flags to the receiving channel
+   */
+  uint32_t *recv_channel_flags;
+
+  /**
+   * Array of pending operations on this peer.
+   */
+  struct PeerPendingOp *pending_ops;
+
+  /**
+   * Handle to the callback given to cadet_ntfy_tmt_rdy()
+   *
+   * To be canceled on shutdown.
+   */
+  struct PendingMessage *liveliness_check_pending;
+
+  /**
+   * Number of pending operations.
+   */
+  unsigned int num_pending_ops;
+
+  /**
+   * Identity of the peer
+   */
+  struct GNUNET_PeerIdentity peer_id;
+
+  /**
+   * Flags indicating status of peer
+   */
+  uint32_t peer_flags;
+
+  /**
+   * Last time we received something from that peer.
+   */
+  struct GNUNET_TIME_Absolute last_message_recv;
+
+  /**
+   * Last time we received a keepalive message.
+   */
+  struct GNUNET_TIME_Absolute last_keepalive;
+
+  /**
+   * DLL with all messages that are yet to be sent
+   */
+  struct PendingMessage *pending_messages_head;
+  struct PendingMessage *pending_messages_tail;
+
+  /**
+   * This is pobably followed by 'statistical' data (when we first saw
+   * him, how did we get his ID, how many pushes (in a timeinterval),
+   * ...)
+   */
+};
+
+/**
+ * @brief Closure to #valid_peer_iterator
+ */
+struct PeersIteratorCls
+{
+  /**
+   * Iterator function
+   */
+  PeersIterator iterator;
+
+  /**
+   * Closure to iterator
+   */
+  void *cls;
+};
+
+/**
+ * @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;
+
+/**
+ * @brief Filename of the file that stores the valid peers persistently.
+ */
+static char *filename_valid_peers;
+
+/**
+ * Set of all peers to keep track of them.
+ */
+static struct GNUNET_CONTAINER_MultiPeerMap *peer_map;
+
+/**
+ * Cadet handle.
+ */
+static struct GNUNET_CADET_Handle *cadet_handle;
+
+
+
+/**
+ * @brief Get the #PeerContext associated with a peer
+ *
+ * @param peer the peer id
+ *
+ * @return the #PeerContext
+ */
+static struct PeerContext *
+get_peer_ctx (const struct GNUNET_PeerIdentity *peer)
+{
+  struct PeerContext *ctx;
+  int ret;
+
+  ret = GNUNET_CONTAINER_multipeermap_contains (peer_map, peer);
+  GNUNET_assert (GNUNET_YES == ret);
+  ctx = GNUNET_CONTAINER_multipeermap_get (peer_map, peer);
+  GNUNET_assert (NULL != ctx);
+  return ctx;
+}
+
+int
+Peers_check_peer_known (const struct GNUNET_PeerIdentity *peer);
+
+/**
+ * @brief Create a new #PeerContext and insert it into the peer map
+ *
+ * @param peer the peer to create the #PeerContext for
+ *
+ * @return the #PeerContext
+ */
+static struct PeerContext *
+create_peer_ctx (const struct GNUNET_PeerIdentity *peer)
+{
+  struct PeerContext *ctx;
+  int ret;
+
+  GNUNET_assert (GNUNET_NO == Peers_check_peer_known (peer));
+
+  ctx = GNUNET_new (struct PeerContext);
+  ctx->peer_id = *peer;
+  ctx->send_channel_flags = GNUNET_new (uint32_t);
+  ctx->recv_channel_flags = GNUNET_new (uint32_t);
+  ret = GNUNET_CONTAINER_multipeermap_put (peer_map, peer, ctx,
+      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+  GNUNET_assert (GNUNET_OK == ret);
+  return ctx;
+}
+
+
+/**
+ * @brief Create or get a #PeerContext
+ *
+ * @param peer the peer to get the associated context to
+ *
+ * @return the context
+ */
+static struct PeerContext *
+create_or_get_peer_ctx (const struct GNUNET_PeerIdentity *peer)
+{
+  if (GNUNET_NO == Peers_check_peer_known (peer))
+  {
+    return create_peer_ctx (peer);
+  }
+  return get_peer_ctx (peer);
+}
+
+void
+Peers_unset_peer_flag (const struct GNUNET_PeerIdentity *peer, enum 
Peers_PeerFlags flags);
+
+void
+Peers_set_peer_flag (const struct GNUNET_PeerIdentity *peer, enum 
Peers_PeerFlags flags);
+
+/**
+ * @brief Check whether we have a connection to this @a peer
+ *
+ * Also sets the #Peers_ONLINE flag accordingly
+ *
+ * @param peer the peer in question
+ *
+ * @return #GNUNET_YES if we are connected
+ *         #GNUNET_NO  otherwise
+ */
+int
+Peers_check_connected (const struct GNUNET_PeerIdentity *peer)
+{
+  const struct PeerContext *peer_ctx;
+
+  /* If we don't know about this peer we don't know whether it's online */
+  if (GNUNET_NO == Peers_check_peer_known (peer))
+  {
+    return GNUNET_NO;
+  }
+  /* Get the context */
+  peer_ctx = get_peer_ctx (peer);
+  /* If we have no channel to this peer we don't know whether it's online */
+  if ( (NULL == peer_ctx->send_channel) &&
+       (NULL == peer_ctx->recv_channel) )
+  {
+    Peers_unset_peer_flag (peer, Peers_ONLINE);
+    return GNUNET_NO;
+  }
+  /* Otherwise (if we have a channel, we know that it's online */
+  Peers_set_peer_flag (peer, Peers_ONLINE);
+  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)
+{
+  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 adds peer to #valid_peers.
+ *
+ * @param peer_ctx the #PeerContext of the peer to set live
+ */
+static void
+set_peer_live (struct PeerContext *peer_ctx)
+{
+  struct GNUNET_PeerIdentity *peer;
+  unsigned int i;
+
+  peer = &peer_ctx->peer_id;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+      "Peer %s is live and valid, calling %i pending operations on it\n",
+      GNUNET_i2s (peer),
+      peer_ctx->num_pending_ops);
+
+  if (NULL != peer_ctx->liveliness_check_pending)
+  {
+    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;
+  }
+
+  (void) add_valid_peer (peer);
+  set_peer_flag (peer_ctx, Peers_ONLINE);
+
+  /* Call pending operations */
+  for (i = 0; i < peer_ctx->num_pending_ops; i++)
+  {
+    peer_ctx->pending_ops[i].op (peer_ctx->pending_ops[i].op_cls, peer);
+  }
+  GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0);
+}
+
+static void
+cleanup_destroyed_channel (void *cls,
+                           const struct GNUNET_CADET_Channel *channel);
+
+/* Declaration of handlers */
+static void
+handle_peer_check (void *cls,
+                   const struct GNUNET_MessageHeader *msg);
+
+static void
+handle_peer_push (void *cls,
+                  const struct GNUNET_MessageHeader *msg);
+
+static void
+handle_peer_pull_request (void *cls,
+                          const struct GNUNET_MessageHeader *msg);
+
+static int
+check_peer_pull_reply (void *cls,
+                       const struct GNUNET_RPS_P2P_PullReplyMessage *msg);
+
+static void
+handle_peer_pull_reply (void *cls,
+                        const struct GNUNET_RPS_P2P_PullReplyMessage *msg);
+
+/* End declaration of handlers */
+
+
+/**
+ * @brief Get the channel of a peer. If not existing, create.
+ *
+ * @param peer the peer id
+ * @return the #GNUNET_CADET_Channel used to send data to @a peer
+ */
+struct GNUNET_CADET_Channel *
+get_channel (const struct GNUNET_PeerIdentity *peer)
+{
+  struct PeerContext *peer_ctx;
+  struct GNUNET_HashCode port;
+  /* There exists a copy-paste-clone in run() */
+  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
+    GNUNET_MQ_hd_fixed_size (peer_check,
+                             GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE,
+                             struct GNUNET_MessageHeader,
+                             NULL),
+    GNUNET_MQ_hd_fixed_size (peer_push,
+                             GNUNET_MESSAGE_TYPE_RPS_PP_PUSH,
+                             struct GNUNET_MessageHeader,
+                             NULL),
+    GNUNET_MQ_hd_fixed_size (peer_pull_request,
+                             GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST,
+                             struct GNUNET_MessageHeader,
+                             NULL),
+    GNUNET_MQ_hd_var_size (peer_pull_reply,
+                           GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY,
+                           struct GNUNET_RPS_P2P_PullReplyMessage,
+                           NULL),
+    GNUNET_MQ_handler_end ()
+  };
+
+
+  peer_ctx = get_peer_ctx (peer);
+  if (NULL == peer_ctx->send_channel)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Trying to establish channel to peer %s\n",
+         GNUNET_i2s (peer));
+    GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS,
+                        strlen (GNUNET_APPLICATION_PORT_RPS),
+                        &port);
+    peer_ctx->send_channel =
+      GNUNET_CADET_channel_create (cadet_handle,
+                                   (struct GNUNET_PeerIdentity *) peer, /* 
context */
+                                   peer,
+                                   &port,
+                                   GNUNET_CADET_OPTION_RELIABLE,
+                                   NULL, /* WindowSize handler */
+                                   cleanup_destroyed_channel, /* Disconnect 
handler */
+                                   cadet_handlers);
+  }
+  GNUNET_assert (NULL != peer_ctx->send_channel);
+  return peer_ctx->send_channel;
+}
+
+
+/**
+ * Get the message queue (#GNUNET_MQ_Handle) of a specific peer.
+ *
+ * If we already have a message queue open to this client,
+ * simply return it, otherways create one.
+ *
+ * @param peer the peer to get the mq to
+ * @return the #GNUNET_MQ_Handle
+ */
+static struct GNUNET_MQ_Handle *
+get_mq (const struct GNUNET_PeerIdentity *peer)
+{
+  struct PeerContext *peer_ctx;
+
+  peer_ctx = get_peer_ctx (peer);
+
+  if (NULL == peer_ctx->mq)
+  {
+    (void) get_channel (peer);
+    peer_ctx->mq = GNUNET_CADET_get_mq (peer_ctx->send_channel);
+  }
+  return peer_ctx->mq;
+}
+
+
+/**
+ * @brief This is called in response to the first message we sent as a
+ * liveliness check.
+ *
+ * @param cls #PeerContext of peer with pending liveliness check
+ */
+static void
+mq_liveliness_check_successful (void *cls)
+{
+  struct PeerContext *peer_ctx = cls;
+
+  if (NULL != peer_ctx->liveliness_check_pending)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+        "Liveliness check for peer %s was successfull\n",
+        GNUNET_i2s (&peer_ctx->peer_id));
+    GNUNET_free (peer_ctx->liveliness_check_pending);
+    peer_ctx->liveliness_check_pending = NULL;
+    set_peer_live (peer_ctx);
+  }
+}
+
+/**
+ * Issue a check whether peer is live
+ *
+ * @param peer_ctx the context of the peer
+ */
+static void
+check_peer_live (struct PeerContext *peer_ctx)
+{
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Get informed about peer %s getting live\n",
+       GNUNET_i2s (&peer_ctx->peer_id));
+
+  struct GNUNET_MQ_Handle *mq;
+  struct GNUNET_MQ_Envelope *ev;
+
+  ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE);
+  peer_ctx->liveliness_check_pending = GNUNET_new (struct PendingMessage);
+  peer_ctx->liveliness_check_pending->ev = ev;
+  peer_ctx->liveliness_check_pending->peer_ctx = peer_ctx;
+  peer_ctx->liveliness_check_pending->type = "Check liveliness";
+  mq = get_mq (&peer_ctx->peer_id);
+  GNUNET_MQ_notify_sent (ev,
+                         mq_liveliness_check_successful,
+                         peer_ctx);
+  GNUNET_MQ_send (mq, ev);
+}
+
+/**
+ * @brief Add an envelope to a message passed to mq to list of pending messages
+ *
+ * @param peer peer the message was sent to
+ * @param ev envelope to the message
+ * @param type type of the message to be sent
+ * @return pointer to pending message
+ */
+static struct PendingMessage *
+insert_pending_message (const struct GNUNET_PeerIdentity *peer,
+                        struct GNUNET_MQ_Envelope *ev,
+                        const char *type)
+{
+  struct PendingMessage *pending_msg;
+  struct PeerContext *peer_ctx;
+
+  peer_ctx = get_peer_ctx (peer);
+  pending_msg = GNUNET_new (struct PendingMessage);
+  pending_msg->ev = ev;
+  pending_msg->peer_ctx = peer_ctx;
+  pending_msg->type = type;
+  GNUNET_CONTAINER_DLL_insert (peer_ctx->pending_messages_head,
+                               peer_ctx->pending_messages_tail,
+                               pending_msg);
+  return pending_msg;
+}
+
+
+/**
+ * @brief Remove a pending message from the respective DLL
+ *
+ * @param pending_msg the pending message to remove
+ * @param cancel cancel the pending message, too
+ */
+static void
+remove_pending_message (struct PendingMessage *pending_msg, int cancel)
+{
+  struct PeerContext *peer_ctx;
+
+  peer_ctx = pending_msg->peer_ctx;
+  GNUNET_assert (NULL != peer_ctx);
+  GNUNET_CONTAINER_DLL_remove (peer_ctx->pending_messages_head,
+                               peer_ctx->pending_messages_tail,
+                               pending_msg);
+  // TODO wait for the cadet implementation of message cancellation
+  //if (GNUNET_YES == cancel)
+  //{
+  //  GNUNET_MQ_send_cancel (pending_msg->ev);
+  //}
+  GNUNET_free (pending_msg);
+}
+
+
+/**
+ * @brief Check whether function of type #PeerOp was already scheduled
+ *
+ * The array with pending operations will probably never grow really big, so
+ * iterating over it should be ok.
+ *
+ * @param peer the peer to check
+ * @param peer_op the operation (#PeerOp) on the peer
+ *
+ * @return #GNUNET_YES if this operation is scheduled on that peer
+ *         #GNUNET_NO  otherwise
+ */
+static int
+check_operation_scheduled (const struct GNUNET_PeerIdentity *peer,
+                           const PeerOp peer_op)
+{
+  const struct PeerContext *peer_ctx;
+  unsigned int i;
+
+  peer_ctx = get_peer_ctx (peer);
+  for (i = 0; i < peer_ctx->num_pending_ops; i++)
+    if (peer_op == peer_ctx->pending_ops[i].op)
+      return GNUNET_YES;
+  return GNUNET_NO;
+}
+
+int
+Peers_remove_peer (const struct GNUNET_PeerIdentity *peer);
+
+/**
+ * Iterator over hash map entries. Deletes all contexts of peers.
+ *
+ * @param cls closure
+ * @param key current public key
+ * @param value value in the hash map
+ * @return #GNUNET_YES if we should continue to iterate,
+ *         #GNUNET_NO if not.
+ */
+static int
+peermap_clear_iterator (void *cls,
+                        const struct GNUNET_PeerIdentity *key,
+                        void *value)
+{
+  Peers_remove_peer (key);
+  return GNUNET_YES;
+}
+
+
+/**
+ * @brief This is called once a message is sent.
+ *
+ * Removes the pending message
+ *
+ * @param cls type of the message that was sent
+ */
+static void
+mq_notify_sent_cb (void *cls)
+{
+  struct PendingMessage *pending_msg = (struct PendingMessage *) cls;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+      "%s was sent.\n",
+      pending_msg->type);
+  /* Do not cancle message */
+  remove_pending_message (pending_msg, GNUNET_NO);
+}
+
+
+/**
+ * @brief Iterator function for #store_valid_peers.
+ *
+ * Implements #GNUNET_CONTAINER_PeerMapIterator.
+ * Writes single peer to disk.
+ *
+ * @param cls the file handle to write to.
+ * @param peer current peer
+ * @param value unused
+ *
+ * @return  #GNUNET_YES if we should continue to
+ *          iterate,
+ *          #GNUNET_NO if not.
+ */
+static int
+store_peer_presistently_iterator (void *cls,
+                                  const struct GNUNET_PeerIdentity *peer,
+                                  void *value)
+{
+  const struct GNUNET_DISK_FileHandle *fh = cls;
+  char peer_string[128];
+  int size;
+  ssize_t ret;
+
+  if (NULL == peer)
+  {
+    return GNUNET_YES;
+  }
+  size = GNUNET_snprintf (peer_string,
+                          sizeof (peer_string),
+                          "%s\n",
+                          GNUNET_i2s_full (peer));
+  GNUNET_assert (53 == size);
+  ret = GNUNET_DISK_file_write (fh,
+                                peer_string,
+                                size);
+  GNUNET_assert (size == ret);
+  return GNUNET_YES;
+}
+
+
+/**
+ * @brief Store the peers currently in #valid_peers to disk.
+ */
+static void
+store_valid_peers ()
+{
+  struct GNUNET_DISK_FileHandle *fh;
+  uint32_t number_written_peers;
+  int ret;
+
+  if (0 == strncmp ("DISABLE", filename_valid_peers, 7))
+  {
+    return;
+  }
+
+  ret = GNUNET_DISK_directory_create_for_file (filename_valid_peers);
+  if (GNUNET_SYSERR == ret)
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+        "Not able to create directory for file `%s'\n",
+        filename_valid_peers);
+    GNUNET_break (0);
+  }
+  else if (GNUNET_NO == ret)
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+        "Directory for file `%s' exists but is not writable for us\n",
+        filename_valid_peers);
+    GNUNET_break (0);
+  }
+  fh = GNUNET_DISK_file_open (filename_valid_peers,
+                              GNUNET_DISK_OPEN_WRITE |
+                                  GNUNET_DISK_OPEN_CREATE,
+                              GNUNET_DISK_PERM_USER_READ |
+                                  GNUNET_DISK_PERM_USER_WRITE);
+  if (NULL == fh)
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+        "Not able to write valid peers to file `%s'\n",
+        filename_valid_peers);
+    return;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+      "Writing %u valid peers to disk\n",
+      GNUNET_CONTAINER_multipeermap_size (valid_peers));
+  number_written_peers =
+    GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
+                                           store_peer_presistently_iterator,
+                                           fh);
+  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
+  GNUNET_assert (number_written_peers ==
+      GNUNET_CONTAINER_multipeermap_size (valid_peers));
+}
+
+
+/**
+ * @brief Convert string representation of peer id to peer id.
+ *
+ * Counterpart to #GNUNET_i2s_full.
+ *
+ * @param string_repr The string representation of the peer id
+ *
+ * @return The peer id
+ */
+static const struct GNUNET_PeerIdentity *
+s2i_full (const char *string_repr)
+{
+  struct GNUNET_PeerIdentity *peer;
+  size_t len;
+  int ret;
+
+  peer = GNUNET_new (struct GNUNET_PeerIdentity);
+  len = strlen (string_repr);
+  if (52 > len)
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+        "Not able to convert string representation of PeerID to PeerID\n"
+        "Sting representation: %s (len %lu) - too short\n",
+        string_repr,
+        len);
+    GNUNET_break (0);
+  }
+  else if (52 < len)
+  {
+    len = 52;
+  }
+  ret = GNUNET_CRYPTO_eddsa_public_key_from_string (string_repr,
+                                                    len,
+                                                    &peer->public_key);
+  if (GNUNET_OK != ret)
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+        "Not able to convert string representation of PeerID to PeerID\n"
+        "Sting representation: %s\n",
+        string_repr);
+    GNUNET_break (0);
+  }
+  return peer;
+}
+
+
+/**
+ * @brief Restore the peers on disk to #valid_peers.
+ */
+static void
+restore_valid_peers ()
+{
+  off_t file_size;
+  uint32_t num_peers;
+  struct GNUNET_DISK_FileHandle *fh;
+  char *buf;
+  ssize_t size_read;
+  char *iter_buf;
+  char *str_repr;
+  const struct GNUNET_PeerIdentity *peer;
+
+  if (0 == strncmp ("DISABLE", filename_valid_peers, 7))
+  {
+    return;
+  }
+
+  if (GNUNET_OK != GNUNET_DISK_file_test (filename_valid_peers))
+  {
+    return;
+  }
+  fh = GNUNET_DISK_file_open (filename_valid_peers,
+                              GNUNET_DISK_OPEN_READ,
+                              GNUNET_DISK_PERM_NONE);
+  GNUNET_assert (NULL != fh);
+  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_handle_size (fh, &file_size));
+  num_peers = file_size / 53;
+  buf = GNUNET_malloc (file_size);
+  size_read = GNUNET_DISK_file_read (fh, buf, file_size);
+  GNUNET_assert (size_read == file_size);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+      "Restoring %" PRIu32 " peers from file `%s'\n",
+      num_peers,
+      filename_valid_peers);
+  for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53)
+  {
+    str_repr = GNUNET_strndup (iter_buf, 53);
+    peer = s2i_full (str_repr);
+    GNUNET_free (str_repr);
+    add_valid_peer (peer);
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+        "Restored valid peer %s from disk\n",
+        GNUNET_i2s_full (peer));
+  }
+  iter_buf = NULL;
+  GNUNET_free (buf);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+      "num_peers: %" PRIu32 ", _size (valid_peers): %u\n",
+      num_peers,
+      GNUNET_CONTAINER_multipeermap_size (valid_peers));
+  if (num_peers != GNUNET_CONTAINER_multipeermap_size (valid_peers))
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+        "Number of restored peers does not match file size. Have probably 
duplicates.\n");
+  }
+  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+      "Restored %u valid peers from disk\n",
+      GNUNET_CONTAINER_multipeermap_size (valid_peers));
+}
+
+
+/**
+ * @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 disconnect_handler Disconnect handler
+ * @param own_id own peer identity
+ */
+void
+Peers_initialise (char* fn_valid_peers,
+                  struct GNUNET_CADET_Handle *cadet_h,
+                  GNUNET_CADET_DisconnectEventHandler disconnect_handler,
+                  const struct GNUNET_PeerIdentity *own_id)
+{
+  filename_valid_peers = GNUNET_strdup (fn_valid_peers);
+  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);
+  restore_valid_peers ();
+}
+
+
+/**
+ * @brief Delete storage of peers that was created with #Peers_initialise ()
+ */
+void
+Peers_terminate ()
+{
+  if (GNUNET_SYSERR ==
+      GNUNET_CONTAINER_multipeermap_iterate (peer_map,
+                                             peermap_clear_iterator,
+                                             NULL))
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+        "Iteration destroying peers was aborted.\n");
+  }
+  GNUNET_CONTAINER_multipeermap_destroy (peer_map);
+  store_valid_peers ();
+  GNUNET_free (filename_valid_peers);
+  GNUNET_CONTAINER_multipeermap_destroy (valid_peers);
+}
+
+
+/**
+ * Iterator over #valid_peers hash map entries.
+ *
+ * @param cls closure - unused
+ * @param peer current peer id
+ * @param value value in the hash map - unused
+ * @return #GNUNET_YES if we should continue to
+ *         iterate,
+ *         #GNUNET_NO if not.
+ */
+static int
+valid_peer_iterator (void *cls,
+                     const struct GNUNET_PeerIdentity *peer,
+                     void *value)
+{
+  struct PeersIteratorCls *it_cls = cls;
+
+  return it_cls->iterator (it_cls->cls,
+                           peer);
+}
+
+
+/**
+ * @brief Get all currently known, valid peer ids.
+ *
+ * @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)
+{
+  struct PeersIteratorCls *cls;
+  int ret;
+
+  cls = GNUNET_new (struct PeersIteratorCls);
+  cls->iterator = iterator;
+  cls->cls = it_cls;
+  ret = GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
+                                               valid_peer_iterator,
+                                               cls);
+  GNUNET_free (cls);
+  return ret;
+}
+
+
+/**
+ * @brief Add peer to known peers.
+ *
+ * This function is called on new peer_ids from 'external' sources
+ * (client seed, cadet get_peers(), ...)
+ *
+ * @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)
+ */
+int
+Peers_insert_peer (const struct GNUNET_PeerIdentity *peer)
+{
+  if ( (GNUNET_YES == Peers_check_peer_known (peer)) ||
+       (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity)) )
+  {
+    return GNUNET_NO; /* We already know this peer - nothing to do */
+  }
+  (void) create_peer_ctx (peer);
+  return GNUNET_YES;
+}
+
+int
+Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum 
Peers_PeerFlags flags);
+
+/**
+ * @brief Try connecting to a peer to see whether it is online
+ *
+ * If not known yet, insert into known peers
+ *
+ * @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)
+{
+  struct PeerContext *peer_ctx;
+  int ret;
+
+  if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity))
+  {
+    return GNUNET_NO;
+  }
+  ret = Peers_insert_peer (peer);
+  peer_ctx = get_peer_ctx (peer);
+  if (GNUNET_NO == Peers_check_peer_flag (peer, Peers_ONLINE))
+  {
+    check_peer_live (peer_ctx);
+  }
+  return ret;
+}
+
+
+/**
+ * @brief Check if peer is removable.
+ *
+ * Check if
+ *  - a recv channel exists
+ *  - there are pending messages
+ *  - there is no pending pull reply
+ *
+ * @param peer the peer in question
+ * @return #GNUNET_YES    if peer is removable
+ *         #GNUNET_NO     if peer is NOT removable
+ *         #GNUNET_SYSERR if peer is not known
+ */
+int
+Peers_check_removable (const struct GNUNET_PeerIdentity *peer)
+{
+  struct PeerContext *peer_ctx;
+
+  if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer))
+  {
+    return GNUNET_SYSERR;
+  }
+
+  peer_ctx = get_peer_ctx (peer);
+  if ( (NULL != peer_ctx->recv_channel) ||
+       (NULL != peer_ctx->pending_messages_head) ||
+       (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) 
)
+  {
+    return GNUNET_NO;
+  }
+  return GNUNET_YES;
+}
+
+uint32_t *
+Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
+                        enum Peers_ChannelRole role);
+
+int
+Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags 
flags);
+
+/**
+ * @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;
+  uint32_t *channel_flag;
+
+  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);
+    /* Cancle pending message, too */
+    remove_pending_message (peer_ctx->pending_messages_head, GNUNET_YES);
+  }
+  /* 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;
+  }
+  channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING);
+  if (NULL != peer_ctx->send_channel &&
+      GNUNET_YES != Peers_check_channel_flag (channel_flag, 
Peers_CHANNEL_DESTROING))
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+        "Destroying send channel\n");
+    GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
+    peer_ctx->send_channel = NULL;
+  }
+  channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_RECEIVING);
+  if (NULL != peer_ctx->recv_channel &&
+      GNUNET_YES != Peers_check_channel_flag (channel_flag, 
Peers_CHANNEL_DESTROING))
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+        "Destroying recv channel\n");
+    GNUNET_CADET_channel_destroy (peer_ctx->recv_channel);
+    peer_ctx->recv_channel = 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;
+}
+
+
+/**
+ * @brief set flags on a given peer.
+ *
+ * @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)
+{
+  struct PeerContext *peer_ctx;
+
+  peer_ctx = get_peer_ctx (peer);
+  set_peer_flag (peer_ctx, flags);
+}
+
+
+/**
+ * @brief unset flags on a given peer.
+ *
+ * @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)
+{
+  struct PeerContext *peer_ctx;
+
+  peer_ctx = get_peer_ctx (peer);
+  unset_peer_flag (peer_ctx, 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_SYSERR if peer is not known
+ *         #GNUNET_YES    if all given flags are set
+ *         #GNUNET_NO     otherwise
+ */
+int
+Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum 
Peers_PeerFlags flags)
+{
+  struct PeerContext *peer_ctx;
+
+  if (GNUNET_NO == Peers_check_peer_known (peer))
+  {
+    return GNUNET_SYSERR;
+  }
+  peer_ctx = get_peer_ctx (peer);
+  return check_peer_flag_set (peer_ctx, flags);
+}
+
+
+/**
+ * @brief set flags on a given channel.
+ *
+ * @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)
+{
+  set_channel_flag (channel_flags, 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)
+{
+  unset_channel_flag (channel_flags, 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)
+{
+  return check_channel_flag_set (channel_flags, flags);
+}
+
+/**
+ * @brief Get the flags for the channel in @a role for @a peer.
+ *
+ * @param peer Peer to get the channel flags for.
+ * @param role Role of channel to get flags for
+ *
+ * @return The flags.
+ */
+uint32_t *
+Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
+                        enum Peers_ChannelRole role)
+{
+  const struct PeerContext *peer_ctx;
+
+  peer_ctx = get_peer_ctx (peer);
+  if (Peers_CHANNEL_ROLE_SENDING == role)
+  {
+    return peer_ctx->send_channel_flags;
+  }
+  else if (Peers_CHANNEL_ROLE_RECEIVING == role)
+  {
+    return peer_ctx->recv_channel_flags;
+  }
+  else
+  {
+    GNUNET_assert (0);
+  }
+}
+
+/**
+ * @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)
+{
+  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
+ *
+ * This establishes a sending channel
+ *
+ * @param peer the peer to establish channel to
+ */
+void
+Peers_indicate_sending_intention (const struct GNUNET_PeerIdentity *peer)
+{
+  GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
+  (void) get_channel (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
+Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer)
+{
+  const struct PeerContext *peer_ctx;
+
+  peer_ctx = get_peer_ctx (peer);
+  if (NULL != peer_ctx->recv_channel)
+  {
+    return GNUNET_YES;
+  }
+  return GNUNET_NO;
+}
+
+
+/**
+ * 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
+ *
+ * @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)
+{
+  struct PeerContext *peer_ctx;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+      "New channel was established to us (Peer %s).\n",
+      GNUNET_i2s (initiator));
+  GNUNET_assert (NULL != channel); /* according to cadet API */
+  /* Make sure we 'know' about this peer */
+  peer_ctx = create_or_get_peer_ctx (initiator);
+  set_peer_live (peer_ctx);
+  /* We only accept one incoming channel per peer */
+  if (GNUNET_YES == Peers_check_peer_send_intention (initiator))
+  {
+    set_channel_flag (peer_ctx->recv_channel_flags,
+                      Peers_CHANNEL_ESTABLISHED_TWICE);
+    GNUNET_CADET_channel_destroy (channel);
+    /* return the channel context */
+    return &peer_ctx->peer_id;
+  }
+  peer_ctx->recv_channel = channel;
+  return &peer_ctx->peer_id;
+}
+
+
+/**
+ * @brief Check whether a sending channel towards the given peer exists
+ *
+ * @param peer the peer to check for
+ *
+ * @return #GNUNET_YES if a sending channel towards that peer exists
+ *         #GNUNET_NO  otherwise
+ */
+int
+Peers_check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer)
+{
+  struct PeerContext *peer_ctx;
+
+  if (GNUNET_NO == Peers_check_peer_known (peer))
+  { /* If no such peer exists, there is no channel */
+    return GNUNET_NO;
+  }
+  peer_ctx = get_peer_ctx (peer);
+  if (NULL == peer_ctx->send_channel)
+  {
+    return GNUNET_NO;
+  }
+  return GNUNET_YES;
+}
+
+
+/**
+ * @brief check whether the given channel is the sending channel of the given
+ *        peer
+ *
+ * @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 #GNUNET_YES if the given chennel is the sending channel of the peer
+ *         #GNUNET_NO  otherwise
+ */
+int
+Peers_check_channel_role (const struct GNUNET_PeerIdentity *peer,
+                          const struct GNUNET_CADET_Channel *channel,
+                          enum Peers_ChannelRole role)
+{
+  const struct PeerContext *peer_ctx;
+
+  if (GNUNET_NO == Peers_check_peer_known (peer))
+  {
+    return GNUNET_NO;
+  }
+  peer_ctx = get_peer_ctx (peer);
+  if ( (Peers_CHANNEL_ROLE_SENDING == role) &&
+       (channel == peer_ctx->send_channel) )
+  {
+    return GNUNET_YES;
+  }
+  if ( (Peers_CHANNEL_ROLE_RECEIVING == role) &&
+       (channel == peer_ctx->recv_channel) )
+  {
+    return GNUNET_YES;
+  }
+  return GNUNET_NO;
+}
+
+
+/**
+ * @brief Destroy the send channel of a peer e.g. stop indicating a sending
+ *        intention to another peer
+ *
+ * If there is also no channel to receive messages from that peer, remove it
+ * from the peermap.
+ * TODO really?
+ *
+ * @peer the peer identity of the peer whose sending channel to destroy
+ * @return #GNUNET_YES if channel was destroyed
+ *         #GNUNET_NO  otherwise
+ */
+int
+Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer)
+{
+  struct PeerContext *peer_ctx;
+
+  if (GNUNET_NO == Peers_check_peer_known (peer))
+  {
+    return GNUNET_NO;
+  }
+  peer_ctx = get_peer_ctx (peer);
+  if (NULL != peer_ctx->send_channel)
+  {
+    set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_CLEAN);
+    GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
+    peer_ctx->send_channel = NULL;
+    (void) Peers_check_connected (peer);
+    return GNUNET_YES;
+  }
+  return GNUNET_NO;
+}
+
+/**
+ * This is called when a channel is destroyed.
+ *
+ * @param cls The closure
+ * @param channel The channel being closed
+ * @param channel_ctx The context associated with this channel
+ */
+void
+Peers_cleanup_destroyed_channel (void *cls,
+                                 const struct GNUNET_CADET_Channel *channel)
+{
+  struct GNUNET_PeerIdentity *peer = cls;
+  struct PeerContext *peer_ctx;
+
+  if (GNUNET_NO == Peers_check_peer_known (peer))
+  {/* We don't want to implicitly create a context that we're about to kill */
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "channel (%s) without associated context was destroyed\n",
+       GNUNET_i2s (peer));
+    return;
+  }
+  peer_ctx = get_peer_ctx (peer);
+
+  /* If our peer issued the destruction of the channel, the #Peers_TO_DESTROY
+   * flag will be set. In this case simply make sure that the channels are
+   * cleaned. */
+  /* FIXME This distinction seems to be redundant */
+  if (Peers_check_peer_flag (peer, Peers_TO_DESTROY))
+  {/* We initiatad the destruction of this particular peer */
+    if (channel == peer_ctx->send_channel)
+      peer_ctx->send_channel = NULL;
+    else if (channel == peer_ctx->recv_channel)
+      peer_ctx->recv_channel = NULL;
+
+    if (NULL != peer_ctx->send_channel)
+    {
+      GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
+      peer_ctx->send_channel = NULL;
+    }
+    if (NULL != peer_ctx->recv_channel)
+    {
+      GNUNET_CADET_channel_destroy (peer_ctx->recv_channel);
+      peer_ctx->recv_channel = NULL;
+    }
+    /* Set the #Peers_ONLINE flag accordingly */
+    (void) Peers_check_connected (peer);
+    return;
+  }
+
+  else
+  { /* We did not initiate the destruction of this peer */
+    if (channel == peer_ctx->send_channel)
+    { /* Something (but us) killd the channel - clean up peer */
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+          "send channel (%s) was destroyed - cleaning up\n",
+          GNUNET_i2s (peer));
+      peer_ctx->send_channel = NULL;
+    }
+    else if (channel == peer_ctx->recv_channel)
+    { /* Other peer doesn't want to send us messages anymore */
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "Peer %s destroyed recv channel - cleaning up channel\n",
+           GNUNET_i2s (peer));
+      peer_ctx->recv_channel = NULL;
+    }
+    else
+    {
+      LOG (GNUNET_ERROR_TYPE_WARNING,
+           "unknown channel (%s) was destroyed\n",
+           GNUNET_i2s (peer));
+    }
+  }
+  (void) Peers_check_connected (peer);
+}
+
+/**
+ * @brief Send a message to another peer.
+ *
+ * Keeps track about pending messages so they can be properly removed when the
+ * peer is destroyed.
+ *
+ * @param peer receeiver of the message
+ * @param ev envelope of the message
+ * @param type type of the message
+ */
+void
+Peers_send_message (const struct GNUNET_PeerIdentity *peer,
+                    struct GNUNET_MQ_Envelope *ev,
+                    const char *type)
+{
+  struct PendingMessage *pending_msg;
+  struct GNUNET_MQ_Handle *mq;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Sending message to %s of type %s\n",
+             GNUNET_i2s (peer),
+             type);
+  pending_msg = insert_pending_message (peer, ev, type);
+  mq = get_mq (peer);
+  GNUNET_MQ_notify_sent (ev,
+                         mq_notify_sent_cb,
+                         pending_msg);
+  GNUNET_MQ_send (mq, ev);
+}
+
+/**
+ * @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)
+{
+  struct PeerPendingOp pending_op;
+  struct PeerContext *peer_ctx;
+
+  if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, &own_identity))
+  {
+    return GNUNET_NO;
+  }
+  GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
+
+  //TODO if LIVE/ONLINE execute immediately
+
+  if (GNUNET_NO == check_operation_scheduled (peer, peer_op))
+  {
+    peer_ctx = get_peer_ctx (peer);
+    pending_op.op = peer_op;
+    pending_op.op_cls = NULL;
+    GNUNET_array_append (peer_ctx->pending_ops,
+                         peer_ctx->num_pending_ops,
+                         pending_op);
+    return GNUNET_YES;
+  }
+  return GNUNET_NO;
+}
+
+/**
+ * @brief Get the recv_channel of @a peer.
+ * Needed to correctly handle (call #GNUNET_CADET_receive_done()) incoming
+ * messages.
+ *
+ * @param peer The peer to get the recv_channel from.
+ *
+ * @return The recv_channel.
+ */
+struct GNUNET_CADET_Channel *
+Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer)
+{
+  struct PeerContext *peer_ctx;
+
+  GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
+  peer_ctx = get_peer_ctx (peer);
+  return peer_ctx->recv_channel;
+}
+/***********************************************************************
+ * /Old gnunet-service-rps_peers.c
+***********************************************************************/
+
+
 /***********************************************************************
  * Housekeeping with clients
 ***********************************************************************/
@@ -847,6 +2568,7 @@ cleanup_destroyed_channel (void *cls,
 {
   struct GNUNET_PeerIdentity *peer = cls;
   uint32_t *channel_flag;
+  struct PeerContext *peer_ctx;
 
   if (GNUNET_NO == Peers_check_peer_known (peer))
   { /* We don't know a context to that peer */
@@ -856,6 +2578,15 @@ cleanup_destroyed_channel (void *cls,
     return;
   }
 
+  peer_ctx = get_peer_ctx (peer);
+  if (GNUNET_YES == Peers_check_channel_role (peer, channel, 
Peers_CHANNEL_ROLE_RECEIVING))
+  {
+    set_channel_flag (peer_ctx->recv_channel_flags, Peers_CHANNEL_DESTROING);
+  } else if (GNUNET_YES == Peers_check_channel_role (peer, channel, 
Peers_CHANNEL_ROLE_SENDING))
+  {
+    set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_DESTROING);
+  }
+
   if (GNUNET_YES == Peers_check_peer_flag (peer, Peers_TO_DESTROY))
   { /* We are in the middle of removing that peer from our knowledge. In this
        case simply make sure that the channels are cleaned. */
@@ -2236,26 +3967,6 @@ run (void *cls,
      const struct GNUNET_CONFIGURATION_Handle *c,
      struct GNUNET_SERVICE_Handle *service)
 {
-  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
-    GNUNET_MQ_hd_fixed_size (peer_check,
-                             GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE,
-                             struct GNUNET_MessageHeader,
-                             NULL),
-    GNUNET_MQ_hd_fixed_size (peer_push,
-                             GNUNET_MESSAGE_TYPE_RPS_PP_PUSH,
-                             struct GNUNET_MessageHeader,
-                             NULL),
-    GNUNET_MQ_hd_fixed_size (peer_pull_request,
-                             GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST,
-                             struct GNUNET_MessageHeader,
-                             NULL),
-    GNUNET_MQ_hd_var_size (peer_pull_reply,
-                           GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY,
-                           struct GNUNET_RPS_P2P_PullReplyMessage,
-                           NULL),
-    GNUNET_MQ_handler_end ()
-  };
-
   int size;
   int out_size;
   char* fn_valid_peers;
@@ -2345,6 +4056,27 @@ run (void *cls,
 
 
   /* Initialise cadet */
+  /* There exists a copy-paste-clone in get_channel() */
+  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
+    GNUNET_MQ_hd_fixed_size (peer_check,
+                             GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE,
+                             struct GNUNET_MessageHeader,
+                             NULL),
+    GNUNET_MQ_hd_fixed_size (peer_push,
+                             GNUNET_MESSAGE_TYPE_RPS_PP_PUSH,
+                             struct GNUNET_MessageHeader,
+                             NULL),
+    GNUNET_MQ_hd_fixed_size (peer_pull_request,
+                             GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST,
+                             struct GNUNET_MessageHeader,
+                             NULL),
+    GNUNET_MQ_hd_var_size (peer_pull_reply,
+                           GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY,
+                           struct GNUNET_RPS_P2P_PullReplyMessage,
+                           NULL),
+    GNUNET_MQ_handler_end ()
+  };
+
   cadet_handle = GNUNET_CADET_connect (cfg);
   GNUNET_assert (NULL != cadet_handle);
   GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS,
@@ -2361,7 +4093,7 @@ run (void *cls,
 
   peerinfo_handle = GNUNET_PEERINFO_connect (cfg);
   Peers_initialise (fn_valid_peers, cadet_handle, cleanup_destroyed_channel,
-                    cadet_handlers, &own_identity);
+                    &own_identity);
   GNUNET_free (fn_valid_peers);
 
   /* Initialise sampler */
diff --git a/src/rps/gnunet-service-rps_peers.c 
b/src/rps/gnunet-service-rps_peers.c
deleted file mode 100644
index 933e3cb87..000000000
--- a/src/rps/gnunet-service-rps_peers.c
+++ /dev/null
@@ -1,1701 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C)
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-
-/**
- * @file rps/gnunet-service-rps_peers.c
- * @brief utilities for managing (information about) peers
- * @author Julius Bünger
- */
-#include "platform.h"
-#include "gnunet_applications.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_cadet_service.h"
-#include <inttypes.h>
-#include "rps.h"
-#include "gnunet-service-rps_peers.h"
-
-
-
-#define LOG(kind, ...) GNUNET_log_from(kind,"rps-peers",__VA_ARGS__)
-
-
-/**
- * Set a peer flag of given peer context.
- */
-#define set_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) |= (mask))
-
-/**
- * Get peer flag of given peer context.
- */
-#define check_peer_flag_set(peer_ctx, mask)\
-  ((peer_ctx->peer_flags) & (mask) ? GNUNET_YES : GNUNET_NO)
-
-/**
- * Unset flag of given peer context.
- */
-#define unset_peer_flag(peer_ctx, mask) ((peer_ctx->peer_flags) &= ~(mask))
-
-/**
- * Set a channel flag of given channel context.
- */
-#define set_channel_flag(channel_flags, mask) ((*channel_flags) |= (mask))
-
-/**
- * Get channel flag of given channel context.
- */
-#define check_channel_flag_set(channel_flags, mask)\
-  ((*channel_flags) & (mask) ? GNUNET_YES : GNUNET_NO)
-
-/**
- * Unset flag of given channel context.
- */
-#define unset_channel_flag(channel_flags, mask) ((*channel_flags) &= ~(mask))
-
-
-
-/**
- * Pending operation on peer consisting of callback and closure
- *
- * When an operation cannot be executed right now this struct is used to store
- * the callback and closure for later execution.
- */
-struct PeerPendingOp
-{
-  /**
-   * Callback
-   */
-  PeerOp op;
-
-  /**
-   * Closure
-   */
-  void *op_cls;
-};
-
-/**
- * List containing all messages that are yet to be send
- *
- * This is used to keep track of all messages that have not been sent yet. When
- * a peer is to be removed the pending messages can be removed properly.
- */
-struct PendingMessage
-{
-  /**
-   * DLL next, prev
-   */
-  struct PendingMessage *next;
-  struct PendingMessage *prev;
-
-  /**
-   * The envelope to the corresponding message
-   */
-  struct GNUNET_MQ_Envelope *ev;
-
-  /**
-   * The corresponding context
-   */
-  struct PeerContext *peer_ctx;
-
-  /**
-   * The message type
-   */
-  const char *type;
-};
-
-/**
- * Struct used to keep track of other peer's status
- *
- * This is stored in a multipeermap.
- * It contains information such as cadet channels, a message queue for sending,
- * status about the channels, the pending operations on this peer and some 
flags
- * about the status of the peer itself. (live, valid, ...)
- */
-struct PeerContext
-{
-  /**
-   * Message queue open to client
-   */
-  struct GNUNET_MQ_Handle *mq;
-
-  /**
-   * Channel open to client.
-   */
-  struct GNUNET_CADET_Channel *send_channel;
-
-  /**
-   * Flags to the sending channel
-   */
-  uint32_t *send_channel_flags;
-
-  /**
-   * Channel open from client.
-   */
-  struct GNUNET_CADET_Channel *recv_channel; // unneeded?
-
-  /**
-   * Flags to the receiving channel
-   */
-  uint32_t *recv_channel_flags;
-
-  /**
-   * Array of pending operations on this peer.
-   */
-  struct PeerPendingOp *pending_ops;
-
-  /**
-   * Handle to the callback given to cadet_ntfy_tmt_rdy()
-   *
-   * To be canceled on shutdown.
-   */
-  struct PendingMessage *liveliness_check_pending;
-
-  /**
-   * Number of pending operations.
-   */
-  unsigned int num_pending_ops;
-
-  /**
-   * Identity of the peer
-   */
-  struct GNUNET_PeerIdentity peer_id;
-
-  /**
-   * Flags indicating status of peer
-   */
-  uint32_t peer_flags;
-
-  /**
-   * Last time we received something from that peer.
-   */
-  struct GNUNET_TIME_Absolute last_message_recv;
-
-  /**
-   * Last time we received a keepalive message.
-   */
-  struct GNUNET_TIME_Absolute last_keepalive;
-
-  /**
-   * DLL with all messages that are yet to be sent
-   */
-  struct PendingMessage *pending_messages_head;
-  struct PendingMessage *pending_messages_tail;
-
-  /**
-   * This is pobably followed by 'statistical' data (when we first saw
-   * him, how did we get his ID, how many pushes (in a timeinterval),
-   * ...)
-   */
-};
-
-/**
- * @brief Closure to #valid_peer_iterator
- */
-struct PeersIteratorCls
-{
-  /**
-   * Iterator function
-   */
-  PeersIterator iterator;
-
-  /**
-   * Closure to iterator
-   */
-  void *cls;
-};
-
-/**
- * @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;
-
-/**
- * @brief Filename of the file that stores the valid peers persistently.
- */
-static char *filename_valid_peers;
-
-/**
- * Set of all peers to keep track of them.
- */
-static struct GNUNET_CONTAINER_MultiPeerMap *peer_map;
-
-/**
- * Own #GNUNET_PeerIdentity.
- */
-static const struct GNUNET_PeerIdentity *own_identity;
-
-/**
- * Cadet handle.
- */
-static struct GNUNET_CADET_Handle *cadet_handle;
-
-/**
- * @brief Disconnect handler
- */
-static GNUNET_CADET_DisconnectEventHandler cleanup_destroyed_channel;
-
-/**
- * @brief cadet handlers
- */
-static const struct GNUNET_MQ_MessageHandler *cadet_handlers;
-
-
-
-/**
- * @brief Get the #PeerContext associated with a peer
- *
- * @param peer the peer id
- *
- * @return the #PeerContext
- */
-static struct PeerContext *
-get_peer_ctx (const struct GNUNET_PeerIdentity *peer)
-{
-  struct PeerContext *ctx;
-  int ret;
-
-  ret = GNUNET_CONTAINER_multipeermap_contains (peer_map, peer);
-  GNUNET_assert (GNUNET_YES == ret);
-  ctx = GNUNET_CONTAINER_multipeermap_get (peer_map, peer);
-  GNUNET_assert (NULL != ctx);
-  return ctx;
-}
-
-
-/**
- * @brief Create a new #PeerContext and insert it into the peer map
- *
- * @param peer the peer to create the #PeerContext for
- *
- * @return the #PeerContext
- */
-static struct PeerContext *
-create_peer_ctx (const struct GNUNET_PeerIdentity *peer)
-{
-  struct PeerContext *ctx;
-  int ret;
-
-  GNUNET_assert (GNUNET_NO == Peers_check_peer_known (peer));
-
-  ctx = GNUNET_new (struct PeerContext);
-  ctx->peer_id = *peer;
-  ctx->send_channel_flags = GNUNET_new (uint32_t);
-  ctx->recv_channel_flags = GNUNET_new (uint32_t);
-  ret = GNUNET_CONTAINER_multipeermap_put (peer_map, peer, ctx,
-      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
-  GNUNET_assert (GNUNET_OK == ret);
-  return ctx;
-}
-
-
-/**
- * @brief Create or get a #PeerContext
- *
- * @param peer the peer to get the associated context to
- *
- * @return the context
- */
-static struct PeerContext *
-create_or_get_peer_ctx (const struct GNUNET_PeerIdentity *peer)
-{
-  if (GNUNET_NO == Peers_check_peer_known (peer))
-  {
-    return create_peer_ctx (peer);
-  }
-  return get_peer_ctx (peer);
-}
-
-
-/**
- * @brief Check whether we have a connection to this @a peer
- *
- * Also sets the #Peers_ONLINE flag accordingly
- *
- * @param peer the peer in question
- *
- * @return #GNUNET_YES if we are connected
- *         #GNUNET_NO  otherwise
- */
-int
-Peers_check_connected (const struct GNUNET_PeerIdentity *peer)
-{
-  const struct PeerContext *peer_ctx;
-
-  /* If we don't know about this peer we don't know whether it's online */
-  if (GNUNET_NO == Peers_check_peer_known (peer))
-  {
-    return GNUNET_NO;
-  }
-  /* Get the context */
-  peer_ctx = get_peer_ctx (peer);
-  /* If we have no channel to this peer we don't know whether it's online */
-  if ( (NULL == peer_ctx->send_channel) &&
-       (NULL == peer_ctx->recv_channel) )
-  {
-    Peers_unset_peer_flag (peer, Peers_ONLINE);
-    return GNUNET_NO;
-  }
-  /* Otherwise (if we have a channel, we know that it's online */
-  Peers_set_peer_flag (peer, Peers_ONLINE);
-  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)
-{
-  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 adds peer to #valid_peers.
- *
- * @param peer_ctx the #PeerContext of the peer to set live
- */
-static void
-set_peer_live (struct PeerContext *peer_ctx)
-{
-  struct GNUNET_PeerIdentity *peer;
-  unsigned int i;
-
-  peer = &peer_ctx->peer_id;
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-      "Peer %s is live and valid, calling %i pending operations on it\n",
-      GNUNET_i2s (peer),
-      peer_ctx->num_pending_ops);
-
-  if (NULL != peer_ctx->liveliness_check_pending)
-  {
-    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;
-  }
-
-  (void) add_valid_peer (peer);
-  set_peer_flag (peer_ctx, Peers_ONLINE);
-
-  /* Call pending operations */
-  for (i = 0; i < peer_ctx->num_pending_ops; i++)
-  {
-    peer_ctx->pending_ops[i].op (peer_ctx->pending_ops[i].op_cls, peer);
-  }
-  GNUNET_array_grow (peer_ctx->pending_ops, peer_ctx->num_pending_ops, 0);
-}
-
-
-/**
- * @brief Get the channel of a peer. If not existing, create.
- *
- * @param peer the peer id
- * @return the #GNUNET_CADET_Channel used to send data to @a peer
- */
-struct GNUNET_CADET_Channel *
-get_channel (const struct GNUNET_PeerIdentity *peer)
-{
-  struct PeerContext *peer_ctx;
-  struct GNUNET_HashCode port;
-
-  peer_ctx = get_peer_ctx (peer);
-  if (NULL == peer_ctx->send_channel)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Trying to establish channel to peer %s\n",
-         GNUNET_i2s (peer));
-    GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS,
-                        strlen (GNUNET_APPLICATION_PORT_RPS),
-                        &port);
-    peer_ctx->send_channel =
-      GNUNET_CADET_channel_create (cadet_handle,
-                                   (struct GNUNET_PeerIdentity *) peer, /* 
context */
-                                   peer,
-                                   &port,
-                                   GNUNET_CADET_OPTION_RELIABLE,
-                                   NULL, /* WindowSize handler */
-                                   cleanup_destroyed_channel, /* Disconnect 
handler */
-                                   cadet_handlers);
-  }
-  GNUNET_assert (NULL != peer_ctx->send_channel);
-  return peer_ctx->send_channel;
-}
-
-
-/**
- * Get the message queue (#GNUNET_MQ_Handle) of a specific peer.
- *
- * If we already have a message queue open to this client,
- * simply return it, otherways create one.
- *
- * @param peer the peer to get the mq to
- * @return the #GNUNET_MQ_Handle
- */
-static struct GNUNET_MQ_Handle *
-get_mq (const struct GNUNET_PeerIdentity *peer)
-{
-  struct PeerContext *peer_ctx;
-
-  peer_ctx = get_peer_ctx (peer);
-
-  if (NULL == peer_ctx->mq)
-  {
-    (void) get_channel (peer);
-    peer_ctx->mq = GNUNET_CADET_get_mq (peer_ctx->send_channel);
-  }
-  return peer_ctx->mq;
-}
-
-
-/**
- * @brief This is called in response to the first message we sent as a
- * liveliness check.
- *
- * @param cls #PeerContext of peer with pending liveliness check
- */
-static void
-mq_liveliness_check_successful (void *cls)
-{
-  struct PeerContext *peer_ctx = cls;
-
-  if (NULL != peer_ctx->liveliness_check_pending)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-        "Liveliness check for peer %s was successfull\n",
-        GNUNET_i2s (&peer_ctx->peer_id));
-    GNUNET_free (peer_ctx->liveliness_check_pending);
-    peer_ctx->liveliness_check_pending = NULL;
-    set_peer_live (peer_ctx);
-  }
-}
-
-/**
- * Issue a check whether peer is live
- *
- * @param peer_ctx the context of the peer
- */
-static void
-check_peer_live (struct PeerContext *peer_ctx)
-{
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Get informed about peer %s getting live\n",
-       GNUNET_i2s (&peer_ctx->peer_id));
-
-  struct GNUNET_MQ_Handle *mq;
-  struct GNUNET_MQ_Envelope *ev;
-
-  ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE);
-  peer_ctx->liveliness_check_pending = GNUNET_new (struct PendingMessage);
-  peer_ctx->liveliness_check_pending->ev = ev;
-  peer_ctx->liveliness_check_pending->peer_ctx = peer_ctx;
-  peer_ctx->liveliness_check_pending->type = "Check liveliness";
-  mq = get_mq (&peer_ctx->peer_id);
-  GNUNET_MQ_notify_sent (ev,
-                         mq_liveliness_check_successful,
-                         peer_ctx);
-  GNUNET_MQ_send (mq, ev);
-}
-
-/**
- * @brief Add an envelope to a message passed to mq to list of pending messages
- *
- * @param peer peer the message was sent to
- * @param ev envelope to the message
- * @param type type of the message to be sent
- * @return pointer to pending message
- */
-static struct PendingMessage *
-insert_pending_message (const struct GNUNET_PeerIdentity *peer,
-                        struct GNUNET_MQ_Envelope *ev,
-                        const char *type)
-{
-  struct PendingMessage *pending_msg;
-  struct PeerContext *peer_ctx;
-
-  peer_ctx = get_peer_ctx (peer);
-  pending_msg = GNUNET_new (struct PendingMessage);
-  pending_msg->ev = ev;
-  pending_msg->peer_ctx = peer_ctx;
-  pending_msg->type = type;
-  GNUNET_CONTAINER_DLL_insert (peer_ctx->pending_messages_head,
-                               peer_ctx->pending_messages_tail,
-                               pending_msg);
-  return pending_msg;
-}
-
-
-/**
- * @brief Remove a pending message from the respective DLL
- *
- * @param pending_msg the pending message to remove
- * @param cancel cancel the pending message, too
- */
-static void
-remove_pending_message (struct PendingMessage *pending_msg, int cancel)
-{
-  struct PeerContext *peer_ctx;
-
-  peer_ctx = pending_msg->peer_ctx;
-  GNUNET_assert (NULL != peer_ctx);
-  GNUNET_CONTAINER_DLL_remove (peer_ctx->pending_messages_head,
-                               peer_ctx->pending_messages_tail,
-                               pending_msg);
-  // TODO wait for the cadet implementation of message cancellation
-  //if (GNUNET_YES == cancel)
-  //{
-  //  GNUNET_MQ_send_cancel (pending_msg->ev);
-  //}
-  GNUNET_free (pending_msg);
-}
-
-
-/**
- * @brief Check whether function of type #PeerOp was already scheduled
- *
- * The array with pending operations will probably never grow really big, so
- * iterating over it should be ok.
- *
- * @param peer the peer to check
- * @param peer_op the operation (#PeerOp) on the peer
- *
- * @return #GNUNET_YES if this operation is scheduled on that peer
- *         #GNUNET_NO  otherwise
- */
-static int
-check_operation_scheduled (const struct GNUNET_PeerIdentity *peer,
-                           const PeerOp peer_op)
-{
-  const struct PeerContext *peer_ctx;
-  unsigned int i;
-
-  peer_ctx = get_peer_ctx (peer);
-  for (i = 0; i < peer_ctx->num_pending_ops; i++)
-    if (peer_op == peer_ctx->pending_ops[i].op)
-      return GNUNET_YES;
-  return GNUNET_NO;
-}
-
-
-/**
- * Iterator over hash map entries. Deletes all contexts of peers.
- *
- * @param cls closure
- * @param key current public key
- * @param value value in the hash map
- * @return #GNUNET_YES if we should continue to iterate,
- *         #GNUNET_NO if not.
- */
-static int
-peermap_clear_iterator (void *cls,
-                        const struct GNUNET_PeerIdentity *key,
-                        void *value)
-{
-  Peers_remove_peer (key);
-  return GNUNET_YES;
-}
-
-
-/**
- * @brief This is called once a message is sent.
- *
- * Removes the pending message
- *
- * @param cls type of the message that was sent
- */
-static void
-mq_notify_sent_cb (void *cls)
-{
-  struct PendingMessage *pending_msg = (struct PendingMessage *) cls;
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-      "%s was sent.\n",
-      pending_msg->type);
-  /* Do not cancle message */
-  remove_pending_message (pending_msg, GNUNET_NO);
-}
-
-
-/**
- * @brief Iterator function for #store_valid_peers.
- *
- * Implements #GNUNET_CONTAINER_PeerMapIterator.
- * Writes single peer to disk.
- *
- * @param cls the file handle to write to.
- * @param peer current peer
- * @param value unused
- *
- * @return  #GNUNET_YES if we should continue to
- *          iterate,
- *          #GNUNET_NO if not.
- */
-static int
-store_peer_presistently_iterator (void *cls,
-                                  const struct GNUNET_PeerIdentity *peer,
-                                  void *value)
-{
-  const struct GNUNET_DISK_FileHandle *fh = cls;
-  char peer_string[128];
-  int size;
-  ssize_t ret;
-
-  if (NULL == peer)
-  {
-    return GNUNET_YES;
-  }
-  size = GNUNET_snprintf (peer_string,
-                          sizeof (peer_string),
-                          "%s\n",
-                          GNUNET_i2s_full (peer));
-  GNUNET_assert (53 == size);
-  ret = GNUNET_DISK_file_write (fh,
-                                peer_string,
-                                size);
-  GNUNET_assert (size == ret);
-  return GNUNET_YES;
-}
-
-
-/**
- * @brief Store the peers currently in #valid_peers to disk.
- */
-static void
-store_valid_peers ()
-{
-  struct GNUNET_DISK_FileHandle *fh;
-  uint32_t number_written_peers;
-  int ret;
-
-  if (0 == strncmp ("DISABLE", filename_valid_peers, 7))
-  {
-    return;
-  }
-
-  ret = GNUNET_DISK_directory_create_for_file (filename_valid_peers);
-  if (GNUNET_SYSERR == ret)
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "Not able to create directory for file `%s'\n",
-        filename_valid_peers);
-    GNUNET_break (0);
-  }
-  else if (GNUNET_NO == ret)
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "Directory for file `%s' exists but is not writable for us\n",
-        filename_valid_peers);
-    GNUNET_break (0);
-  }
-  fh = GNUNET_DISK_file_open (filename_valid_peers,
-                              GNUNET_DISK_OPEN_WRITE |
-                                  GNUNET_DISK_OPEN_CREATE,
-                              GNUNET_DISK_PERM_USER_READ |
-                                  GNUNET_DISK_PERM_USER_WRITE);
-  if (NULL == fh)
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "Not able to write valid peers to file `%s'\n",
-        filename_valid_peers);
-    return;
-  }
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-      "Writing %u valid peers to disk\n",
-      GNUNET_CONTAINER_multipeermap_size (valid_peers));
-  number_written_peers =
-    GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
-                                           store_peer_presistently_iterator,
-                                           fh);
-  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
-  GNUNET_assert (number_written_peers ==
-      GNUNET_CONTAINER_multipeermap_size (valid_peers));
-}
-
-
-/**
- * @brief Convert string representation of peer id to peer id.
- *
- * Counterpart to #GNUNET_i2s_full.
- *
- * @param string_repr The string representation of the peer id
- *
- * @return The peer id
- */
-static const struct GNUNET_PeerIdentity *
-s2i_full (const char *string_repr)
-{
-  struct GNUNET_PeerIdentity *peer;
-  size_t len;
-  int ret;
-
-  peer = GNUNET_new (struct GNUNET_PeerIdentity);
-  len = strlen (string_repr);
-  if (52 > len)
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "Not able to convert string representation of PeerID to PeerID\n"
-        "Sting representation: %s (len %u) - too short\n",
-        string_repr,
-        len);
-    GNUNET_break (0);
-  }
-  else if (52 < len)
-  {
-    len = 52;
-  }
-  ret = GNUNET_CRYPTO_eddsa_public_key_from_string (string_repr,
-                                                    len,
-                                                    &peer->public_key);
-  if (GNUNET_OK != ret)
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "Not able to convert string representation of PeerID to PeerID\n"
-        "Sting representation: %s\n",
-        string_repr);
-    GNUNET_break (0);
-  }
-  return peer;
-}
-
-
-/**
- * @brief Restore the peers on disk to #valid_peers.
- */
-static void
-restore_valid_peers ()
-{
-  off_t file_size;
-  uint32_t num_peers;
-  struct GNUNET_DISK_FileHandle *fh;
-  char *buf;
-  ssize_t size_read;
-  char *iter_buf;
-  char *str_repr;
-  const struct GNUNET_PeerIdentity *peer;
-
-  if (0 == strncmp ("DISABLE", filename_valid_peers, 7))
-  {
-    return;
-  }
-
-  if (GNUNET_OK != GNUNET_DISK_file_test (filename_valid_peers))
-  {
-    return;
-  }
-  fh = GNUNET_DISK_file_open (filename_valid_peers,
-                              GNUNET_DISK_OPEN_READ,
-                              GNUNET_DISK_PERM_NONE);
-  GNUNET_assert (NULL != fh);
-  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_handle_size (fh, &file_size));
-  num_peers = file_size / 53;
-  buf = GNUNET_malloc (file_size);
-  size_read = GNUNET_DISK_file_read (fh, buf, file_size);
-  GNUNET_assert (size_read == file_size);
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-      "Restoring %" PRIu32 " peers from file `%s'\n",
-      num_peers,
-      filename_valid_peers);
-  for (iter_buf = buf; iter_buf < buf + file_size - 1; iter_buf += 53)
-  {
-    str_repr = GNUNET_strndup (iter_buf, 53);
-    peer = s2i_full (str_repr);
-    GNUNET_free (str_repr);
-    add_valid_peer (peer);
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-        "Restored valid peer %s from disk\n",
-        GNUNET_i2s_full (peer));
-  }
-  iter_buf = NULL;
-  GNUNET_free (buf);
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-      "num_peers: %" PRIu32 ", _size (valid_peers): %u\n",
-      num_peers,
-      GNUNET_CONTAINER_multipeermap_size (valid_peers));
-  if (num_peers != GNUNET_CONTAINER_multipeermap_size (valid_peers))
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "Number of restored peers does not match file size. Have probably 
duplicates.\n");
-  }
-  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-      "Restored %u valid peers from disk\n",
-      GNUNET_CONTAINER_multipeermap_size (valid_peers));
-}
-
-
-/**
- * @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 disconnect_handler Disconnect handler
- * @param c_handlers cadet handlers
- * @param own_id own peer identity
- */
-void
-Peers_initialise (char* fn_valid_peers,
-                  struct GNUNET_CADET_Handle *cadet_h,
-                  GNUNET_CADET_DisconnectEventHandler disconnect_handler,
-                  const struct GNUNET_MQ_MessageHandler *c_handlers,
-                  const struct GNUNET_PeerIdentity *own_id)
-{
-  filename_valid_peers = GNUNET_strdup (fn_valid_peers);
-  cadet_handle = cadet_h;
-  cleanup_destroyed_channel = disconnect_handler;
-  cadet_handlers = c_handlers;
-  own_identity = own_id;
-  peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO);
-  valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO);
-  restore_valid_peers ();
-}
-
-
-/**
- * @brief Delete storage of peers that was created with #Peers_initialise ()
- */
-void
-Peers_terminate ()
-{
-  if (GNUNET_SYSERR ==
-      GNUNET_CONTAINER_multipeermap_iterate (peer_map,
-                                             peermap_clear_iterator,
-                                             NULL))
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-        "Iteration destroying peers was aborted.\n");
-  }
-  GNUNET_CONTAINER_multipeermap_destroy (peer_map);
-  store_valid_peers ();
-  GNUNET_free (filename_valid_peers);
-  GNUNET_CONTAINER_multipeermap_destroy (valid_peers);
-}
-
-
-/**
- * Iterator over #valid_peers hash map entries.
- *
- * @param cls closure - unused
- * @param peer current peer id
- * @param value value in the hash map - unused
- * @return #GNUNET_YES if we should continue to
- *         iterate,
- *         #GNUNET_NO if not.
- */
-static int
-valid_peer_iterator (void *cls,
-                     const struct GNUNET_PeerIdentity *peer,
-                     void *value)
-{
-  struct PeersIteratorCls *it_cls = cls;
-
-  return it_cls->iterator (it_cls->cls,
-                           peer);
-}
-
-
-/**
- * @brief Get all currently known, valid peer ids.
- *
- * @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)
-{
-  struct PeersIteratorCls *cls;
-  int ret;
-
-  cls = GNUNET_new (struct PeersIteratorCls);
-  cls->iterator = iterator;
-  cls->cls = it_cls;
-  ret = GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
-                                               valid_peer_iterator,
-                                               cls);
-  GNUNET_free (cls);
-  return ret;
-}
-
-
-/**
- * @brief Add peer to known peers.
- *
- * This function is called on new peer_ids from 'external' sources
- * (client seed, cadet get_peers(), ...)
- *
- * @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)
- */
-int
-Peers_insert_peer (const struct GNUNET_PeerIdentity *peer)
-{
-  if ( (GNUNET_YES == Peers_check_peer_known (peer)) ||
-       (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, own_identity)) )
-  {
-    return GNUNET_NO; /* We already know this peer - nothing to do */
-  }
-  (void) create_peer_ctx (peer);
-  return GNUNET_YES;
-}
-
-
-/**
- * @brief Try connecting to a peer to see whether it is online
- *
- * If not known yet, insert into known peers
- *
- * @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)
-{
-  struct PeerContext *peer_ctx;
-  int ret;
-
-  if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, own_identity))
-  {
-    return GNUNET_NO;
-  }
-  ret = Peers_insert_peer (peer);
-  peer_ctx = get_peer_ctx (peer);
-  if (GNUNET_NO == Peers_check_peer_flag (peer, Peers_ONLINE))
-  {
-    check_peer_live (peer_ctx);
-  }
-  return ret;
-}
-
-
-/**
- * @brief Check if peer is removable.
- *
- * Check if
- *  - a recv channel exists
- *  - there are pending messages
- *  - there is no pending pull reply
- *
- * @param peer the peer in question
- * @return #GNUNET_YES    if peer is removable
- *         #GNUNET_NO     if peer is NOT removable
- *         #GNUNET_SYSERR if peer is not known
- */
-int
-Peers_check_removable (const struct GNUNET_PeerIdentity *peer)
-{
-  struct PeerContext *peer_ctx;
-
-  if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer))
-  {
-    return GNUNET_SYSERR;
-  }
-
-  peer_ctx = get_peer_ctx (peer);
-  if ( (NULL != peer_ctx->recv_channel) ||
-       (NULL != peer_ctx->pending_messages_head) ||
-       (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) 
)
-  {
-    return GNUNET_NO;
-  }
-  return GNUNET_YES;
-}
-
-
-/**
- * @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);
-    /* Cancle pending message, too */
-    remove_pending_message (peer_ctx->pending_messages_head, GNUNET_YES);
-  }
-  /* 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;
-  }
-
-  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;
-}
-
-
-/**
- * @brief set flags on a given peer.
- *
- * @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)
-{
-  struct PeerContext *peer_ctx;
-
-  peer_ctx = get_peer_ctx (peer);
-  set_peer_flag (peer_ctx, flags);
-}
-
-
-/**
- * @brief unset flags on a given peer.
- *
- * @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)
-{
-  struct PeerContext *peer_ctx;
-
-  peer_ctx = get_peer_ctx (peer);
-  unset_peer_flag (peer_ctx, 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_SYSERR if peer is not known
- *         #GNUNET_YES    if all given flags are set
- *         #GNUNET_NO     otherwise
- */
-int
-Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum 
Peers_PeerFlags flags)
-{
-  struct PeerContext *peer_ctx;
-
-  if (GNUNET_NO == Peers_check_peer_known (peer))
-  {
-    return GNUNET_SYSERR;
-  }
-  peer_ctx = get_peer_ctx (peer);
-  return check_peer_flag_set (peer_ctx, flags);
-}
-
-
-/**
- * @brief set flags on a given channel.
- *
- * @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)
-{
-  set_channel_flag (channel_flags, 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)
-{
-  unset_channel_flag (channel_flags, 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)
-{
-  return check_channel_flag_set (channel_flags, flags);
-}
-
-/**
- * @brief Get the flags for the channel in @a role for @a peer.
- *
- * @param peer Peer to get the channel flags for.
- * @param role Role of channel to get flags for
- *
- * @return The flags.
- */
-uint32_t *
-Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
-                        enum Peers_ChannelRole role)
-{
-  const struct PeerContext *peer_ctx;
-
-  peer_ctx = get_peer_ctx (peer);
-  if (Peers_CHANNEL_ROLE_SENDING == role)
-  {
-    return peer_ctx->send_channel_flags;
-  }
-  else if (Peers_CHANNEL_ROLE_RECEIVING == role)
-  {
-    return peer_ctx->recv_channel_flags;
-  }
-  else
-  {
-    GNUNET_assert (0);
-  }
-}
-
-/**
- * @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)
-{
-  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
- *
- * This establishes a sending channel
- *
- * @param peer the peer to establish channel to
- */
-void
-Peers_indicate_sending_intention (const struct GNUNET_PeerIdentity *peer)
-{
-  GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
-  (void) get_channel (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
-Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer)
-{
-  const struct PeerContext *peer_ctx;
-
-  peer_ctx = get_peer_ctx (peer);
-  if (NULL != peer_ctx->recv_channel)
-  {
-    return GNUNET_YES;
-  }
-  return GNUNET_NO;
-}
-
-
-/**
- * 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
- *
- * @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)
-{
-  struct PeerContext *peer_ctx;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-      "New channel was established to us (Peer %s).\n",
-      GNUNET_i2s (initiator));
-  GNUNET_assert (NULL != channel); /* according to cadet API */
-  /* Make sure we 'know' about this peer */
-  peer_ctx = create_or_get_peer_ctx (initiator);
-  set_peer_live (peer_ctx);
-  /* We only accept one incoming channel per peer */
-  if (GNUNET_YES == Peers_check_peer_send_intention (initiator))
-  {
-    set_channel_flag (peer_ctx->recv_channel_flags,
-                      Peers_CHANNEL_ESTABLISHED_TWICE);
-    GNUNET_CADET_channel_destroy (channel);
-    /* return the channel context */
-    return &peer_ctx->peer_id;
-  }
-  peer_ctx->recv_channel = channel;
-  return &peer_ctx->peer_id;
-}
-
-
-/**
- * @brief Check whether a sending channel towards the given peer exists
- *
- * @param peer the peer to check for
- *
- * @return #GNUNET_YES if a sending channel towards that peer exists
- *         #GNUNET_NO  otherwise
- */
-int
-Peers_check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer)
-{
-  struct PeerContext *peer_ctx;
-
-  if (GNUNET_NO == Peers_check_peer_known (peer))
-  { /* If no such peer exists, there is no channel */
-    return GNUNET_NO;
-  }
-  peer_ctx = get_peer_ctx (peer);
-  if (NULL == peer_ctx->send_channel)
-  {
-    return GNUNET_NO;
-  }
-  return GNUNET_YES;
-}
-
-
-/**
- * @brief check whether the given channel is the sending channel of the given
- *        peer
- *
- * @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 #GNUNET_YES if the given chennel is the sending channel of the peer
- *         #GNUNET_NO  otherwise
- */
-int
-Peers_check_channel_role (const struct GNUNET_PeerIdentity *peer,
-                          const struct GNUNET_CADET_Channel *channel,
-                          enum Peers_ChannelRole role)
-{
-  const struct PeerContext *peer_ctx;
-
-  if (GNUNET_NO == Peers_check_peer_known (peer))
-  {
-    return GNUNET_NO;
-  }
-  peer_ctx = get_peer_ctx (peer);
-  if ( (Peers_CHANNEL_ROLE_SENDING == role) &&
-       (channel == peer_ctx->send_channel) )
-  {
-    return GNUNET_YES;
-  }
-  if ( (Peers_CHANNEL_ROLE_RECEIVING == role) &&
-       (channel == peer_ctx->recv_channel) )
-  {
-    return GNUNET_YES;
-  }
-  return GNUNET_NO;
-}
-
-
-/**
- * @brief Destroy the send channel of a peer e.g. stop indicating a sending
- *        intention to another peer
- *
- * If there is also no channel to receive messages from that peer, remove it
- * from the peermap.
- * TODO really?
- *
- * @peer the peer identity of the peer whose sending channel to destroy
- * @return #GNUNET_YES if channel was destroyed
- *         #GNUNET_NO  otherwise
- */
-int
-Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer)
-{
-  struct PeerContext *peer_ctx;
-
-  if (GNUNET_NO == Peers_check_peer_known (peer))
-  {
-    return GNUNET_NO;
-  }
-  peer_ctx = get_peer_ctx (peer);
-  if (NULL != peer_ctx->send_channel)
-  {
-    set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_CLEAN);
-    GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
-    peer_ctx->send_channel = NULL;
-    (void) Peers_check_connected (peer);
-    return GNUNET_YES;
-  }
-  return GNUNET_NO;
-}
-
-/**
- * This is called when a channel is destroyed.
- *
- * @param cls The closure
- * @param channel The channel being closed
- * @param channel_ctx The context associated with this channel
- */
-void
-Peers_cleanup_destroyed_channel (void *cls,
-                                 const struct GNUNET_CADET_Channel *channel)
-{
-  struct GNUNET_PeerIdentity *peer = cls;
-  struct PeerContext *peer_ctx;
-
-  if (GNUNET_NO == Peers_check_peer_known (peer))
-  {/* We don't want to implicitly create a context that we're about to kill */
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "channel (%s) without associated context was destroyed\n",
-       GNUNET_i2s (peer));
-    return;
-  }
-  peer_ctx = get_peer_ctx (peer);
-
-  /* If our peer issued the destruction of the channel, the #Peers_TO_DESTROY
-   * flag will be set. In this case simply make sure that the channels are
-   * cleaned. */
-  /* FIXME This distinction seems to be redundant */
-  if (Peers_check_peer_flag (peer, Peers_TO_DESTROY))
-  {/* We initiatad the destruction of this particular peer */
-    if (channel == peer_ctx->send_channel)
-      peer_ctx->send_channel = NULL;
-    else if (channel == peer_ctx->recv_channel)
-      peer_ctx->recv_channel = NULL;
-
-    if (NULL != peer_ctx->send_channel)
-    {
-      GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
-      peer_ctx->send_channel = NULL;
-    }
-    if (NULL != peer_ctx->recv_channel)
-    {
-      GNUNET_CADET_channel_destroy (peer_ctx->recv_channel);
-      peer_ctx->recv_channel = NULL;
-    }
-    /* Set the #Peers_ONLINE flag accordingly */
-    (void) Peers_check_connected (peer);
-    return;
-  }
-
-  else
-  { /* We did not initiate the destruction of this peer */
-    if (channel == peer_ctx->send_channel)
-    { /* Something (but us) killd the channel - clean up peer */
-      LOG (GNUNET_ERROR_TYPE_DEBUG,
-          "send channel (%s) was destroyed - cleaning up\n",
-          GNUNET_i2s (peer));
-      peer_ctx->send_channel = NULL;
-    }
-    else if (channel == peer_ctx->recv_channel)
-    { /* Other peer doesn't want to send us messages anymore */
-      LOG (GNUNET_ERROR_TYPE_DEBUG,
-           "Peer %s destroyed recv channel - cleaning up channel\n",
-           GNUNET_i2s (peer));
-      peer_ctx->recv_channel = NULL;
-    }
-    else
-    {
-      LOG (GNUNET_ERROR_TYPE_WARNING,
-           "unknown channel (%s) was destroyed\n",
-           GNUNET_i2s (peer));
-    }
-  }
-  (void) Peers_check_connected (peer);
-}
-
-/**
- * @brief Send a message to another peer.
- *
- * Keeps track about pending messages so they can be properly removed when the
- * peer is destroyed.
- *
- * @param peer receeiver of the message
- * @param ev envelope of the message
- * @param type type of the message
- */
-void
-Peers_send_message (const struct GNUNET_PeerIdentity *peer,
-                    struct GNUNET_MQ_Envelope *ev,
-                    const char *type)
-{
-  struct PendingMessage *pending_msg;
-  struct GNUNET_MQ_Handle *mq;
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-             "Sending message to %s of type %s\n",
-             GNUNET_i2s (peer),
-             type);
-  pending_msg = insert_pending_message (peer, ev, type);
-  mq = get_mq (peer);
-  GNUNET_MQ_notify_sent (ev,
-                         mq_notify_sent_cb,
-                         pending_msg);
-  GNUNET_MQ_send (mq, ev);
-}
-
-/**
- * @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)
-{
-  struct PeerPendingOp pending_op;
-  struct PeerContext *peer_ctx;
-
-  if (0 == GNUNET_CRYPTO_cmp_peer_identity (peer, own_identity))
-  {
-    return GNUNET_NO;
-  }
-  GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
-
-  //TODO if LIVE/ONLINE execute immediately
-
-  if (GNUNET_NO == check_operation_scheduled (peer, peer_op))
-  {
-    peer_ctx = get_peer_ctx (peer);
-    pending_op.op = peer_op;
-    pending_op.op_cls = NULL;
-    GNUNET_array_append (peer_ctx->pending_ops,
-                         peer_ctx->num_pending_ops,
-                         pending_op);
-    return GNUNET_YES;
-  }
-  return GNUNET_NO;
-}
-
-/**
- * @brief Get the recv_channel of @a peer.
- * Needed to correctly handle (call #GNUNET_CADET_receive_done()) incoming
- * messages.
- *
- * @param peer The peer to get the recv_channel from.
- *
- * @return The recv_channel.
- */
-struct GNUNET_CADET_Channel *
-Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer)
-{
-  struct PeerContext *peer_ctx;
-
-  GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
-  peer_ctx = get_peer_ctx (peer);
-  return peer_ctx->recv_channel;
-}
-
-/* end of gnunet-service-rps_peers.c */
diff --git a/src/rps/gnunet-service-rps_peers.h 
b/src/rps/gnunet-service-rps_peers.h
deleted file mode 100644
index 15970a7ce..000000000
--- a/src/rps/gnunet-service-rps_peers.h
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C)
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-
-/**
- * @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"
-
-
-/**
- * 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.
- *
- * 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.
- *
- * @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.
- *
- * @param cls closure
- * @param peer current public peer id
- * @return #GNUNET_YES if we should continue to
- *         iterate,
- *         #GNUNET_NO if not.
- */
-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 disconnect_handler Disconnect handler
- * @param c_handlers cadet handlers
- * @param own_id own peer identity
- */
-void
-Peers_initialise (char* fn_valid_peers,
-                  struct GNUNET_CADET_Handle *cadet_h,
-                  GNUNET_CADET_DisconnectEventHandler disconnect_handler,
-                  const struct GNUNET_MQ_MessageHandler *c_handlers,
-                  const struct GNUNET_PeerIdentity *own_id);
-
-/**
- * @brief Delete storage of peers that was created with #Peers_initialise ()
- */
-void
-Peers_terminate ();
-
-
-/**
- * @brief Get all currently known, valid peer ids.
- *
- * @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(), ...)
- *
- * @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)
- */
-int
-Peers_insert_peer (const struct GNUNET_PeerIdentity *peer);
-
-/**
- * @brief Try connecting to a peer to see whether it is online
- *
- * If not known yet, insert into known peers
- *
- * @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 Check if peer is removable.
- *
- * Check if
- *  - a recv channel exists
- *  - there are pending messages
- *  - there is no pending pull reply
- *
- * @param peer the peer in question
- * @return #GNUNET_YES    if peer is removable
- *         #GNUNET_NO     if peer is NOT removable
- *         #GNUNET_SYSERR if peer is not known
- */
-int
-Peers_check_removable (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
-Peers_remove_peer (const struct GNUNET_PeerIdentity *peer);
-
-/**
- * @brief set flags on a given peer.
- *
- * @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.
- *
- * @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
-Peers_check_peer_flag (const struct GNUNET_PeerIdentity *peer, enum 
Peers_PeerFlags flags);
-
-
-/**
- * @brief set flags on a given channel.
- *
- * @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 Get the flags for the channel in @a role for @a peer.
- *
- * @param peer Peer to get the channel flags for.
- * @param role Role of channel to get flags for
- *
- * @return The flags.
- */
-uint32_t *
-Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
-                        enum Peers_ChannelRole role);
-
-/**
- * @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
- *
- * 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
-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
- *
- * @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);
-
-/**
- * @brief Check whether a sending channel towards the given peer exists
- *
- * @param peer the peer to check for
- *
- * @return #GNUNET_YES if a sending channel towards that peer exists
- *         #GNUNET_NO  otherwise
- */
-int
-Peers_check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer);
-
-/**
- * @brief check whether the given channel is the sending channel of the given
- *        peer
- *
- * @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 #GNUNET_YES if the given chennel is the sending channel of the peer
- *         #GNUNET_NO  otherwise
- */
-int
-Peers_check_channel_role (const struct GNUNET_PeerIdentity *peer,
-                          const struct GNUNET_CADET_Channel *channel,
-                          enum Peers_ChannelRole role);
-
-/**
- * @brief Destroy the send channel of a peer e.g. stop indicating a sending
- *        intention to another peer
- *
- * If there is also no channel to receive messages from that peer, remove it
- * from the peermap.
- *
- * @peer the peer identity of the peer whose sending channel to destroy
- * @return #GNUNET_YES if channel was destroyed
- *         #GNUNET_NO  otherwise
- */
-int
-Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer);
-
-/**
- * This is called when a channel is destroyed.
- *
- * Removes peer completely from our knowledge if the send_channel was destroyed
- * Otherwise simply delete the recv_channel
- *
- * @param cls The closure
- * @param channel The channel being closed
- * @param channel_ctx The context associated with this channel
- */
-void
-Peers_cleanup_destroyed_channel (void *cls,
-                                 const struct GNUNET_CADET_Channel *channel);
-
-/**
- * @brief Send a message to another peer.
- *
- * Keeps track about pending messages so they can be properly removed when the
- * peer is destroyed.
- *
- * @param peer receeiver of the message
- * @param ev envelope of the message
- * @param type type of the message
- */
-void
-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);
-
-/**
- * @brief Get the recv_channel of @a peer.
- * Needed to correctly handle (call #GNUNET_CADET_receive_done()) incoming
- * messages.
- *
- * @param peer The peer to get the recv_channel from.
- *
- * @return The recv_channel.
- */
-struct GNUNET_CADET_Channel *
-Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer);
-
-/* end of gnunet-service-rps_peers.h */
diff --git a/src/rps/rps.h b/src/rps/rps.h
index 3037e2190..f5cc2e8d1 100644
--- a/src/rps/rps.h
+++ b/src/rps/rps.h
@@ -175,4 +175,100 @@ struct GNUNET_RPS_CS_ActMaliciousMessage
 };
 #endif /* ENABLE_MALICIOUS */
 
+
+/***********************************************************************
+ * Defines from old gnunet-service-rps_peers.h
+***********************************************************************/
+
+/**
+ * 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.
+ *
+ * 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,
+
+  /**
+   * We destroyed the channel because the other peer established a second one.
+   */
+  Peers_CHANNEL_DESTROING = 0x4,
+};
+
+
+/**
+ * @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.
+ *
+ * @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.
+ *
+ * @param cls closure
+ * @param peer current public peer id
+ * @return #GNUNET_YES if we should continue to
+ *         iterate,
+ *         #GNUNET_NO if not.
+ */
+typedef int
+(*PeersIterator) (void *cls,
+                  const struct GNUNET_PeerIdentity *peer);
+
+
 GNUNET_NETWORK_STRUCT_END
diff --git a/src/rps/test_service_rps_peers.c b/src/rps/test_service_rps_peers.c
deleted file mode 100644
index 9cd677fef..000000000
--- a/src/rps/test_service_rps_peers.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C)
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file rps/test_service_rps_peers.c
- * @brief testcase for gnunet-service-rps_peers.c
- */
-#include <platform.h>
-#include "gnunet-service-rps_peers.h"
-
-#define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); 
Peers_terminate (); return 1; }
-#define CHECK(c) { if (! (c)) ABORT(); }
-
-#define FN_VALID_PEERS "DISABLE"
-
-/**
- * @brief Dummy implementation of #PeerOp (Operation on peer)
- *
- * @param cls closure
- * @param peer peer
- */
-void peer_op (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
-  GNUNET_assert (NULL != peer);
-}
-
-/**
- * @brief Function that is called on a peer for later execution
- *
- * @param cls closure
- * @param peer peer to execute function upon
- */
-void
-peer_op (void *cls, const struct GNUNET_PeerIdentity *peer);
-
-static int
-check ()
-{
-  struct GNUNET_PeerIdentity k1;
-  struct GNUNET_PeerIdentity own_id;
-  
-  memset (&k1, 0, sizeof (k1));
-  memset (&own_id, 1, sizeof (own_id));
-
-  /* Do nothing */
-  Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
-  Peers_terminate ();
-
-
-  /* Create peer */
-  Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
-  CHECK (GNUNET_YES == Peers_insert_peer (&k1));
-  Peers_terminate ();
-
-
-  /* Create peer */
-  Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
-  CHECK (GNUNET_YES == Peers_insert_peer (&k1));
-  CHECK (GNUNET_YES == Peers_remove_peer (&k1));
-  Peers_terminate ();
-
-
-  /* Insertion and Removal */
-  Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
-  CHECK (GNUNET_NO  == Peers_check_peer_known (&k1));
-
-  CHECK (GNUNET_YES == Peers_insert_peer (&k1));
-  CHECK (GNUNET_NO  == Peers_insert_peer (&k1));
-  CHECK (GNUNET_YES == Peers_check_peer_known (&k1));
-
-  CHECK (GNUNET_YES == Peers_remove_peer (&k1));
-  CHECK (GNUNET_NO  == Peers_remove_peer (&k1));
-  CHECK (GNUNET_NO  == Peers_check_peer_known (&k1));
-
-
-  /* Flags */
-  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_ONLINE));
-  CHECK (GNUNET_NO == Peers_check_peer_flag (&k1, Peers_TO_DESTROY));
-
-  CHECK (GNUNET_NO  == Peers_check_peer_flag (&k1, Peers_ONLINE));
-
-  Peers_set_peer_flag (&k1, Peers_ONLINE);
-  CHECK (GNUNET_YES == Peers_check_peer_flag (&k1, Peers_ONLINE));
-  CHECK (GNUNET_NO  == Peers_check_peer_flag (&k1, Peers_TO_DESTROY));
-  CHECK (GNUNET_YES == Peers_check_peer_flag (&k1, Peers_ONLINE));
-  CHECK (GNUNET_NO  == Peers_check_peer_flag (&k1, Peers_TO_DESTROY));
-
-  /* Check send intention */
-  CHECK (GNUNET_NO == Peers_check_peer_send_intention (&k1));
-
-  /* Check existence of sending channel */
-  CHECK (GNUNET_NO == Peers_check_sending_channel_exists (&k1));
-
-  /* Check role of channels */
-  CHECK (GNUNET_YES == Peers_check_channel_role (&k1,
-                                                 NULL,
-                                                 Peers_CHANNEL_ROLE_SENDING));
-  CHECK (GNUNET_YES == Peers_check_channel_role (&k1,
-                                                 NULL,
-                                                 
Peers_CHANNEL_ROLE_RECEIVING));
-
-  CHECK (GNUNET_YES == Peers_schedule_operation (&k1, peer_op));
-
-  Peers_terminate ();
-  return 0;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  GNUNET_log_setup ("test_service_rps_peers", 
-                   "WARNING",
-                   NULL);
-  return check ();
-}
-
-/* end of test_service_rps_peers.c */

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]