gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnunet] branch master updated: RECLAIM: bugfixes; add dele


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated: RECLAIM: bugfixes; add delete attribute API
Date: Sun, 14 Apr 2019 15:23:50 +0200

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new 494af3383 RECLAIM: bugfixes; add delete attribute API
494af3383 is described below

commit 494af3383d2a5d3402e1f03209cb574af86079a8
Author: Schanzenbach, Martin <address@hidden>
AuthorDate: Sun Apr 14 15:23:44 2019 +0200

    RECLAIM: bugfixes; add delete attribute API
---
 po/POTFILES.in                               |   1 -
 src/include/gnunet_protocols.h               |  90 ++++---
 src/include/gnunet_reclaim_plugin.h          | 123 ---------
 src/include/gnunet_reclaim_service.h         |  19 ++
 src/reclaim/gnunet-reclaim.c                 |  61 ++++-
 src/reclaim/gnunet-service-reclaim.c         | 356 +++++++++++++++++++++++----
 src/reclaim/gnunet-service-reclaim_tickets.c | 126 +++++-----
 src/reclaim/gnunet-service-reclaim_tickets.h |  37 ++-
 src/reclaim/reclaim.h                        |  54 ++--
 src/reclaim/reclaim_api.c                    |  58 ++++-
 10 files changed, 612 insertions(+), 313 deletions(-)

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5c6a91963..f9000c654 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -287,7 +287,6 @@ src/reclaim/gnunet-service-reclaim_tickets.c
 src/reclaim/json_reclaim.c
 src/reclaim/oidc_helper.c
 src/reclaim/plugin_gnsrecord_reclaim.c
-src/reclaim/plugin_reclaim_sqlite.c
 src/reclaim/plugin_rest_openid_connect.c
 src/reclaim/plugin_rest_reclaim.c
 src/reclaim/reclaim_api.c
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index f461249eb..e402460c0 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -43,9 +43,8 @@
 #define GNUNET_PROTOCOLS_H
 
 #ifdef __cplusplus
-extern "C"
-{
-#if 0                           /* keep Emacsens' auto-indent happy */
+extern "C" {
+#if 0 /* keep Emacsens' auto-indent happy */
 }
 #endif
 #endif
@@ -252,7 +251,8 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_DV_DISCONNECT 50
 
 /**
- * P2P DV message telling plugin that a message transmission failed (negative 
ACK)
+ * P2P DV message telling plugin that a message transmission failed (negative
+ * ACK)
  */
 #define GNUNET_MESSAGE_TYPE_DV_SEND_NACK 51
 
@@ -622,37 +622,37 @@ extern "C"
 /**
  * Receive information about transiting GETs
  */
-#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET             149
+#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET 149
 
 /**
  * Receive information about transiting GET responses
  */
-#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP        150
+#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET_RESP 150
 
 /**
  * Receive information about transiting PUTs
  */
-#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT             151
+#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT 151
 
 /**
  * Receive information about transiting PUT responses (TODO)
  */
-#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT_RESP        152
+#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT_RESP 152
 
 /**
  * Request information about transiting messages
  */
-#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_START             153
+#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_START 153
 
 /**
  * Stop information about transiting messages
  */
-#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP             154
+#define GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP 154
 
 /**
  * Certain results are already known to the client, filter those.
  */
-#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN             156
+#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN 156
 
 /**
  * Further X-VINE DHT messages continued from 880
@@ -829,7 +829,6 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_DNS_HELPER 214
 
 
-
 
/*******************************************************************************
  * CHAT message types START
  
******************************************************************************/
@@ -1490,7 +1489,8 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_TESTBED_SLAVE_CONFIGURATION 480
 
 /**
- * Message to signal the result of 
#GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS request
+ * Message to signal the result of 
#GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS
+ * request
  */
 #define GNUNET_MESSAGE_TYPE_TESTBED_LINK_CONTROLLERS_RESULT 481
 
@@ -1600,8 +1600,8 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE 524
 
 /**
- * Sent by service to client in order to signal a completed consensus 
conclusion.
- * Last message sent in a consensus session.
+ * Sent by service to client in order to signal a completed consensus
+ * conclusion. Last message sent in a consensus session.
  */
 #define GNUNET_MESSAGE_TYPE_CONSENSUS_CLIENT_CONCLUDE_DONE 525
 
@@ -1646,7 +1646,8 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_HELLO 546
 
 /**
- * Report that the peer is synced with the partner after successfuly decoding 
the invertible bloom filter.
+ * Report that the peer is synced with the partner after successfuly decoding
+ * the invertible bloom filter.
  */
 #define GNUNET_MESSAGE_TYPE_CONSENSUS_P2P_SYNCED 547
 
@@ -1871,7 +1872,6 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_TESTBED_LOGGER_ACK 601
 
 
-
 /**
  * Advertise regex capability.
  */
@@ -2023,9 +2023,6 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA 652
 
 
-
-
-
 
/*******************************************************************************
  * PSYCSTORE message types
  
******************************************************************************/
@@ -2122,8 +2119,10 @@ extern "C"
 /** S<--C: PSYC message which contains one or more message parts. */
 #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE 691
 
-/** M<->S<->C: PSYC message which contains a header and one or more message 
parts. */
-#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_HEADER 692 // FIXME: start using this 
where appropriate
+/** M<->S<->C: PSYC message which contains a header and one or more message
+ * parts. */
+#define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_HEADER                                
\
+  692 // FIXME: start using this where appropriate
 
 /** Message part: method */
 #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_METHOD 693
@@ -2333,7 +2332,6 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_MULTICAST_REPLAY_RESPONSE_END 762
 
 
-
 
/*******************************************************************************
  * SECRETSHARING message types
  
******************************************************************************/
@@ -2544,7 +2542,7 @@ extern "C"
 /**
  * Acknowledge receiving ACT MALICIOUS request
  */
-#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_ACT_MALICIOUS_OK  894
+#define GNUNET_MESSAGE_TYPE_DHT_CLIENT_ACT_MALICIOUS_OK 894
 
 #endif
 
@@ -2606,23 +2604,22 @@ extern "C"
 /**
  * RPS check liveliness message to check liveliness of other peer
  */
-#define GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE     950
+#define GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE 950
 
 /**
  * RPS PUSH message to push own ID to another peer
  */
-#define GNUNET_MESSAGE_TYPE_RPS_PP_PUSH           951
+#define GNUNET_MESSAGE_TYPE_RPS_PP_PUSH 951
 
 /**
  * RPS PULL REQUEST message to request the local view of another peer
  */
-#define GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST   952
+#define GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST 952
 
 /**
  * RPS PULL REPLY message which contains the view of the other peer
  */
-#define GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY     953
-
+#define GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY 953
 
 
 /* Client-Service Messages */
@@ -2631,25 +2628,25 @@ extern "C"
 /**
  * RPS CS SEED Message for the Client to seed peers into rps
  */
-#define GNUNET_MESSAGE_TYPE_RPS_CS_SEED           954
+#define GNUNET_MESSAGE_TYPE_RPS_CS_SEED 954
 
 #if ENABLE_MALICIOUS
 /**
  * Turn RPS service malicious
  */
-#define GNUNET_MESSAGE_TYPE_RPS_ACT_MALICIOUS     955
+#define GNUNET_MESSAGE_TYPE_RPS_ACT_MALICIOUS 955
 
 #endif /* ENABLE_MALICIOUS */
 
 /**
  * RPS client-service message to start a sub sampler
  */
-#define GNUNET_MESSAGE_TYPE_RPS_CS_SUB_START           956
+#define GNUNET_MESSAGE_TYPE_RPS_CS_SUB_START 956
 
 /**
  * RPS client-service message to stop a sub sampler
  */
-#define GNUNET_MESSAGE_TYPE_RPS_CS_SUB_STOP            957
+#define GNUNET_MESSAGE_TYPE_RPS_CS_SUB_STOP 957
 
 /* Debugging API continues at 1130 */
 
@@ -2662,7 +2659,7 @@ extern "C"
  */
 #define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE 961
 
-#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE 962
+#define GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE 962
 
 #define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START 963
 
@@ -2690,11 +2687,13 @@ extern "C"
 
 #define GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT 975
 
+#define GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE 976
+
 /**************************************************
  *
  * CREDENTIAL MESSAGE TYPES
  */
-#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY     981
+#define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY 981
 
 #define GNUNET_MESSAGE_TYPE_CREDENTIAL_VERIFY_RESULT 982
 
@@ -2776,7 +2775,6 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH 1009
 
 
-
 /**********************************  Channel  
*********************************/
 
 /**
@@ -2964,7 +2962,8 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_NAT_AUTO_CFG_RESULT 1068
 
 
-/* 1080-1109 reserved for TMCG (Heiko Stamer, see gnunet-developers, January 
2017) */
+/* 1080-1109 reserved for TMCG (Heiko Stamer, see gnunet-developers, January
+ * 2017) */
 
 
 
/******************************************************************************/
@@ -2987,7 +2986,6 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_AUCTION_CLIENT_OUTCOME 1112
 
 
-
 
/******************************************************************************/
 /*********************************  RPS DEBUG  
********************************/
 
/******************************************************************************/
@@ -3000,12 +2998,12 @@ extern "C"
 /**
  * @brief Send update of the view
  */
-#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_REPLY   1131
+#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_REPLY 1131
 
 /**
  * @brief Cancel getting updates of the view
  */
-#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_CANCEL  1132
+#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_VIEW_CANCEL 1132
 
 
 /**
@@ -3016,12 +3014,12 @@ extern "C"
 /**
  * @brief Send peer of biased stream
  */
-#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_REPLY   1134
+#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_REPLY 1134
 
 /**
  * @brief Cancel getting biased strem
  */
-#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_CANCEL  1135
+#define GNUNET_MESSAGE_TYPE_RPS_CS_DEBUG_STREAM_CANCEL 1135
 
 
 /*******************************************************
@@ -3190,8 +3188,8 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL 1301
 
 /**
- * Type of the 'struct RequestHelloValidationMessage' send by clients to 
TRANSPORT
- * to trigger validation of addresses.
+ * Type of the 'struct RequestHelloValidationMessage' send by clients to
+ * TRANSPORT to trigger validation of addresses.
  */
 #define GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION 1302
 
@@ -3207,7 +3205,6 @@ extern "C"
 #define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE 1304
 
 
-
 /* ************** NEW (NG) ATS Messages ************* */
 /* NOTE: it is not clear ATS will survive in TNG      */
 
@@ -3286,14 +3283,13 @@ extern "C"
  */
 
 
-
 /**
  * Type used to match 'all' message types.
  */
 #define GNUNET_MESSAGE_TYPE_ALL 65535
 
 
-#if 0                           /* keep Emacsens' auto-indent happy */
+#if 0 /* keep Emacsens' auto-indent happy */
 {
 #endif
 #ifdef __cplusplus
diff --git a/src/include/gnunet_reclaim_plugin.h 
b/src/include/gnunet_reclaim_plugin.h
deleted file mode 100644
index 72a4bc218..000000000
--- a/src/include/gnunet_reclaim_plugin.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-     This file is part of GNUnet
-     Copyright (C) 2012, 2013 GNUnet e.V.
-
-     GNUnet is free software: you can redistribute it and/or modify it
-     under the terms of the GNU Affero General Public License as published
-     by the Free Software Foundation, either version 3 of the License,
-     or (at your option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     Affero General Public License for more details.
-    
-     You should have received a copy of the GNU Affero General Public License
-     along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-     SPDX-License-Identifier: AGPL3.0-or-later
-*/
-
-/**
- * @author Martin Schanzenbach
- *
- * @file
- * Plugin API for the idp database backend
- *
- * @defgroup reclaim-plugin  IdP service plugin API
- * Plugin API for the idp database backend
- * @{
- */
-#ifndef GNUNET_RECLAIM_PLUGIN_H
-#define GNUNET_RECLAIM_PLUGIN_H
-
-#include "gnunet_util_lib.h"
-#include "gnunet_reclaim_service.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0                           /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-
-/**
- * Function called by for each matching ticket.
- *
- * @param cls closure
- * @param ticket the ticket
- */
-typedef void (*GNUNET_RECLAIM_TicketIterator) (void *cls,
-                                                const struct 
GNUNET_RECLAIM_Ticket *ticket,
-             const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs);
-
-
-/**
- * @brief struct returned by the initialization function of the plugin
- */
-struct GNUNET_RECLAIM_PluginFunctions
-{
-
-  /**
-   * Closure to pass to all plugin functions.
-   */
-  void *cls;
-
-  /**
-   * Store a ticket in the database.
-   *
-   * @param cls closure (internal context for the plugin)
-   * @param ticket the ticket to store
-   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
-   */
-  int (*store_ticket) (void *cls,
-                       const struct GNUNET_RECLAIM_Ticket *ticket,
-      const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs);
-
-  /**
-   * Delete a ticket from the database.
-   *
-   * @param cls closure (internal context for the plugin)
-   * @param ticket the ticket to store
-   * @return #GNUNET_OK on success, else #GNUNET_SYSERR
-   */
-  int (*delete_ticket) (void *cls,
-                       const struct GNUNET_RECLAIM_Ticket *ticket);
-
-
-
-  /**
-   * Iterate over all tickets
-   *
-   * @param cls closure (internal context for the plugin)
-   * @param identity the identity
-   * @param audience GNUNET_YES if the identity is the audience of the ticket
-   *                 else it is considered the issuer
-   * @param iter function to call with the result
-   * @param iter_cls closure for @a iter
-   * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, 
#GNUNET_SYSERR on error
-   */
-  int (*iterate_tickets) (void *cls,
-                         const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
-        int audience,
-                         uint64_t offset,
-                         GNUNET_RECLAIM_TicketIterator iter, void *iter_cls);
-
-  int (*get_ticket_attributes) (void* cls,
-                                const struct GNUNET_RECLAIM_Ticket *ticket,
-                                GNUNET_RECLAIM_TicketIterator iter,
-                                void *iter_cls);
-};
-
-#if 0                           /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/** @} */  /* end of group */
diff --git a/src/include/gnunet_reclaim_service.h 
b/src/include/gnunet_reclaim_service.h
index d179485bb..fc3d0f920 100644
--- a/src/include/gnunet_reclaim_service.h
+++ b/src/include/gnunet_reclaim_service.h
@@ -150,6 +150,25 @@ GNUNET_RECLAIM_attribute_store (
     GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls);
 
 
+/**
+ * Delete an attribute. Tickets used to share this attribute are updated
+ * accordingly.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey Private key of the identity to add an attribute to
+ * @param attr The attribute
+ * @param cont Continuation to call when done
+ * @param cont_cls Closure for @a cont
+ * @return handle Used to to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attribute_delete (
+    struct GNUNET_RECLAIM_Handle *h,
+    const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+    const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+    GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls);
+
+
 /**
  * List all attributes for a local identity.
  * This MUST lock the `struct GNUNET_RECLAIM_Handle`
diff --git a/src/reclaim/gnunet-reclaim.c b/src/reclaim/gnunet-reclaim.c
index 1c3b4174d..a9d6f67d2 100644
--- a/src/reclaim/gnunet-reclaim.c
+++ b/src/reclaim/gnunet-reclaim.c
@@ -157,6 +157,16 @@ static struct GNUNET_SCHEDULER_Task *cleanup_task;
  */
 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
 
+/**
+ * Claim to delete
+ */
+static char *attr_delete;
+
+/**
+ * Claim object to delete
+ */
+static struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr_to_delete;
+
 static void
 do_cleanup (void *cls)
 {
@@ -177,6 +187,8 @@ do_cleanup (void *cls)
     GNUNET_free (abe_key);
   if (NULL != attr_list)
     GNUNET_free (attr_list);
+  if (NULL != attr_to_delete)
+    GNUNET_free (attr_to_delete);
 }
 
 static void
@@ -208,6 +220,7 @@ process_attrs (void *cls, const struct 
GNUNET_CRYPTO_EcdsaPublicKey *identity,
                const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
 {
   char *value_str;
+  char *id;
   const char *attr_type;
 
   if (NULL == identity) {
@@ -222,8 +235,10 @@ process_attrs (void *cls, const struct 
GNUNET_CRYPTO_EcdsaPublicKey *identity,
   value_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, attr->data,
                                                         attr->data_size);
   attr_type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
-  fprintf (stdout, "%s: %s [%s,v%u,id=%" PRIu64 "]\n", attr->name, value_str,
-           attr_type, attr->version, attr->id);
+  id = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof (uint64_t));
+  fprintf (stdout, "Name: %s; Value: %s (%s); Version %u; ID: %s\n", 
attr->name,
+           value_str, attr_type, attr->version, id);
+  GNUNET_free (id);
 }
 
 static void
@@ -284,6 +299,19 @@ process_rvk (void *cls, int success, const char *msg)
   cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
 }
 
+
+static void
+process_delete (void *cls, int success, const char *msg)
+{
+  reclaim_op = NULL;
+  if (GNUNET_OK != success) {
+    fprintf (stderr, "Deletion failed.\n");
+    ret = 1;
+  }
+  cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
+}
+
+
 static void
 iter_finished (void *cls)
 {
@@ -315,6 +343,15 @@ iter_finished (void *cls)
                                                &process_rvk, NULL);
     return;
   }
+  if (attr_delete) {
+    if (NULL == attr_to_delete) {
+      fprintf (stdout, "No such attribute ``%s''\n", attr_delete);
+      return;
+    }
+    reclaim_op = GNUNET_RECLAIM_attribute_delete (
+        reclaim_handle, pkey, attr_to_delete, &process_delete, NULL);
+    return;
+  }
   if (attr_name) {
     if (NULL == type_str)
       type = GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING;
@@ -348,6 +385,8 @@ iter_cb (void *cls, const struct 
GNUNET_CRYPTO_EcdsaPublicKey *identity,
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
   char *attrs_tmp;
   char *attr_str;
+  char *label;
+  char *id;
   const char *attr_type;
 
   if ((NULL != attr_name) && (NULL != claim)) {
@@ -373,12 +412,22 @@ iter_cb (void *cls, const struct 
GNUNET_CRYPTO_EcdsaPublicKey *identity,
       break;
     }
     GNUNET_free (attrs_tmp);
+  } else if (attr_delete && (NULL == attr_to_delete)) {
+    label = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof (uint64_t));
+    if (0 == strcasecmp (attr_delete, label)) {
+      attr_to_delete = GNUNET_RECLAIM_ATTRIBUTE_claim_new (
+          attr->name, attr->type, attr->data, attr->data_size);
+      attr_to_delete->id = attr->id;
+    }
+    GNUNET_free (label);
   } else if (list) {
     attr_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, 
attr->data,
                                                          attr->data_size);
     attr_type = GNUNET_RECLAIM_ATTRIBUTE_number_to_typename (attr->type);
-    fprintf (stdout, "%s: %s [%s,v%u,id=%" PRIu64 "]\n", attr->name, attr_str,
-             attr_type, attr->version, attr->id);
+    id = GNUNET_STRINGS_data_to_string_alloc (&attr->id, sizeof (uint64_t));
+    fprintf (stdout, "Name: %s; Value: %s (%s); Version %u; ID: %s\n",
+             attr->name, attr_str, attr_type, attr->version, id);
+    GNUNET_free (id);
   }
   GNUNET_RECLAIM_get_attributes_next (attr_iterator);
 }
@@ -474,7 +523,9 @@ main (int argc, char *const argv[])
       GNUNET_GETOPT_option_string ('a', "add", "NAME",
                                    gettext_noop ("Add an attribute NAME"),
                                    &attr_name),
-
+      GNUNET_GETOPT_option_string ('d', "delete", "ID",
+                                   gettext_noop ("Add an attribute with ID"),
+                                   &attr_delete),
       GNUNET_GETOPT_option_string ('V', "value", "VALUE",
                                    gettext_noop ("The attribute VALUE"),
                                    &attr_value),
diff --git a/src/reclaim/gnunet-service-reclaim.c 
b/src/reclaim/gnunet-service-reclaim.c
index 2bb4f5a74..5deb482e9 100644
--- a/src/reclaim/gnunet-service-reclaim.c
+++ b/src/reclaim/gnunet-service-reclaim.c
@@ -34,7 +34,7 @@
 #include "gnunet_namestore_service.h"
 #include "gnunet_protocols.h"
 #include "gnunet_reclaim_attribute_lib.h"
-#include "gnunet_reclaim_plugin.h"
+#include "gnunet_reclaim_service.h"
 #include "gnunet_signatures.h"
 #include "reclaim.h"
 
@@ -63,16 +63,6 @@
  */
 static struct GNUNET_IDENTITY_Handle *identity_handle;
 
-/**
- * Database handle
- */
-static struct GNUNET_RECLAIM_PluginFunctions *TKT_database;
-
-/**
- * Name of DB plugin
- */
-static char *db_lib_name;
-
 /**
  * Token expiration interval
  */
@@ -106,7 +96,8 @@ struct IdpClient;
 /**
  * A ticket iteration operation.
  */
-struct TicketIteration {
+struct TicketIteration
+{
   /**
    * DLL
    */
@@ -136,7 +127,8 @@ struct TicketIteration {
 /**
  * An attribute iteration operation.
  */
-struct AttributeIterator {
+struct AttributeIterator
+{
   /**
    * Next element in the DLL
    */
@@ -171,7 +163,8 @@ struct AttributeIterator {
 /**
  * An idp client
  */
-struct IdpClient {
+struct IdpClient
+{
 
   /**
    * The client
@@ -246,9 +239,80 @@ struct IdpClient {
    * Tail of DLL of attribute store ops
    */
   struct AttributeStoreHandle *store_op_tail;
+  /**
+   * Head of DLL of attribute delete ops
+   */
+  struct AttributeDeleteHandle *delete_op_head;
+
+  /**
+   * Tail of DLL of attribute delete ops
+   */
+  struct AttributeDeleteHandle *delete_op_tail;
+};
+
+
+struct AttributeDeleteHandle
+{
+  /**
+   * DLL
+   */
+  struct AttributeDeleteHandle *next;
+
+  /**
+   * DLL
+   */
+  struct AttributeDeleteHandle *prev;
+
+  /**
+   * Client connection
+   */
+  struct IdpClient *client;
+
+  /**
+   * Identity
+   */
+  struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
+
+
+  /**
+   * QueueEntry
+   */
+  struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+  /**
+   * Iterator
+   */
+  struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
+
+  /**
+   * The attribute to delete
+   */
+  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
+
+  /**
+   * Tickets to update
+   */
+  struct TicketRecordsEntry *tickets_to_update_head;
+
+  /**
+   * Tickets to update
+   */
+  struct TicketRecordsEntry *tickets_to_update_tail;
+
+  /**
+   * Attribute label
+   */
+  char *label;
+
+  /**
+   * request id
+   */
+  uint32_t r_id;
 };
 
-struct AttributeStoreHandle {
+
+struct AttributeStoreHandle
+{
   /**
    * DLL
    */
@@ -295,7 +359,8 @@ struct AttributeStoreHandle {
   uint32_t r_id;
 };
 
-struct ConsumeTicketOperation {
+struct ConsumeTicketOperation
+{
   /**
    * DLL
    */
@@ -325,7 +390,8 @@ struct ConsumeTicketOperation {
 /**
  * Updated attribute IDs
  */
-struct TicketAttributeUpdateEntry {
+struct TicketAttributeUpdateEntry
+{
   /**
    * DLL
    */
@@ -350,7 +416,8 @@ struct TicketAttributeUpdateEntry {
 /**
  * Ticket revocation request handle
  */
-struct TicketRevocationOperation {
+struct TicketRevocationOperation
+{
   /**
    * DLL
    */
@@ -380,7 +447,8 @@ struct TicketRevocationOperation {
 /**
  * Ticket issue operation handle
  */
-struct TicketIssueOperation {
+struct TicketIssueOperation
+{
   /**
    * DLL
    */
@@ -407,7 +475,8 @@ struct TicketIssueOperation {
  * map in json_t format
  *
  */
-struct EgoEntry {
+struct EgoEntry
+{
   /**
    * DLL
    */
@@ -438,9 +507,6 @@ cleanup ()
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
 
   RECLAIM_TICKETS_deinit ();
-  GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, TKT_database));
-  GNUNET_free (db_lib_name);
-  db_lib_name = NULL;
   if (NULL != timeout_task)
     GNUNET_SCHEDULER_cancel (timeout_task);
   if (NULL != update_task)
@@ -673,7 +739,7 @@ attr_store_cont (void *cls, int32_t success, const char 
*emsg)
 {
   struct AttributeStoreHandle *ash = cls;
   struct GNUNET_MQ_Envelope *env;
-  struct AttributeStoreResultMessage *acr_msg;
+  struct SuccessResultMessage *acr_msg;
 
   ash->ns_qe = NULL;
   GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
@@ -687,10 +753,8 @@ attr_store_cont (void *cls, int32_t success, const char 
*emsg)
     return;
   }
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Sending ATTRIBUTE_STORE_RESPONSE message\n");
-  env = GNUNET_MQ_msg (acr_msg,
-                       GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
+  env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
   acr_msg->id = htonl (ash->r_id);
   acr_msg->op_result = htonl (GNUNET_OK);
   GNUNET_MQ_send (ash->client->mq, env);
@@ -771,6 +835,220 @@ handle_attribute_store_message (void *cls,
   GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
 }
 
+
+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);
+}
+
+
+static void
+send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
+{
+  struct GNUNET_MQ_Envelope *env;
+  struct SuccessResultMessage *acr_msg;
+
+  GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
+                               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);
+  acr_msg->id = htonl (adh->r_id);
+  acr_msg->op_result = htonl (success);
+  GNUNET_MQ_send (adh->client->mq, env);
+}
+
+
+static void
+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;
+  struct TicketRecordsEntry *le;
+  int has_changed = GNUNET_NO;
+
+  for (int i = 0; i < rd_count; i++) {
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
+      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",
+                adh->label);
+    has_changed = GNUNET_YES;
+    break;
+  }
+  if (GNUNET_YES == has_changed) {
+    le = GNUNET_new (struct TicketRecordsEntry);
+    le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
+    le->data = GNUNET_malloc (le->data_size);
+    le->rd_count = rd_count;
+    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);
+  }
+  GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
+}
+
+
+static void
+update_tickets (void *cls);
+
+
+static void
+ticket_updated (void *cls, int32_t success, const char *emsg)
+{
+  struct AttributeDeleteHandle *adh = cls;
+  adh->ns_qe = NULL;
+  GNUNET_SCHEDULER_add_now (&update_tickets, adh);
+}
+
+static void
+update_tickets (void *cls)
+{
+  struct AttributeDeleteHandle *adh = cls;
+  struct TicketRecordsEntry *le;
+  if (NULL == adh->tickets_to_update_head) {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Finished updatding tickets, success\n");
+    send_delete_response (adh, GNUNET_OK);
+    cleanup_adh (adh);
+    return;
+  }
+  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);
+  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);
+  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))))
+      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);
+  GNUNET_free (le->label);
+  GNUNET_free (le->data);
+  GNUNET_free (le);
+}
+
+
+static void
+ticket_iter_fin (void *cls)
+{
+  struct AttributeDeleteHandle *adh = cls;
+  adh->ns_it = NULL;
+  GNUNET_SCHEDULER_add_now (&update_tickets, adh);
+}
+
+
+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",
+              adh->label);
+  send_delete_response (adh, GNUNET_SYSERR);
+  cleanup_adh (adh);
+}
+
+
+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);
+}
+
+
+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 (%s)\n",
+                adh->claim->name, adh->label);
+    send_delete_response (adh, GNUNET_SYSERR);
+    cleanup_adh (adh);
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating tickets...\n");
+  GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
+}
+
+
+static int
+check_attribute_delete_message (void *cls,
+                                const struct AttributeDeleteMessage *dam)
+{
+  uint16_t size;
+
+  size = ntohs (dam->header.size);
+  if (size <= sizeof (struct AttributeDeleteMessage)) {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+static void
+handle_attribute_delete_message (void *cls,
+                                 const struct AttributeDeleteMessage *dam)
+{
+  struct AttributeDeleteHandle *adh;
+  struct IdpClient *idp = cls;
+  size_t data_len;
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received ATTRIBUTE_DELETE message\n");
+
+  data_len = ntohs (dam->attr_len);
+
+  adh = GNUNET_new (struct AttributeDeleteHandle);
+  adh->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *)&dam[1], 
data_len);
+
+  adh->r_id = ntohl (dam->id);
+  adh->identity = dam->identity;
+  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);
+}
+
+
 /*************************************************
  * Attrubute iteration
  *************************************************/
@@ -1013,7 +1291,6 @@ static void
 run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c,
      struct GNUNET_SERVICE_Handle *server)
 {
-  char *database;
   cfg = c;
 
   if (GNUNET_OK != RECLAIM_TICKETS_init (cfg)) {
@@ -1030,19 +1307,6 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle 
*c,
   }
 
   identity_handle = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
-  /* Loading DB plugin */
-  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (
-                       cfg, "reclaim", "database", &database))
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
-  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_reclaim_%s", database);
-  TKT_database = GNUNET_PLUGIN_load (db_lib_name, (void *)cfg);
-  GNUNET_free (database);
-  if (NULL == TKT_database) {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Could not load database backend `%s'\n", db_lib_name);
-    GNUNET_SCHEDULER_shutdown ();
-    return;
-  }
 
   if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (
                        cfg, "reclaim", "TOKEN_EXPIRATION_INTERVAL",
@@ -1075,6 +1339,7 @@ client_disconnect_cb (void *cls, struct 
GNUNET_SERVICE_Client *client,
   struct TicketIssueOperation *iss;
   struct ConsumeTicketOperation *ct;
   struct AttributeStoreHandle *as;
+  struct AttributeDeleteHandle *adh;
 
   // TODO other operations
 
@@ -1095,6 +1360,10 @@ client_disconnect_cb (void *cls, struct 
GNUNET_SERVICE_Client *client,
     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);
@@ -1143,6 +1412,9 @@ GNUNET_SERVICE_MAIN (
     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),
diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c 
b/src/reclaim/gnunet-service-reclaim_tickets.c
index 549ea8c34..1cdd4268d 100644
--- a/src/reclaim/gnunet-service-reclaim_tickets.c
+++ b/src/reclaim/gnunet-service-reclaim_tickets.c
@@ -30,6 +30,34 @@
 
 struct ParallelLookup;
 
+
+/**
+ * A reference to a ticket stored in GNS
+ */
+struct TicketReference
+{
+  /**
+   * DLL
+   */
+  struct TicketReference *next;
+
+  /**
+   * DLL
+   */
+  struct TicketReference *prev;
+
+  /**
+   * Attributes
+   */
+  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
+
+  /**
+   * Tickets
+   */
+  struct GNUNET_RECLAIM_Ticket ticket;
+};
+
+
 struct RECLAIM_TICKETS_ConsumeHandle
 {
   /**
@@ -115,33 +143,6 @@ struct ParallelLookup
 };
 
 
-/**
- * A reference to a ticket stored in GNS
- */
-struct TicketReference
-{
-  /**
-   * DLL
-   */
-  struct TicketReference *next;
-
-  /**
-   * DLL
-   */
-  struct TicketReference *prev;
-
-  /**
-   * Attributes
-   */
-  struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
-
-  /**
-   * Tickets
-   */
-  struct GNUNET_RECLAIM_Ticket ticket;
-};
-
-
 /**
  * Ticket issue request handle
  */
@@ -224,39 +225,6 @@ struct RevokedAttributeEntry
 };
 
 
-struct TicketRecordsEntry
-{
-  /**
-   * DLL
-   */
-  struct TicketRecordsEntry *next;
-
-  /**
-   * DLL
-   */
-  struct TicketRecordsEntry *prev;
-
-  /**
-   * Record count
-   */
-  unsigned int rd_count;
-
-  /**
-   * Data
-   */
-  char *data;
-
-  /**
-   * Data size
-   */
-  size_t data_size;
-
-  /**
-   * Label
-   */
-  char *label;
-};
-
 /**
  * Ticket revocation request handle
  */
@@ -414,8 +382,11 @@ rvk_move_attr_cb (void *cls, const struct 
GNUNET_CRYPTO_EcdsaPrivateKey *zone,
                   const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
+  struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
+  struct GNUNET_GNSRECORD_Data new_rd;
   struct RevokedAttributeEntry *le;
   char *new_label;
+  char *attr_data;
   rvk->ns_qe = NULL;
   if (0 == rd_count) {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -430,12 +401,24 @@ rvk_move_attr_cb (void *cls, const struct 
GNUNET_CRYPTO_EcdsaPrivateKey *zone,
   /** find a new place for this attribute **/
   rvk->move_attr->new_id =
       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+  new_rd = *rd;
+  claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+              "Attribute to update: Name=%s, ID=%" PRIu64 "\n", claim->name,
+              claim->id);
+  claim->id = rvk->move_attr->new_id;
+  new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
+  attr_data = GNUNET_malloc (rd->data_size);
+  new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
+  new_rd.data = attr_data;
   new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
                                                    sizeof (uint64_t));
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
-  rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, new_label,
-                                               1, rd, &move_attr_finished, 
rvk);
+  rvk->ns_qe = GNUNET_NAMESTORE_records_store (
+      nsh, &rvk->identity, new_label, 1, &new_rd, &move_attr_finished, rvk);
   GNUNET_free (new_label);
+  GNUNET_free (claim);
+  GNUNET_free (attr_data);
 }
 
 
@@ -703,7 +686,7 @@ process_parallel_lookup_result (void *cls, uint32_t 
rd_count,
   struct ParallelLookup *parallel_lookup = cls;
   struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle;
   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parallel lookup finished (count=%u)\n",
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Parallel lookup finished (count=%u)\n",
               rd_count);
 
   GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
@@ -777,8 +760,10 @@ lookup_authz_cb (void *cls, uint32_t rd_count,
                             GNUNET_YES);
 
   for (int i = 0; i < rd_count; i++) {
+    if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
+      continue;
     lbl = GNUNET_STRINGS_data_to_string_alloc (rd[i].data, rd[i].data_size);
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute ref found %s\n", lbl);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attribute ref found %s\n", lbl);
     parallel_lookup = GNUNET_new (struct ParallelLookup);
     parallel_lookup->handle = cth;
     parallel_lookup->label = lbl;
@@ -790,9 +775,14 @@ lookup_authz_cb (void *cls, uint32_t rd_count,
     GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head,
                                  cth->parallel_lookups_tail, parallel_lookup);
   }
-  cth->kill_task = GNUNET_SCHEDULER_add_delayed (
-      GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3),
-      &abort_parallel_lookups, cth);
+  if (NULL != cth->parallel_lookups_head) {
+    cth->kill_task = GNUNET_SCHEDULER_add_delayed (
+        GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3),
+        &abort_parallel_lookups, cth);
+    return;
+  }
+  cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
+  cleanup_cth (cth);
 }
 
 
@@ -813,7 +803,7 @@ RECLAIM_TICKETS_consume (const struct 
GNUNET_CRYPTO_EcdsaPrivateKey *id,
   cth->cb_cls = cb_cls;
   label =
       GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof 
(uint64_t));
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for AuthZ info under %s\n",
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for AuthZ info under %s\n",
               label);
   cth->lookup_start_time = GNUNET_TIME_absolute_get ();
   cth->lookup_request = GNUNET_GNS_lookup (
diff --git a/src/reclaim/gnunet-service-reclaim_tickets.h 
b/src/reclaim/gnunet-service-reclaim_tickets.h
index d2b614c46..6e704243d 100644
--- a/src/reclaim/gnunet-service-reclaim_tickets.h
+++ b/src/reclaim/gnunet-service-reclaim_tickets.h
@@ -38,7 +38,7 @@
 #include "gnunet_namestore_service.h"
 #include "gnunet_protocols.h"
 #include "gnunet_reclaim_attribute_lib.h"
-#include "gnunet_reclaim_plugin.h"
+#include "gnunet_reclaim_service.h"
 #include "gnunet_signatures.h"
 #include "gnunet_statistics_service.h"
 #include "reclaim.h"
@@ -47,6 +47,41 @@ struct RECLAIM_TICKETS_Iterator;
 struct RECLAIM_TICKETS_ConsumeHandle;
 struct RECLAIM_TICKETS_RevokeHandle;
 
+
+struct TicketRecordsEntry
+{
+  /**
+   * DLL
+   */
+  struct TicketRecordsEntry *next;
+
+  /**
+   * DLL
+   */
+  struct TicketRecordsEntry *prev;
+
+  /**
+   * Record count
+   */
+  unsigned int rd_count;
+
+  /**
+   * Data
+   */
+  char *data;
+
+  /**
+   * Data size
+   */
+  size_t data_size;
+
+  /**
+   * Label
+   */
+  char *label;
+};
+
+
 /**
  * Continuation called with ticket.
  *
diff --git a/src/reclaim/reclaim.h b/src/reclaim/reclaim.h
index c29902ab1..982cd8ae4 100644
--- a/src/reclaim/reclaim.h
+++ b/src/reclaim/reclaim.h
@@ -33,6 +33,7 @@
 
 GNUNET_NETWORK_STRUCT_BEGIN
 
+
 /**
  * Use to store an identity attribute
  */
@@ -64,13 +65,42 @@ struct AttributeStoreMessage
   struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
 
   /* followed by the serialized attribute */
+};
+
+
+/**
+ * Use to delete an identity attribute
+ */
+struct AttributeDeleteMessage
+{
+  /**
+   * Type: #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * Unique identifier for this request (for key collisions).
+   */
+  uint32_t id GNUNET_PACKED;
+
+  /**
+   * The length of the attribute
+   */
+  uint32_t attr_len GNUNET_PACKED;
+
+  /**
+   * Identity
+   */
+  struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
 
+  /* followed by the serialized attribute */
 };
 
+
 /**
- * Attribute store response message
+ * Attribute store/delete response message
  */
-struct AttributeStoreResultMessage
+struct SuccessResultMessage
 {
   /**
    * Message header
@@ -86,7 +116,6 @@ struct AttributeStoreResultMessage
    * #GNUNET_SYSERR on failure, #GNUNET_OK on success
    */
   int32_t op_result GNUNET_PACKED;
-
 };
 
 /**
@@ -99,7 +128,7 @@ struct AttributeResultMessage
    */
   struct GNUNET_MessageHeader header;
 
-   /**
+  /**
    * Unique identifier for this request (for key collisions).
    */
   uint32_t id GNUNET_PACKED;
@@ -144,7 +173,6 @@ struct AttributeIterationStartMessage
    * Identity.
    */
   struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
-
 };
 
 
@@ -162,7 +190,6 @@ struct AttributeIterationNextMessage
    * Unique identifier for this request (for key collisions).
    */
   uint32_t id GNUNET_PACKED;
-
 };
 
 
@@ -180,7 +207,6 @@ struct AttributeIterationStopMessage
    * Unique identifier for this request (for key collisions).
    */
   uint32_t id GNUNET_PACKED;
-
 };
 
 /**
@@ -202,7 +228,6 @@ struct TicketIterationStartMessage
    * Identity.
    */
   struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
-
 };
 
 
@@ -220,7 +245,6 @@ struct TicketIterationNextMessage
    * Unique identifier for this request (for key collisions).
    */
   uint32_t id GNUNET_PACKED;
-
 };
 
 
@@ -238,11 +262,9 @@ struct TicketIterationStopMessage
    * Unique identifier for this request (for key collisions).
    */
   uint32_t id GNUNET_PACKED;
-
 };
 
 
-
 /**
  * Ticket issue message
  */
@@ -273,7 +295,7 @@ struct IssueTicketMessage
    */
   uint32_t attr_len GNUNET_PACKED;
 
-  //Followed by a serialized attribute list
+  // Followed by a serialized attribute list
 };
 
 /**
@@ -301,7 +323,7 @@ struct RevokeTicketMessage
    */
   uint32_t attrs_len GNUNET_PACKED;
 
-  //Followed by a ticket and serialized attribute list
+  // Followed by a ticket and serialized attribute list
 };
 
 /**
@@ -340,7 +362,6 @@ struct TicketResultMessage
    * Unique identifier for this request (for key collisions).
    */
   uint32_t id GNUNET_PACKED;
-
 };
 
 /**
@@ -363,7 +384,7 @@ struct ConsumeTicketMessage
    */
   struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
 
-  //Followed by a serialized ticket
+  // Followed by a serialized ticket
 };
 
 /**
@@ -376,7 +397,7 @@ struct ConsumeTicketResultMessage
    */
   struct GNUNET_MessageHeader header;
 
-   /**
+  /**
    * Unique identifier for this request (for key collisions).
    */
   uint32_t id GNUNET_PACKED;
@@ -407,7 +428,6 @@ struct ConsumeTicketResultMessage
 };
 
 
-
 GNUNET_NETWORK_STRUCT_END
 
 #endif
diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c
index 0edae76c2..e0ca9adf3 100644
--- a/src/reclaim/reclaim_api.c
+++ b/src/reclaim/reclaim_api.c
@@ -407,14 +407,13 @@ mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
 
 /**
  * Handle an incoming message of type
- * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
+ * #GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE
  *
  * @param cls
  * @param msg the message we received
  */
 static void
-handle_attribute_store_response (void *cls,
-                                 const struct AttributeStoreResultMessage *msg)
+handle_success_response (void *cls, const struct SuccessResultMessage *msg)
 {
   struct GNUNET_RECLAIM_Handle *h = cls;
   struct GNUNET_RECLAIM_Operation *op;
@@ -429,8 +428,8 @@ handle_attribute_store_response (void *cls,
     return;
 
   res = ntohl (msg->op_result);
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Received ATTRIBUTE_STORE_RESPONSE with result %d\n", res);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Received SUCCESS_RESPONSE with result %d\n",
+       res);
 
   /* TODO: add actual error message to response... */
   if (GNUNET_SYSERR == res)
@@ -735,10 +734,9 @@ static void
 reconnect (struct GNUNET_RECLAIM_Handle *h)
 {
   struct GNUNET_MQ_MessageHandler handlers[] = {
-      GNUNET_MQ_hd_fixed_size (
-          attribute_store_response,
-          GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE,
-          struct AttributeStoreResultMessage, h),
+      GNUNET_MQ_hd_fixed_size (success_response,
+                               GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE,
+                               struct SuccessResultMessage, h),
       GNUNET_MQ_hd_var_size (attribute_result,
                              GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
                              struct AttributeResultMessage, h),
@@ -873,6 +871,48 @@ GNUNET_RECLAIM_attribute_store (
 }
 
 
+/**
+ * Delete an attribute. Tickets used to share this attribute are updated
+ * accordingly.
+ *
+ * @param h handle to the re:claimID service
+ * @param pkey Private key of the identity to add an attribute to
+ * @param attr The attribute
+ * @param cont Continuation to call when done
+ * @param cont_cls Closure for @a cont
+ * @return handle Used to to abort the request
+ */
+struct GNUNET_RECLAIM_Operation *
+GNUNET_RECLAIM_attribute_delete (
+    struct GNUNET_RECLAIM_Handle *h,
+    const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
+    const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
+    GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls)
+{
+  struct GNUNET_RECLAIM_Operation *op;
+  struct AttributeDeleteMessage *dam;
+  size_t attr_len;
+
+  op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
+  op->h = h;
+  op->as_cb = cont;
+  op->cls = cont_cls;
+  op->r_id = h->r_id_gen++;
+  GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
+  attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (attr);
+  op->env = GNUNET_MQ_msg_extra (dam, attr_len,
+                                 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE);
+  dam->identity = *pkey;
+  dam->id = htonl (op->r_id);
+  GNUNET_RECLAIM_ATTRIBUTE_serialize (attr, (char *)&dam[1]);
+
+  dam->attr_len = htons (attr_len);
+  if (NULL != h->mq)
+    GNUNET_MQ_send_copy (h->mq, op->env);
+  return op;
+}
+
+
 /**
  * List all attributes for a local identity.
  * This MUST lock the `struct GNUNET_RECLAIM_Handle`

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]