ticket duplicates fix
[oweals/gnunet.git] / src / reclaim / gnunet-service-reclaim.c
index 0f0de86d3981d18fa6e4a82dafed1200a09ae5ef..57bff8ed463effebc574725e10174b1f7fe633d8 100644 (file)
  *
  */
 #include "platform.h"
-
 #include "gnunet_util_lib.h"
-
 #include "gnunet-service-reclaim_tickets.h"
 #include "gnunet_constants.h"
 #include "gnunet_gnsrecord_lib.h"
-#include "gnunet_identity_service.h"
-#include "gnunet_namestore_service.h"
 #include "gnunet_protocols.h"
 #include "gnunet_reclaim_attribute_lib.h"
 #include "gnunet_reclaim_service.h"
 #include "gnunet_signatures.h"
 #include "reclaim.h"
 
-/**
- * First pass state
- */
-#define STATE_INIT 0
-
-/**
- * Normal operation state
- */
-#define STATE_POST_INIT 1
-
-/**
- * Minimum interval between updates
- */
-#define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
-
-/**
- * Standard token expiration time
- */
-#define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
-
-/**
- * Identity handle
- */
-static struct GNUNET_IDENTITY_Handle *identity_handle;
-
-/**
- * Token expiration interval
- */
-static struct GNUNET_TIME_Relative token_expiration_interval;
 
 /**
  * Namestore handle
@@ -78,11 +45,6 @@ static struct GNUNET_NAMESTORE_Handle *nsh;
  */
 static struct GNUNET_SCHEDULER_Task *timeout_task;
 
-/**
- * Update task
- */
-static struct GNUNET_SCHEDULER_Task *update_task;
-
 /**
  * Our configuration.
  */
@@ -124,6 +86,7 @@ struct TicketIteration
   struct RECLAIM_TICKETS_Iterator *iter;
 };
 
+
 /**
  * An attribute iteration operation.
  */
@@ -160,11 +123,21 @@ struct AttributeIterator
   uint32_t request_id;
 };
 
+
 /**
  * An idp client
  */
 struct IdpClient
 {
+  /**
+   * DLL
+   */
+  struct IdpClient *prev;
+
+  /**
+   * DLL
+   */
+  struct IdpClient *next;
 
   /**
    * The client
@@ -251,6 +224,9 @@ struct IdpClient
 };
 
 
+/**
+ * Handle for attribute deletion request
+ */
 struct AttributeDeleteHandle
 {
   /**
@@ -311,6 +287,9 @@ struct AttributeDeleteHandle
 };
 
 
+/**
+ * Handle for attribute store request
+ */
 struct AttributeStoreHandle
 {
   /**
@@ -359,6 +338,10 @@ struct AttributeStoreHandle
   uint32_t r_id;
 };
 
+
+/**
+ * Handle for ticket consume request
+ */
 struct ConsumeTicketOperation
 {
   /**
@@ -387,31 +370,6 @@ struct ConsumeTicketOperation
   struct RECLAIM_TICKETS_ConsumeHandle *ch;
 };
 
-/**
- * Updated attribute IDs
- */
-struct TicketAttributeUpdateEntry
-{
-  /**
-   * DLL
-   */
-  struct TicketAttributeUpdateEntry *next;
-
-  /**
-   * DLL
-   */
-  struct TicketAttributeUpdateEntry *prev;
-
-  /**
-   * The old ID
-   */
-  uint64_t old_id;
-
-  /**
-   * The new ID
-   */
-  uint64_t new_id;
-};
 
 /**
  * Ticket revocation request handle
@@ -444,6 +402,7 @@ struct TicketRevocationOperation
   uint32_t r_id;
 };
 
+
 /**
  * Ticket issue operation handle
  */
@@ -470,33 +429,123 @@ struct TicketIssueOperation
   uint32_t r_id;
 };
 
+
+/**
+ * Client list
+ */
+static struct IdpClient *client_list_head = NULL;
+
 /**
- * DLL for ego handles to egos containing the RECLAIM_ATTRS in a
- * map in json_t format
+ * Client list
+ */
+static struct IdpClient *client_list_tail = NULL;
+
+
+/**
+ * Cleanup attribute delete handle
  *
+ * @param adh the attribute to cleanup
  */
-struct EgoEntry
+static void
+cleanup_adh (struct AttributeDeleteHandle *adh)
 {
-  /**
-   * DLL
-   */
-  struct EgoEntry *next;
+  struct TicketRecordsEntry *le;
+  if (NULL != adh->ns_it)
+    GNUNET_NAMESTORE_zone_iteration_stop (adh->ns_it);
+  if (NULL != adh->ns_qe)
+    GNUNET_NAMESTORE_cancel (adh->ns_qe);
+  if (NULL != adh->label)
+    GNUNET_free (adh->label);
+  if (NULL != adh->claim)
+    GNUNET_free (adh->claim);
+  while (NULL != (le = adh->tickets_to_update_head)) {
+    GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
+                                 adh->tickets_to_update_tail,
+                                 le);
+    if (NULL != le->label)
+      GNUNET_free (le->label);
+    if (NULL != le->data)
+      GNUNET_free (le->data);
+    GNUNET_free (le);
+  }
+  GNUNET_free (adh);
+}
 
-  /**
-   * DLL
-   */
-  struct EgoEntry *prev;
 
-  /**
-   * Ego handle
-   */
-  struct GNUNET_IDENTITY_Ego *ego;
+/**
+ * Cleanup attribute store handle
+ *
+ * @param handle handle to clean up
+ */
+static void
+cleanup_as_handle (struct AttributeStoreHandle *ash)
+{
+  if (NULL != ash->ns_qe)
+    GNUNET_NAMESTORE_cancel (ash->ns_qe);
+  if (NULL != ash->claim)
+    GNUNET_free (ash->claim);
+  GNUNET_free (ash);
+}
+
+
+/**
+ * Cleanup client
+ *
+ * @param idp the client to clean up
+ */
+static void
+cleanup_client (struct IdpClient *idp)
+{
+  struct AttributeIterator *ai;
+  struct TicketIteration *ti;
+  struct TicketRevocationOperation *rop;
+  struct TicketIssueOperation *iss;
+  struct ConsumeTicketOperation *ct;
+  struct AttributeStoreHandle *as;
+  struct AttributeDeleteHandle *adh;
+
+  while (NULL != (iss = idp->issue_op_head)) {
+    GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, idp->issue_op_tail, iss);
+    GNUNET_free (iss);
+  }
+  while (NULL != (ct = idp->consume_op_head)) {
+    GNUNET_CONTAINER_DLL_remove (idp->consume_op_head,
+                                 idp->consume_op_tail,
+                                 ct);
+    if (NULL != ct->ch)
+      RECLAIM_TICKETS_consume_cancel (ct->ch);
+    GNUNET_free (ct);
+  }
+  while (NULL != (as = idp->store_op_head)) {
+    GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as);
+    cleanup_as_handle (as);
+  }
+  while (NULL != (adh = idp->delete_op_head)) {
+    GNUNET_CONTAINER_DLL_remove (idp->delete_op_head, idp->delete_op_tail, adh);
+    cleanup_adh (adh);
+  }
+
+  while (NULL != (ai = idp->attr_iter_head)) {
+    GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
+    GNUNET_free (ai);
+  }
+  while (NULL != (rop = idp->revoke_op_head)) {
+    GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, idp->revoke_op_tail, rop);
+    if (NULL != rop->rh)
+      RECLAIM_TICKETS_revoke_cancel (rop->rh);
+    GNUNET_free (rop);
+  }
+  while (NULL != (ti = idp->ticket_iter_head)) {
+    GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
+                                 idp->ticket_iter_tail,
+                                 ti);
+    if (NULL != ti->iter)
+      RECLAIM_TICKETS_iteration_stop (ti->iter);
+    GNUNET_free (ti);
+  }
+  GNUNET_free (idp);
+}
 
-  /**
-   * Attribute map. Contains the attributes as json_t
-   */
-  struct GNUNET_CONTAINER_MultiHashMap *attr_map;
-};
 
 /**
  * Cleanup task
@@ -504,19 +553,24 @@ struct EgoEntry
 static void
 cleanup ()
 {
+  struct IdpClient *cl;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
 
+  while (NULL != (cl = client_list_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (client_list_head,
+                                 client_list_tail,
+                                 cl);
+    cleanup_client (cl);
+  }
   RECLAIM_TICKETS_deinit ();
   if (NULL != timeout_task)
     GNUNET_SCHEDULER_cancel (timeout_task);
-  if (NULL != update_task)
-    GNUNET_SCHEDULER_cancel (update_task);
-  if (NULL != identity_handle)
-    GNUNET_IDENTITY_disconnect (identity_handle);
   if (NULL != nsh)
     GNUNET_NAMESTORE_disconnect (nsh);
 }
 
+
 /**
  * Shutdown task
  *
@@ -530,47 +584,74 @@ do_shutdown (void *cls)
 }
 
 
+/**
+ * Sends a ticket result message to the client
+ *
+ * @param client the client to send to
+ * @param r_id the request message ID to reply to
+ * @param ticket the ticket to include (may be NULL)
+ * @param success the success status of the request
+ */
 static void
-send_ticket_result (const struct IdpClient *client, uint32_t r_id,
+send_ticket_result (const struct IdpClient *client,
+                    uint32_t r_id,
                     const struct GNUNET_RECLAIM_Ticket *ticket,
                     uint32_t success)
 {
   struct TicketResultMessage *irm;
   struct GNUNET_MQ_Envelope *env;
-  struct GNUNET_RECLAIM_Ticket *ticket_buf;
 
+  env = GNUNET_MQ_msg (irm,
+                       GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
   if (NULL != ticket) {
-    env = GNUNET_MQ_msg_extra (irm, sizeof (struct GNUNET_RECLAIM_Ticket),
-                               GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
-    ticket_buf = (struct GNUNET_RECLAIM_Ticket *)&irm[1];
-    *ticket_buf = *ticket;
-  } else {
-    env = GNUNET_MQ_msg (irm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
+    irm->ticket = *ticket;
   }
   // TODO add success member
   irm->id = htonl (r_id);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
   GNUNET_MQ_send (client->mq, env);
 }
 
+
+/**
+ * Issue ticket result
+ *
+ * @param cls out ticket issue operation handle
+ * @param ticket the issued ticket
+ * @param success issue success status (GNUNET_OK if successful)
+ * @param emsg error message (NULL of success is GNUNET_OK)
+ */
 static void
-issue_ticket_result_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket,
-                        int32_t success, const char *emsg)
+issue_ticket_result_cb (void *cls,
+                        struct GNUNET_RECLAIM_Ticket *ticket,
+                        int32_t success,
+                        const char *emsg)
 {
   struct TicketIssueOperation *tio = cls;
   if (GNUNET_OK != success) {
     send_ticket_result (tio->client, tio->r_id, NULL, GNUNET_SYSERR);
     GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
-                                 tio->client->issue_op_tail, tio);
+                                 tio->client->issue_op_tail,
+                                 tio);
     GNUNET_free (tio);
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error issuing ticket: %s\n", emsg);
     return;
   }
   send_ticket_result (tio->client, tio->r_id, ticket, GNUNET_SYSERR);
   GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
-                               tio->client->issue_op_tail, tio);
+                               tio->client->issue_op_tail,
+                               tio);
   GNUNET_free (tio);
 }
 
+
+/**
+ * Check issue ticket message
+ *
+ * @cls unused
+ * @im message to check
+ * @return GNUNET_OK if message is ok
+ */
 static int
 check_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
 {
@@ -584,6 +665,13 @@ check_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
   return GNUNET_OK;
 }
 
+
+/**
+ * Handle ticket issue message
+ *
+ * @param cls our client
+ * @param im the message
+ */
 static void
 handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
 {
@@ -592,22 +680,34 @@ handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
   size_t attrs_len;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ISSUE_TICKET message\n");
   tio = GNUNET_new (struct TicketIssueOperation);
   attrs_len = ntohs (im->attr_len);
   attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *)&im[1], attrs_len);
   tio->r_id = ntohl (im->id);
   tio->client = idp;
   GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, idp->issue_op_tail, tio);
-  RECLAIM_TICKETS_issue (&im->identity, attrs, &im->rp, &issue_ticket_result_cb,
+  RECLAIM_TICKETS_issue (&im->identity,
+                         attrs,
+                         &im->rp,
+                         &issue_ticket_result_cb,
                          tio);
   GNUNET_SERVICE_client_continue (idp->client);
   GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
 }
 
+
+
 /**********************************************************
  * Revocation
  **********************************************************/
 
+/**
+ * Handles revocation result
+ *
+ * @param cls our revocation operation handle
+ * @param success revocation result (GNUNET_OK if successful)
+ */
 static void
 revoke_result_cb (void *cls, int32_t success)
 {
@@ -615,65 +715,78 @@ revoke_result_cb (void *cls, int32_t success)
   struct GNUNET_MQ_Envelope *env;
   struct RevokeTicketResultMessage *trm;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending REVOKE_TICKET_RESULT message\n");
   rop->rh = NULL;
   env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT);
   trm->id = htonl (rop->r_id);
   trm->success = htonl (success);
   GNUNET_MQ_send (rop->client->mq, env);
   GNUNET_CONTAINER_DLL_remove (rop->client->revoke_op_head,
-                               rop->client->revoke_op_tail, rop);
+                               rop->client->revoke_op_tail,
+                               rop);
   GNUNET_free (rop);
 }
 
 
+/**
+ * Check revocation message format
+ *
+ * @param cls unused
+ * @param im the message to check
+ * @return GNUNET_OK if message is ok
+ */
 static int
 check_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *im)
 {
   uint16_t size;
 
   size = ntohs (im->header.size);
-  if (size <= sizeof (struct RevokeTicketMessage)) {
+  if (size != sizeof (struct RevokeTicketMessage)) {
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
   return GNUNET_OK;
 }
 
+
+/**
+ * Handle a revocation message to a ticket.
+ *
+ * @param cls our client
+ * @param rm the message to handle
+ */
 static void
 handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm)
 {
   struct TicketRevocationOperation *rop;
   struct IdpClient *idp = cls;
-  struct GNUNET_RECLAIM_Ticket *ticket;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REVOKE_TICKET message\n");
   rop = GNUNET_new (struct TicketRevocationOperation);
-  ticket = (struct GNUNET_RECLAIM_Ticket *)&rm[1];
   rop->r_id = ntohl (rm->id);
   rop->client = idp;
   GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, idp->revoke_op_tail, rop);
-  rop->rh =
-      RECLAIM_TICKETS_revoke (ticket, &rm->identity, &revoke_result_cb, rop);
+  rop->rh
+    = RECLAIM_TICKETS_revoke (&rm->ticket, &rm->identity, &revoke_result_cb, rop);
   GNUNET_SERVICE_client_continue (idp->client);
 }
 
-static int
-check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
-{
-  uint16_t size;
-
-  size = ntohs (cm->header.size);
-  if (size <= sizeof (struct ConsumeTicketMessage)) {
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
 
+/**
+ * Handle a ticket consume result
+ *
+ * @param cls our consume ticket operation handle
+ * @param identity the attribute authority
+ * @param attrs the attribute/claim list
+ * @param success GNUNET_OK if successful
+ * @param emsg error message (NULL if success=GNUNET_OK)
+ */
 static void
 consume_result_cb (void *cls,
                    const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
                    const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
-                   int32_t success, const char *emsg)
+                   int32_t success,
+                   const char *emsg)
 {
   struct ConsumeTicketOperation *cop = cls;
   struct ConsumeTicketResultMessage *crm;
@@ -684,7 +797,9 @@ consume_result_cb (void *cls,
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error consuming ticket: %s\n", emsg);
   }
   attrs_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
-  env = GNUNET_MQ_msg_extra (crm, attrs_len,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CONSUME_TICKET_RESULT message\n");
+  env = GNUNET_MQ_msg_extra (crm,
+                             attrs_len,
                              GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
   crm->id = htonl (cop->r_id);
   crm->attrs_len = htons (attrs_len);
@@ -694,23 +809,50 @@ consume_result_cb (void *cls,
   GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, data_tmp);
   GNUNET_MQ_send (cop->client->mq, env);
   GNUNET_CONTAINER_DLL_remove (cop->client->consume_op_head,
-                               cop->client->consume_op_tail, cop);
+                               cop->client->consume_op_tail,
+                               cop);
   GNUNET_free (cop);
 }
 
+
+/**
+ * Check a consume ticket message
+ *
+ * @param cls unused
+ * @param cm the message to handle
+ */
+static int
+check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
+{
+  uint16_t size;
+
+  size = ntohs (cm->header.size);
+  if (size != sizeof (struct ConsumeTicketMessage)) {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Handle a consume ticket message
+ *
+ * @param cls our client handle
+ * @cm the message to handle
+ */
 static void
 handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
 {
   struct ConsumeTicketOperation *cop;
-  struct GNUNET_RECLAIM_Ticket *ticket;
   struct IdpClient *idp = cls;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CONSUME_TICKET message\n");
   cop = GNUNET_new (struct ConsumeTicketOperation);
   cop->r_id = ntohl (cm->id);
   cop->client = idp;
-  ticket = (struct GNUNET_RECLAIM_Ticket *)&cm[1];
-  cop->ch =
-      RECLAIM_TICKETS_consume (&cm->identity, ticket, &consume_result_cb, cop);
+  cop->ch
+    = RECLAIM_TICKETS_consume (&cm->identity, &cm->ticket, &consume_result_cb, cop);
   GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop);
   GNUNET_SERVICE_client_continue (idp->client);
 }
@@ -719,21 +861,14 @@ handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
  * Attribute store
  *****************************************/
 
+
 /**
- * Cleanup attribute store handle
+ * Attribute store result handler
  *
- * @param handle handle to clean up
+ * @param cls our attribute store handle
+ * @param success GNUNET_OK if successful
+ * @param emsg error message (NULL if success=GNUNET_OK)
  */
-static void
-cleanup_as_handle (struct AttributeStoreHandle *ash)
-{
-  if (NULL != ash->ns_qe)
-    GNUNET_NAMESTORE_cancel (ash->ns_qe);
-  if (NULL != ash->claim)
-    GNUNET_free (ash->claim);
-  GNUNET_free (ash);
-}
-
 static void
 attr_store_cont (void *cls, int32_t success, const char *emsg)
 {
@@ -743,10 +878,12 @@ attr_store_cont (void *cls, int32_t success, const char *emsg)
 
   ash->ns_qe = NULL;
   GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
-                               ash->client->store_op_tail, ash);
+                               ash->client->store_op_tail,
+                               ash);
 
   if (GNUNET_SYSERR == success) {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to store attribute %s\n",
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to store attribute %s\n",
                 emsg);
     cleanup_as_handle (ash);
     GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
@@ -761,8 +898,9 @@ attr_store_cont (void *cls, int32_t success, const char *emsg)
   cleanup_as_handle (ash);
 }
 
+
 /**
- * Adds a new attribute
+ * Add a new attribute
  *
  * @param cls the AttributeStoreHandle
  */
@@ -780,11 +918,11 @@ attr_store_task (void *cls)
   buf = GNUNET_malloc (buf_size);
   // Give the ash a new id if unset
   if (0 == ash->claim->id)
-    ash->claim->id =
-        GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+    ash->claim->id
+      = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
   GNUNET_RECLAIM_ATTRIBUTE_serialize (ash->claim, buf);
-  label =
-      GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id, sizeof (uint64_t));
+  label
+    = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id, sizeof (uint64_t));
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
 
   rd[0].data_size = buf_size;
@@ -792,11 +930,24 @@ attr_store_task (void *cls)
   rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR;
   rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
   rd[0].expiration_time = ash->exp.rel_value_us;
-  ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &ash->identity, label, 1,
-                                               rd, &attr_store_cont, ash);
+  ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                               &ash->identity,
+                                               label,
+                                               1,
+                                               rd,
+                                               &attr_store_cont,
+                                               ash);
   GNUNET_free (buf);
+  GNUNET_free (label);
 }
 
+
+/**
+ * Check an attribute store message
+ *
+ * @param cls unused
+ * @param sam the message to check
+ */
 static int
 check_attribute_store_message (void *cls,
                                const struct AttributeStoreMessage *sam)
@@ -811,6 +962,13 @@ check_attribute_store_message (void *cls,
   return GNUNET_OK;
 }
 
+
+/**
+ * Handle an attribute store message
+ *
+ * @param cls our client
+ * @param sam the message to handle
+ */
 static void
 handle_attribute_store_message (void *cls,
                                 const struct AttributeStoreMessage *sam)
@@ -837,31 +995,12 @@ handle_attribute_store_message (void *cls,
 }
 
 
-static void
-cleanup_adh (struct AttributeDeleteHandle *adh)
-{
-  struct TicketRecordsEntry *le;
-  if (NULL != adh->ns_it)
-    GNUNET_NAMESTORE_zone_iteration_stop (adh->ns_it);
-  if (NULL != adh->ns_qe)
-    GNUNET_NAMESTORE_cancel (adh->ns_qe);
-  if (NULL != adh->label)
-    GNUNET_free (adh->label);
-  if (NULL != adh->claim)
-    GNUNET_free (adh->claim);
-  while (NULL != (le = adh->tickets_to_update_head)) {
-    GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
-                                 adh->tickets_to_update_tail, le);
-    if (NULL != le->label)
-      GNUNET_free (le->label);
-    if (NULL != le->data)
-      GNUNET_free (le->data);
-    GNUNET_free (le);
-  }
-  GNUNET_free (adh);
-}
-
-
+/**
+ * Send a deletion success response
+ *
+ * @param adh our attribute deletion handle
+ * @param success the success status
+ */
 static void
 send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
 {
@@ -869,7 +1008,8 @@ send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
   struct SuccessResultMessage *acr_msg;
 
   GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
-                               adh->client->delete_op_tail, adh);
+                               adh->client->delete_op_tail,
+                               adh);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
   env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
@@ -879,9 +1019,21 @@ send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
 }
 
 
+/**
+ * Namestore iteration within attribute deletion.
+ * We need to reissue tickets with the deleted attribute removed.
+ *
+ * @param cls our attribute deletion handle
+ * @param zone the private key of the ticket issuer
+ * @param label the label of the record
+ * @param rd_count number of records
+ * @param rd record data
+ */
 static void
-ticket_iter (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
-             const char *label, unsigned int rd_count,
+ticket_iter (void *cls,
+             const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+             const char *label,
+             unsigned int rd_count,
              const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct AttributeDeleteHandle *adh = cls;
@@ -893,7 +1045,8 @@ ticket_iter (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
       continue;
     if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t)))
       continue;
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attribute to delete found (%s)\n",
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Attribute to delete found (%s)\n",
                 adh->label);
     has_changed = GNUNET_YES;
     break;
@@ -906,16 +1059,28 @@ ticket_iter (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
     le->label = GNUNET_strdup (label);
     GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
     GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head,
-                                 adh->tickets_to_update_tail, le);
+                                 adh->tickets_to_update_tail,
+                                 le);
   }
   GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
 }
 
 
+/**
+ * Recursion prototype for function
+ * @param cls our deletion handle
+ */
 static void
 update_tickets (void *cls);
 
 
+/**
+ * Callback called when a ticket was updated
+ *
+ * @param cls our attribute deletion handle
+ * @param success GNUNET_OK if successful
+ * @param emsg error message (NULL if success=GNUNET_OK)
+ */
 static void
 ticket_updated (void *cls, int32_t success, const char *emsg)
 {
@@ -924,6 +1089,14 @@ ticket_updated (void *cls, int32_t success, const char *emsg)
   GNUNET_SCHEDULER_add_now (&update_tickets, adh);
 }
 
+
+/**
+ * Update tickets: Remove shared attribute which has just been deleted.
+ * This method is called recursively until all tickets are processed.
+ * Eventually, the updated tickets are stored using ``update_tickets''.
+ *
+ * @param cls our attribute deletion handle
+ */
 static void
 update_tickets (void *cls)
 {
@@ -936,31 +1109,52 @@ update_tickets (void *cls)
     cleanup_adh (adh);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating %s\n",
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Updating %s\n",
               adh->tickets_to_update_head->label);
   le = adh->tickets_to_update_head;
   GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
-                               adh->tickets_to_update_tail, le);
+                               adh->tickets_to_update_tail,
+                               le);
   struct GNUNET_GNSRECORD_Data rd[le->rd_count];
   struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1];
-  GNUNET_GNSRECORD_records_deserialize (le->data_size, le->data, le->rd_count,
-                                        rd);
+  if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
+                                        le->data,
+                                        le->rd_count,
+                                        rd))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unable to deserialize record data!\n");
+    send_delete_response (adh, GNUNET_SYSERR);
+    cleanup_adh (adh);
+    return;
+  }
   int j = 0;
   for (int i = 0; i < le->rd_count; i++) {
-    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type) &&
-        (0 == memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t))))
+    if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
+        && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t))))
       continue;
     rd_new[j] = rd[i];
     j++;
   }
-  adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &adh->identity, le->label,
-                                               j, rd_new, &ticket_updated, adh);
+  adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                               &adh->identity,
+                                               le->label,
+                                               j,
+                                               rd_new,
+                                               &ticket_updated,
+                                               adh);
   GNUNET_free (le->label);
   GNUNET_free (le->data);
   GNUNET_free (le);
 }
 
 
+/**
+ * Done collecting affected tickets, start updating.
+ *
+ * @param cls our attribute deletion handle
+ */
 static void
 ticket_iter_fin (void *cls)
 {
@@ -970,45 +1164,76 @@ ticket_iter_fin (void *cls)
 }
 
 
+/**
+ * Error collecting affected tickets. Abort.
+ *
+ * @param cls our attribute deletion handle
+ */
 static void
 ticket_iter_err (void *cls)
 {
   struct AttributeDeleteHandle *adh = cls;
   adh->ns_it = NULL;
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Namestore error on delete %s\n",
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Namestore error on delete %s\n",
               adh->label);
   send_delete_response (adh, GNUNET_SYSERR);
   cleanup_adh (adh);
 }
 
 
+/**
+ * Start processing tickets which may still contain reference to deleted
+ * attribute.
+ *
+ * @param cls attribute deletion handle
+ */
 static void
 start_ticket_update (void *cls)
 {
   struct AttributeDeleteHandle *adh = cls;
-  adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
-      nsh, &adh->identity, &ticket_iter_err, adh, &ticket_iter, adh,
-      &ticket_iter_fin, adh);
+  adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
+                                                      &adh->identity,
+                                                      &ticket_iter_err,
+                                                      adh,
+                                                      &ticket_iter,
+                                                      adh,
+                                                      &ticket_iter_fin,
+                                                      adh);
 }
 
 
+/**
+ * Attribute deleted callback
+ *
+ * @param cls our handle
+ * @param success success status
+ * @param emsg error message (NULL if success=GNUNET_OK)
+ */
 static void
 attr_delete_cont (void *cls, int32_t success, const char *emsg)
 {
   struct AttributeDeleteHandle *adh = cls;
   adh->ns_qe = NULL;
   if (GNUNET_SYSERR == success) {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error deleting attribute %s\n",
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Error deleting attribute %s\n",
                 adh->label);
     send_delete_response (adh, GNUNET_SYSERR);
     cleanup_adh (adh);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating tickets...\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
   GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
 }
 
 
+/**
+ * Check attribute delete message format
+ *
+ * @cls unused
+ * @dam message to check
+ */
 static int
 check_attribute_delete_message (void *cls,
                                 const struct AttributeDeleteMessage *dam)
@@ -1024,6 +1249,12 @@ check_attribute_delete_message (void *cls,
 }
 
 
+/**
+ * Handle attribute deletion
+ *
+ * @param cls our client
+ * @param dam deletion message
+ */
 static void
 handle_attribute_delete_message (void *cls,
                                  const struct AttributeDeleteMessage *dam)
@@ -1031,7 +1262,7 @@ handle_attribute_delete_message (void *cls,
   struct AttributeDeleteHandle *adh;
   struct IdpClient *idp = cls;
   size_t data_len;
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received ATTRIBUTE_DELETE message\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_DELETE message\n");
 
   data_len = ntohs (dam->attr_len);
 
@@ -1040,13 +1271,18 @@ handle_attribute_delete_message (void *cls,
 
   adh->r_id = ntohl (dam->id);
   adh->identity = dam->identity;
-  adh->label =
-      GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id, sizeof (uint64_t));
+  adh->label
+    = GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id, sizeof (uint64_t));
   GNUNET_SERVICE_client_continue (idp->client);
   adh->client = idp;
   GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
-  adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &adh->identity, adh->label,
-                                               0, NULL, &attr_delete_cont, adh);
+  adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+                                               &adh->identity,
+                                               adh->label,
+                                               0,
+                                               NULL,
+                                               &attr_delete_cont,
+                                               adh);
 }
 
 
@@ -1054,23 +1290,12 @@ handle_attribute_delete_message (void *cls,
  * Attrubute iteration
  *************************************************/
 
-static void
-cleanup_attribute_iter_handle (struct AttributeIterator *ai)
-{
-  GNUNET_free (ai);
-}
-
-static void
-attr_iter_error (void *cls)
-{
-  struct AttributeIterator *ai = cls;
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
-  GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
-                               ai->client->attr_iter_tail, ai);
-  cleanup_attribute_iter_handle (ai);
-  GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
-}
 
+/**
+ * Done iterating over attributes
+ *
+ * @param cls our iterator handle
+ */
 static void
 attr_iter_finished (void *cls)
 {
@@ -1078,18 +1303,46 @@ attr_iter_finished (void *cls)
   struct GNUNET_MQ_Envelope *env;
   struct AttributeResultMessage *arm;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
   env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
   arm->id = htonl (ai->request_id);
   arm->attr_len = htons (0);
   GNUNET_MQ_send (ai->client->mq, env);
   GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
-                               ai->client->attr_iter_tail, ai);
-  cleanup_attribute_iter_handle (ai);
+                               ai->client->attr_iter_tail,
+                               ai);
+  GNUNET_free (ai);
 }
 
+/**
+ * Error iterating over attributes. Abort.
+ *
+ * @param cls our attribute iteration handle
+ */
 static void
-attr_iter_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
-              const char *label, unsigned int rd_count,
+attr_iter_error (void *cls)
+{
+  struct AttributeIterator *ai = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
+  attr_iter_finished (ai);
+}
+
+
+/**
+ * Got record. Return if it is an attribute.
+ *
+ * @param cls our attribute iterator
+ * @param zone zone we are iterating
+ * @param label label of the records
+ * @param rd_count record count
+ * @param rd records
+ */
+static void
+attr_iter_cb (void *cls,
+              const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+              const char *label,
+              unsigned int rd_count,
               const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct AttributeIterator *ai = cls;
@@ -1107,7 +1360,9 @@ attr_iter_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
     return;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n", label);
-  env = GNUNET_MQ_msg_extra (arm, rd->data_size,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
+  env = GNUNET_MQ_msg_extra (arm,
+                             rd->data_size,
                              GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
   arm->id = htonl (ai->request_id);
   arm->attr_len = htons (rd->data_size);
@@ -1117,6 +1372,13 @@ attr_iter_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
   GNUNET_MQ_send (ai->client->mq, env);
 }
 
+
+/**
+ * Iterate over zone to get attributes
+ *
+ * @param cls our client
+ * @param ais_msg the iteration message to start
+ */
 static void
 handle_iteration_start (void *cls,
                         const struct AttributeIterationStartMessage *ais_msg)
@@ -1132,12 +1394,24 @@ handle_iteration_start (void *cls,
   ai->identity = ais_msg->identity;
 
   GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, idp->attr_iter_tail, ai);
-  ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
-      nsh, &ai->identity, &attr_iter_error, ai, &attr_iter_cb, ai,
-      &attr_iter_finished, ai);
+  ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
+                                                     &ai->identity,
+                                                     &attr_iter_error,
+                                                     ai,
+                                                     &attr_iter_cb,
+                                                     ai,
+                                                     &attr_iter_finished,
+                                                     ai);
   GNUNET_SERVICE_client_continue (idp->client);
 }
 
+
+/**
+ * Handle iteration stop message from client
+ *
+ * @param cls the client
+ * @param ais_msg the stop message
+ */
 static void
 handle_iteration_stop (void *cls,
                        const struct AttributeIterationStopMessage *ais_msg)
@@ -1146,7 +1420,8 @@ handle_iteration_stop (void *cls,
   struct AttributeIterator *ai;
   uint32_t rid;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n",
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received `%s' message\n",
               "ATTRIBUTE_ITERATION_STOP");
   rid = ntohl (ais_msg->id);
   for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
@@ -1162,6 +1437,13 @@ handle_iteration_stop (void *cls,
   GNUNET_SERVICE_client_continue (idp->client);
 }
 
+
+/**
+ * Client requests next attribute from iterator
+ *
+ * @param cls the client
+ * @param ais_msg the message
+ */
 static void
 handle_iteration_next (void *cls,
                        const struct AttributeIterationNextMessage *ais_msg)
@@ -1189,6 +1471,12 @@ handle_iteration_next (void *cls,
  * Ticket iteration
  ******************************************************/
 
+/**
+ * Got a ticket. Return to client
+ *
+ * @param cls our ticket iterator
+ * @param ticket the ticket
+ */
 static void
 ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
 {
@@ -1196,25 +1484,33 @@ ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
   struct GNUNET_MQ_Envelope *env;
   struct TicketResultMessage *trm;
 
+  env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
   if (NULL == ticket) {
     /* send empty response to indicate end of list */
-    env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
     GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
-                                 ti->client->ticket_iter_tail, ti);
+                                 ti->client->ticket_iter_tail,
+                                 ti);
   } else {
-    env = GNUNET_MQ_msg_extra (trm, sizeof (struct GNUNET_RECLAIM_Ticket),
-                               GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
-    memcpy (&trm[1], ticket, sizeof (struct GNUNET_RECLAIM_Ticket));
+    trm->ticket = *ticket;
   }
   trm->id = htonl (ti->r_id);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
   GNUNET_MQ_send (ti->client->mq, env);
   if (NULL == ticket)
     GNUNET_free (ti);
 }
 
+
+/**
+ * Client requests a ticket iteration
+ *
+ * @param cls the client
+ * @param tis_msg the iteration request message
+ */
 static void
 handle_ticket_iteration_start (
-    void *cls, const struct TicketIterationStartMessage *tis_msg)
+                               void *cls,
+                               const struct TicketIterationStartMessage *tis_msg)
 {
   struct IdpClient *client = cls;
   struct TicketIteration *ti;
@@ -1226,12 +1522,20 @@ handle_ticket_iteration_start (
   ti->client = client;
 
   GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
-                               client->ticket_iter_tail, ti);
-  ti->iter =
-      RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti);
+                               client->ticket_iter_tail,
+                               ti);
+  ti->iter
+    = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti);
   GNUNET_SERVICE_client_continue (client->client);
 }
 
+
+/**
+ * Client has had enough tickets
+ *
+ * @param cls the client
+ * @param tis_msg the stop message
+ */
 static void
 handle_ticket_iteration_stop (void *cls,
                               const struct TicketIterationStopMessage *tis_msg)
@@ -1240,7 +1544,8 @@ handle_ticket_iteration_stop (void *cls,
   struct TicketIteration *ti;
   uint32_t rid;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n",
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received `%s' message\n",
               "TICKET_ITERATION_STOP");
   rid = ntohl (tis_msg->id);
   for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
@@ -1253,11 +1558,19 @@ handle_ticket_iteration_stop (void *cls,
   }
   RECLAIM_TICKETS_iteration_stop (ti->iter);
   GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
-                               client->ticket_iter_tail, ti);
+                               client->ticket_iter_tail,
+                               ti);
   GNUNET_free (ti);
   GNUNET_SERVICE_client_continue (client->client);
 }
 
+
+/**
+ * Client requests next result.
+ *
+ * @param cls the client
+ * @param tis_msg the message
+ */
 static void
 handle_ticket_iteration_next (void *cls,
                               const struct TicketIterationNextMessage *tis_msg)
@@ -1281,6 +1594,7 @@ handle_ticket_iteration_next (void *cls,
   GNUNET_SERVICE_client_continue (client->client);
 }
 
+
 /**
  * Main function that will be run
  *
@@ -1289,14 +1603,15 @@ handle_ticket_iteration_next (void *cls,
  * @param server the service handle
  */
 static void
-run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c,
+run (void *cls,
+     const struct GNUNET_CONFIGURATION_Handle *c,
      struct GNUNET_SERVICE_Handle *server)
 {
   cfg = c;
 
   if (GNUNET_OK != RECLAIM_TICKETS_init (cfg)) {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unable to initialized TICKETS subsystem.\n");
+                "Unable to initialize TICKETS subsystem.\n");
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
@@ -1307,21 +1622,10 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c,
                          "error connecting to namestore");
   }
 
-  identity_handle = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
-
-  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (
-                       cfg, "reclaim", "TOKEN_EXPIRATION_INTERVAL",
-                       &token_expiration_interval)) {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Time window for zone iteration: %s\n",
-                GNUNET_STRINGS_relative_time_to_string (
-                    token_expiration_interval, GNUNET_YES));
-  } else {
-    token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
-  }
-
   GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
 }
 
+
 /**
  * Called whenever a client is disconnected.
  *
@@ -1330,60 +1634,19 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c,
  * @param app_ctx @a client
  */
 static void
-client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client,
+client_disconnect_cb (void *cls,
+                      struct GNUNET_SERVICE_Client *client,
                       void *app_ctx)
 {
   struct IdpClient *idp = app_ctx;
-  struct AttributeIterator *ai;
-  struct TicketIteration *ti;
-  struct TicketRevocationOperation *rop;
-  struct TicketIssueOperation *iss;
-  struct ConsumeTicketOperation *ct;
-  struct AttributeStoreHandle *as;
-  struct AttributeDeleteHandle *adh;
-
-  // TODO other operations
-
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
-
-  while (NULL != (iss = idp->issue_op_head)) {
-    GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, idp->issue_op_tail, iss);
-    GNUNET_free (iss);
-  }
-  while (NULL != (ct = idp->consume_op_head)) {
-    GNUNET_CONTAINER_DLL_remove (idp->consume_op_head, idp->consume_op_tail,
-                                 ct);
-    if (NULL != ct->ch)
-      RECLAIM_TICKETS_consume_cancel (ct->ch);
-    GNUNET_free (ct);
-  }
-  while (NULL != (as = idp->store_op_head)) {
-    GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as);
-    cleanup_as_handle (as);
-  }
-  while (NULL != (adh = idp->delete_op_head)) {
-    GNUNET_CONTAINER_DLL_remove (idp->delete_op_head, idp->delete_op_tail, adh);
-    cleanup_adh (adh);
-  }
-
-  while (NULL != (ai = idp->attr_iter_head)) {
-    GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
-    cleanup_attribute_iter_handle (ai);
-  }
-  while (NULL != (rop = idp->revoke_op_head)) {
-    GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, idp->revoke_op_tail, rop);
-    if (NULL != rop->rh)
-      RECLAIM_TICKETS_revoke_cancel (rop->rh);
-    GNUNET_free (rop);
-  }
-  while (NULL != (ti = idp->ticket_iter_head)) {
-    GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head, idp->ticket_iter_tail,
-                                 ti);
-    GNUNET_free (ti);
-  }
-  GNUNET_free (idp);
+  GNUNET_CONTAINER_DLL_remove (client_list_head,
+                               client_list_tail,
+                               idp);
+  cleanup_client (idp);
 }
 
+
 /**
  * Add a client to our list of active clients.
  *
@@ -1393,7 +1656,8 @@ client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client,
  * @return internal namestore client structure for this client
  */
 static void *
-client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *client,
+client_connect_cb (void *cls,
+                   struct GNUNET_SERVICE_Client *client,
                    struct GNUNET_MQ_Handle *mq)
 {
   struct IdpClient *idp;
@@ -1401,47 +1665,67 @@ client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *client,
   idp = GNUNET_new (struct IdpClient);
   idp->client = client;
   idp->mq = mq;
+  GNUNET_CONTAINER_DLL_insert (client_list_head,
+                               client_list_tail,
+                               idp);
   return idp;
 }
 
+
 /**
  * Define "main" method using service macro.
  */
 GNUNET_SERVICE_MAIN (
-    "reclaim", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb,
-    &client_disconnect_cb, NULL,
-    GNUNET_MQ_hd_var_size (attribute_store_message,
-                           GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
-                           struct AttributeStoreMessage, NULL),
-    GNUNET_MQ_hd_var_size (attribute_delete_message,
-                           GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
-                           struct AttributeDeleteMessage, NULL),
-    GNUNET_MQ_hd_fixed_size (
-        iteration_start, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
-        struct AttributeIterationStartMessage, NULL),
-    GNUNET_MQ_hd_fixed_size (
-        iteration_next, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
-        struct AttributeIterationNextMessage, NULL),
-    GNUNET_MQ_hd_fixed_size (
-        iteration_stop, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
-        struct AttributeIterationStopMessage, NULL),
-    GNUNET_MQ_hd_var_size (issue_ticket_message,
-                           GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
-                           struct IssueTicketMessage, NULL),
-    GNUNET_MQ_hd_var_size (consume_ticket_message,
-                           GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
-                           struct ConsumeTicketMessage, NULL),
-    GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
-                             GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
-                             struct TicketIterationStartMessage, NULL),
-    GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
-                             GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
-                             struct TicketIterationNextMessage, NULL),
-    GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
-                             GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
-                             struct TicketIterationStopMessage, NULL),
-    GNUNET_MQ_hd_var_size (revoke_ticket_message,
-                           GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
-                           struct RevokeTicketMessage, NULL),
-    GNUNET_MQ_handler_end ());
+                     "reclaim",
+                     GNUNET_SERVICE_OPTION_NONE,
+                     &run,
+                     &client_connect_cb,
+                     &client_disconnect_cb,
+                     NULL,
+                     GNUNET_MQ_hd_var_size (attribute_store_message,
+                                            GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
+                                            struct AttributeStoreMessage,
+                                            NULL),
+                     GNUNET_MQ_hd_var_size (attribute_delete_message,
+                                            GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
+                                            struct AttributeDeleteMessage,
+                                            NULL),
+                     GNUNET_MQ_hd_fixed_size (
+                                              iteration_start,
+                                              GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
+                                              struct AttributeIterationStartMessage,
+                                              NULL),
+                     GNUNET_MQ_hd_fixed_size (iteration_next,
+                                              GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
+                                              struct AttributeIterationNextMessage,
+                                              NULL),
+                     GNUNET_MQ_hd_fixed_size (iteration_stop,
+                                              GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
+                                              struct AttributeIterationStopMessage,
+                                              NULL),
+                     GNUNET_MQ_hd_var_size (issue_ticket_message,
+                                            GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
+                                            struct IssueTicketMessage,
+                                            NULL),
+                     GNUNET_MQ_hd_var_size (consume_ticket_message,
+                                            GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
+                                            struct ConsumeTicketMessage,
+                                            NULL),
+                     GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
+                                              GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
+                                              struct TicketIterationStartMessage,
+                                              NULL),
+                     GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
+                                              GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
+                                              struct TicketIterationNextMessage,
+                                              NULL),
+                     GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
+                                              GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
+                                              struct TicketIterationStopMessage,
+                                              NULL),
+                     GNUNET_MQ_hd_var_size (revoke_ticket_message,
+                                            GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
+                                            struct RevokeTicketMessage,
+                                            NULL),
+                     GNUNET_MQ_handler_end ());
 /* end of gnunet-service-reclaim.c */