+
+/**
+ * Task run to warn about missing calls to #GNUNET_SERVICE_client_continue().
+ *
+ * @param cls our `struct GNUNET_SERVICE_Client *` to process more requests from
+ */
+static void
+warn_no_client_continue (void *cls)
+{
+ struct GNUNET_SERVICE_Client *client = cls;
+
+ GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
+ client->warn_task
+ = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
+ &warn_no_client_continue,
+ client);
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ _("Processing code for message of type %u did not call `GNUNET_SERVICE_client_continue' after %s\n"),
+ (unsigned int) client->warn_type,
+ GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (client->warn_start),
+ GNUNET_YES));
+}
+
+
+/**
+ * Functions with this signature are called whenever a
+ * complete message is received by the tokenizer for a client.
+ *
+ * Do not call #GNUNET_MST_destroy() from within
+ * the scope of this callback.
+ *
+ * @param cls closure with the `struct GNUNET_SERVICE_Client *`
+ * @param message the actual message
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if the client was dropped
+ */
+static int
+service_client_mst_cb (void *cls,
+ const struct GNUNET_MessageHeader *message)
+{
+ struct GNUNET_SERVICE_Client *client = cls;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Received message of type %u and size %u from client\n",
+ ntohs (message->type),
+ ntohs (message->size));
+ GNUNET_assert (GNUNET_NO == client->needs_continue);
+ client->needs_continue = GNUNET_YES;
+ client->warn_type = ntohs (message->type);
+ client->warn_start = GNUNET_TIME_absolute_get ();
+ GNUNET_assert (NULL == client->warn_task);
+ client->warn_task
+ = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
+ &warn_no_client_continue,
+ client);
+ GNUNET_MQ_inject_message (client->mq,
+ message);
+ if (NULL != client->drop_task)
+ return GNUNET_SYSERR;
+ return GNUNET_OK;
+}
+
+
+/**
+ * A client sent us data. Receive and process it. If we are done,
+ * reschedule this task.
+ *
+ * @param cls the `struct GNUNET_SERVICE_Client` that sent us data.
+ */
+static void
+service_client_recv (void *cls)
+{
+ struct GNUNET_SERVICE_Client *client = cls;
+ int ret;
+
+ client->recv_task = NULL;
+ ret = GNUNET_MST_read (client->mst,
+ client->sock,
+ GNUNET_NO,
+ GNUNET_YES);
+ if (GNUNET_SYSERR == ret)