+#if USE_PEER_ID
+struct CheckPeerContext
+{
+ /**
+ * Peer we found
+ */
+ struct DistantNeighbor *peer;
+
+ /**
+ * Sender id to search for
+ */
+ unsigned int sender_id;
+};
+
+/**
+ * Iterator over hash map entries.
+ *
+ * @param cls closure
+ * @param key current key code
+ * @param value value in the hash map
+ * @return GNUNET_YES if we should continue to
+ * iterate,
+ * GNUNET_NO if not.
+ */
+int checkPeerID (void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
+{
+ struct CheckPeerContext *ctx = cls;
+ struct DistantNeighbor *distant = value;
+
+ if (memcmp(key, &ctx->sender_id, sizeof(unsigned int)) == 0)
+ {
+ ctx->peer = distant;
+ return GNUNET_NO;
+ }
+ return GNUNET_YES;
+
+}
+#endif
+
+
+/**
+ * Handler for messages parsed out by the tokenizer from
+ * DV DATA received for this peer.
+ *
+ * @param cls NULL
+ * @param client the TokenizedMessageContext which contains message information
+ * @param message the actual message
+ */
+void tokenized_message_handler (void *cls,
+ void *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ struct TokenizedMessageContext *ctx = client;
+ GNUNET_break_op (ntohs (message->type) != GNUNET_MESSAGE_TYPE_DV_GOSSIP);
+ GNUNET_break_op (ntohs (message->type) != GNUNET_MESSAGE_TYPE_DV_DATA);
+ if ( (ntohs (message->type) != GNUNET_MESSAGE_TYPE_DV_GOSSIP) &&
+ (ntohs (message->type) != GNUNET_MESSAGE_TYPE_DV_DATA) )
+ {
+#if DEBUG_DV_MESSAGES
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s: Receives %s message for me, uid %u, size %d, type %d cost %u from %s!\n", my_short_id, "DV DATA", ctx->uid, ntohs(message->size), ntohs(message->type), ctx->distant->cost, GNUNET_i2s(&ctx->distant->identity));
+#endif
+ GNUNET_assert(memcmp(ctx->peer, &ctx->distant->identity, sizeof(struct GNUNET_PeerIdentity)) != 0);
+ send_to_plugin(ctx->peer, message, ntohs(message->size), &ctx->distant->identity, ctx->distant->cost);
+ }
+}
+
+#if DELAY_FORWARDS
+struct DelayedMessageContext
+{
+ struct GNUNET_PeerIdentity dest;
+ struct GNUNET_PeerIdentity sender;
+ struct GNUNET_MessageHeader *message;
+ size_t message_size;
+ uint32_t uid;
+};
+
+void send_message_delayed (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct DelayedMessageContext *msg_ctx = cls;
+ if (msg_ctx != NULL)
+ {
+ send_message(&msg_ctx->dest,
+ &msg_ctx->sender,
+ NULL,
+ msg_ctx->message,
+ msg_ctx->message_size,
+ default_dv_priority,
+ msg_ctx->uid,
+ GNUNET_TIME_relative_get_forever());
+ GNUNET_free(msg_ctx->message);
+ GNUNET_free(msg_ctx);
+ }
+}
+#endif
+
+/**
+ * Get distance information from 'atsi'.
+ *
+ * @param atsi performance data
+ * @return connected transport distance
+ */
+static uint32_t
+get_atsi_distance (const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+{
+ while ( (ntohl (atsi->type) != GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR) &&
+ (ntohl (atsi->type) != GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE) )
+ atsi++;
+ if (ntohl (atsi->type) == GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR)
+ {
+ GNUNET_break (0);
+ /* FIXME: we do not have distance data? Assume direct neighbor. */
+ return DIRECT_NEIGHBOR_COST;
+ }
+ return ntohl (atsi->value);
+}
+
+/**
+ * Find latency information in 'atsi'.
+ *
+ * @param atsi performance data
+ * @return connection latency
+ */
+static struct GNUNET_TIME_Relative
+get_atsi_latency (const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+{
+ while ( (ntohl (atsi->type) != GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR) &&
+ (ntohl (atsi->type) != GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY) )
+ atsi++;
+ if (ntohl (atsi->type) == GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR)
+ {
+ GNUNET_break (0);
+ /* how can we not have latency data? */
+ return GNUNET_TIME_UNIT_SECONDS;
+ }
+ /* FIXME: Multiply by GNUNET_TIME_UNIT_MILLISECONDS (1) to get as a GNUNET_TIME_Relative */
+ return GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, ntohl (atsi->value));
+}