+/**
+ * Handle request message for a listen operation
+ *
+ * @param cls the listen handle
+ * @param msg the message
+ */
+static void
+handle_request (void *cls,
+ const struct GNUNET_SET_RequestMessage *msg)
+{
+ struct GNUNET_SET_ListenHandle *lh = cls;
+ struct GNUNET_SET_Request req;
+ const struct GNUNET_MessageHeader *context_msg;
+ struct GNUNET_MQ_Envelope *mqm;
+ struct GNUNET_SET_RejectMessage *rmsg;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Processing incoming operation request\n");
+ /* we got another valid request => reset the backoff */
+ lh->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
+ req.accept_id = ntohl (msg->accept_id);
+ req.accepted = GNUNET_NO;
+ context_msg = GNUNET_MQ_extract_nested_mh (msg);
+ /* calling #GNUNET_SET_accept() in the listen cb will set req->accepted */
+ lh->listen_cb (lh->listen_cls,
+ &msg->peer_id,
+ context_msg,
+ &req);
+ if (GNUNET_YES == req.accepted)
+ return; /* the accept-case is handled in #GNUNET_SET_accept() */
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Rejecting request\n");
+ mqm = GNUNET_MQ_msg (rmsg,
+ GNUNET_MESSAGE_TYPE_SET_REJECT);
+ rmsg->accept_reject_id = msg->accept_id;
+ GNUNET_MQ_send (lh->mq, mqm);
+}
+
+
+/**
+ * Our connection with the set service encountered an error,
+ * re-initialize with exponential back-off.
+ *
+ * @param cls the `struct GNUNET_SET_ListenHandle *`
+ * @param error reason for the disconnect
+ */
+static void
+handle_client_listener_error (void *cls,
+ enum GNUNET_MQ_Error error)
+{
+ struct GNUNET_SET_ListenHandle *lh = cls;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Listener broke down (%d), re-connecting\n",
+ (int) error);
+ GNUNET_MQ_destroy (lh->mq);
+ lh->mq = NULL;
+ lh->reconnect_task = GNUNET_SCHEDULER_add_delayed (lh->reconnect_backoff,
+ &listen_connect,
+ lh);
+ lh->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (lh->reconnect_backoff);
+}
+
+
+/**
+ * Connect to the set service in order to listen for requests.
+ *
+ * @param cls the `struct GNUNET_SET_ListenHandle *` to connect
+ */
+static void
+listen_connect (void *cls)
+{
+ struct GNUNET_SET_ListenHandle *lh = cls;
+ struct GNUNET_MQ_MessageHandler mq_handlers[] = {
+ GNUNET_MQ_hd_var_size (request,
+ GNUNET_MESSAGE_TYPE_SET_REQUEST,
+ struct GNUNET_SET_RequestMessage,
+ lh),
+ GNUNET_MQ_handler_end ()
+ };
+ struct GNUNET_MQ_Envelope *mqm;
+ struct GNUNET_SET_ListenMessage *msg;
+
+ lh->reconnect_task = NULL;