+static void
+psyc_recv_message (void *cls,
+ const struct GNUNET_PSYC_MessageHeader *msg)
+{
+ struct Place *plc = cls;
+
+ char *str = GNUNET_CRYPTO_ecdsa_public_key_to_string (&msg->slave_pub_key);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%p Received PSYC message of size %u from %s.\n",
+ plc, ntohs (msg->header.size), str);
+ GNUNET_free (str);
+
+ GNUNET_PSYC_slicer_message (plc->slicer, msg);
+
+ place_send_msg (plc, &msg->header);
+}
+
+
+/**
+ * Relay a message part received from a guest to the the place.
+ *
+ * @param hst
+ * Host.
+ * @param pmsg
+ * Message part.
+ * @param nym_pub_key
+ * Nym the message is received from.
+ */
+static void
+host_relay_message_part (struct Host *hst,
+ const struct GNUNET_MessageHeader *pmsg,
+ const struct GNUNET_CRYPTO_EcdsaPublicKey *nym_pub_key)
+{
+ /* separate queue per nym */
+ struct GNUNET_HashCode nym_pub_hash;
+ GNUNET_CRYPTO_hash (nym_pub_key, sizeof (*nym_pub_key), &nym_pub_hash);
+
+ struct MessageTransmitQueue *
+ tmit_msg = GNUNET_CONTAINER_multihashmap_get (hst->relay_msgs, &nym_pub_hash);
+
+ uint16_t ptype = ntohs (pmsg->type);
+
+ if (GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD == ptype)
+ {
+ /* FIXME: last message was unfinished, cancel & remove from queue */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "FIXME: last message was unfinished.\n");
+ }
+
+ tmit_msg = psyc_transmit_queue_message (&hst->place, NULL, ntohs (pmsg->size),
+ pmsg, ptype, ptype, tmit_msg);
+
+ switch (ptype)
+ {
+ case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD:
+ GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_put
+ (hst->relay_msgs, &nym_pub_hash, tmit_msg,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+ break;
+ case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_END:
+ case GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_CANCEL:
+ GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove
+ (hst->relay_msgs, &nym_pub_hash, tmit_msg));
+ break;
+ }
+}
+
+
+/**
+ * Received a method to be relayed from a guest.
+ */
+static void
+place_recv_relay_method (void *cls,
+ const struct GNUNET_PSYC_MessageHeader *msg,
+ const struct GNUNET_PSYC_MessageMethod *meth,
+ uint64_t message_id,
+ const char *method_name)
+{
+ struct Place *plc = cls;
+
+ if (GNUNET_PSYC_MESSAGE_REQUEST & ntohs (msg->flags)
+ && GNUNET_YES == plc->is_host)
+ {
+ struct Host *hst = cls;
+ host_relay_message_part (hst, &meth->header, &msg->slave_pub_key);
+ }
+}
+
+
+/**
+ * Received a modifier to be relayed from a guest.
+ */
+static void
+place_recv_relay_modifier (void *cls,
+ const struct GNUNET_PSYC_MessageHeader *msg,
+ const struct GNUNET_MessageHeader *pmsg,
+ uint64_t message_id,
+ enum GNUNET_PSYC_Operator oper,
+ const char *name,
+ const void *value,
+ uint16_t value_size,
+ uint16_t full_value_size)
+{
+ struct Place *plc = cls;
+
+ if (GNUNET_PSYC_MESSAGE_REQUEST & ntohs (msg->flags)
+ && GNUNET_YES == plc->is_host)
+ {
+ struct Host *hst = cls;
+ host_relay_message_part (hst, pmsg, &msg->slave_pub_key);
+ }
+}
+
+/**
+ * Received a data fragment to be relayed from a guest.
+ */
+static void
+place_recv_relay_data (void *cls,
+ const struct GNUNET_PSYC_MessageHeader *msg,
+ const struct GNUNET_MessageHeader *pmsg,
+ uint64_t message_id,
+ const void *data,
+ uint16_t data_size)
+{
+ struct Place *plc = cls;
+
+ if (GNUNET_PSYC_MESSAGE_REQUEST & ntohs (msg->flags)
+ && GNUNET_YES == plc->is_host)
+ {
+ struct Host *hst = cls;
+ host_relay_message_part (hst, pmsg, &msg->slave_pub_key);
+ }
+}
+
+
+/**
+ * Received end of message to be relayed from a guest.
+ */
+static void
+place_recv_relay_eom (void *cls,
+ const struct GNUNET_PSYC_MessageHeader *msg,
+ const struct GNUNET_MessageHeader *pmsg,
+ uint64_t message_id,
+ uint8_t is_cancelled)
+{
+ struct Place *plc = cls;
+
+ if (GNUNET_PSYC_MESSAGE_REQUEST & ntohs (msg->flags)
+ && GNUNET_YES == plc->is_host)
+ {
+ struct Host *hst = cls;
+ host_relay_message_part (hst, pmsg, &msg->slave_pub_key);
+ }
+}
+
+
+/**
+ * Received a method to be saved to disk.
+ *
+ * Create a new file for writing the data part of the message into,
+ * if the file does not yet exist.
+ */
+static void
+place_recv_save_method (void *cls,
+ const struct GNUNET_PSYC_MessageHeader *msg,
+ const struct GNUNET_PSYC_MessageMethod *meth,
+ uint64_t message_id,
+ const char *method_name)