aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim/gnunet-service-reclaim.c
diff options
context:
space:
mode:
authorSchanzenbach, Martin <mschanzenbach@posteo.de>2019-04-14 15:23:44 +0200
committerSchanzenbach, Martin <mschanzenbach@posteo.de>2019-04-14 15:23:44 +0200
commit494af3383d2a5d3402e1f03209cb574af86079a8 (patch)
tree6b457d61846e2f18c3f1b4ace0e3e58480e3e15c /src/reclaim/gnunet-service-reclaim.c
parenta277e037fefe605c93d81869ac514f87cad25768 (diff)
downloadgnunet-494af3383d2a5d3402e1f03209cb574af86079a8.tar.gz
gnunet-494af3383d2a5d3402e1f03209cb574af86079a8.zip
RECLAIM: bugfixes; add delete attribute API
Diffstat (limited to 'src/reclaim/gnunet-service-reclaim.c')
-rw-r--r--src/reclaim/gnunet-service-reclaim.c356
1 files changed, 314 insertions, 42 deletions
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 @@
34#include "gnunet_namestore_service.h" 34#include "gnunet_namestore_service.h"
35#include "gnunet_protocols.h" 35#include "gnunet_protocols.h"
36#include "gnunet_reclaim_attribute_lib.h" 36#include "gnunet_reclaim_attribute_lib.h"
37#include "gnunet_reclaim_plugin.h" 37#include "gnunet_reclaim_service.h"
38#include "gnunet_signatures.h" 38#include "gnunet_signatures.h"
39#include "reclaim.h" 39#include "reclaim.h"
40 40
@@ -64,16 +64,6 @@
64static struct GNUNET_IDENTITY_Handle *identity_handle; 64static struct GNUNET_IDENTITY_Handle *identity_handle;
65 65
66/** 66/**
67 * Database handle
68 */
69static struct GNUNET_RECLAIM_PluginFunctions *TKT_database;
70
71/**
72 * Name of DB plugin
73 */
74static char *db_lib_name;
75
76/**
77 * Token expiration interval 67 * Token expiration interval
78 */ 68 */
79static struct GNUNET_TIME_Relative token_expiration_interval; 69static struct GNUNET_TIME_Relative token_expiration_interval;
@@ -106,7 +96,8 @@ struct IdpClient;
106/** 96/**
107 * A ticket iteration operation. 97 * A ticket iteration operation.
108 */ 98 */
109struct TicketIteration { 99struct TicketIteration
100{
110 /** 101 /**
111 * DLL 102 * DLL
112 */ 103 */
@@ -136,7 +127,8 @@ struct TicketIteration {
136/** 127/**
137 * An attribute iteration operation. 128 * An attribute iteration operation.
138 */ 129 */
139struct AttributeIterator { 130struct AttributeIterator
131{
140 /** 132 /**
141 * Next element in the DLL 133 * Next element in the DLL
142 */ 134 */
@@ -171,7 +163,8 @@ struct AttributeIterator {
171/** 163/**
172 * An idp client 164 * An idp client
173 */ 165 */
174struct IdpClient { 166struct IdpClient
167{
175 168
176 /** 169 /**
177 * The client 170 * The client
@@ -246,9 +239,80 @@ struct IdpClient {
246 * Tail of DLL of attribute store ops 239 * Tail of DLL of attribute store ops
247 */ 240 */
248 struct AttributeStoreHandle *store_op_tail; 241 struct AttributeStoreHandle *store_op_tail;
242 /**
243 * Head of DLL of attribute delete ops
244 */
245 struct AttributeDeleteHandle *delete_op_head;
246
247 /**
248 * Tail of DLL of attribute delete ops
249 */
250 struct AttributeDeleteHandle *delete_op_tail;
251};
252
253
254struct AttributeDeleteHandle
255{
256 /**
257 * DLL
258 */
259 struct AttributeDeleteHandle *next;
260
261 /**
262 * DLL
263 */
264 struct AttributeDeleteHandle *prev;
265
266 /**
267 * Client connection
268 */
269 struct IdpClient *client;
270
271 /**
272 * Identity
273 */
274 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
275
276
277 /**
278 * QueueEntry
279 */
280 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
281
282 /**
283 * Iterator
284 */
285 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
286
287 /**
288 * The attribute to delete
289 */
290 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
291
292 /**
293 * Tickets to update
294 */
295 struct TicketRecordsEntry *tickets_to_update_head;
296
297 /**
298 * Tickets to update
299 */
300 struct TicketRecordsEntry *tickets_to_update_tail;
301
302 /**
303 * Attribute label
304 */
305 char *label;
306
307 /**
308 * request id
309 */
310 uint32_t r_id;
249}; 311};
250 312
251struct AttributeStoreHandle { 313
314struct AttributeStoreHandle
315{
252 /** 316 /**
253 * DLL 317 * DLL
254 */ 318 */
@@ -295,7 +359,8 @@ struct AttributeStoreHandle {
295 uint32_t r_id; 359 uint32_t r_id;
296}; 360};
297 361
298struct ConsumeTicketOperation { 362struct ConsumeTicketOperation
363{
299 /** 364 /**
300 * DLL 365 * DLL
301 */ 366 */
@@ -325,7 +390,8 @@ struct ConsumeTicketOperation {
325/** 390/**
326 * Updated attribute IDs 391 * Updated attribute IDs
327 */ 392 */
328struct TicketAttributeUpdateEntry { 393struct TicketAttributeUpdateEntry
394{
329 /** 395 /**
330 * DLL 396 * DLL
331 */ 397 */
@@ -350,7 +416,8 @@ struct TicketAttributeUpdateEntry {
350/** 416/**
351 * Ticket revocation request handle 417 * Ticket revocation request handle
352 */ 418 */
353struct TicketRevocationOperation { 419struct TicketRevocationOperation
420{
354 /** 421 /**
355 * DLL 422 * DLL
356 */ 423 */
@@ -380,7 +447,8 @@ struct TicketRevocationOperation {
380/** 447/**
381 * Ticket issue operation handle 448 * Ticket issue operation handle
382 */ 449 */
383struct TicketIssueOperation { 450struct TicketIssueOperation
451{
384 /** 452 /**
385 * DLL 453 * DLL
386 */ 454 */
@@ -407,7 +475,8 @@ struct TicketIssueOperation {
407 * map in json_t format 475 * map in json_t format
408 * 476 *
409 */ 477 */
410struct EgoEntry { 478struct EgoEntry
479{
411 /** 480 /**
412 * DLL 481 * DLL
413 */ 482 */
@@ -438,9 +507,6 @@ cleanup ()
438 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); 507 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
439 508
440 RECLAIM_TICKETS_deinit (); 509 RECLAIM_TICKETS_deinit ();
441 GNUNET_break (NULL == GNUNET_PLUGIN_unload (db_lib_name, TKT_database));
442 GNUNET_free (db_lib_name);
443 db_lib_name = NULL;
444 if (NULL != timeout_task) 510 if (NULL != timeout_task)
445 GNUNET_SCHEDULER_cancel (timeout_task); 511 GNUNET_SCHEDULER_cancel (timeout_task);
446 if (NULL != update_task) 512 if (NULL != update_task)
@@ -673,7 +739,7 @@ attr_store_cont (void *cls, int32_t success, const char *emsg)
673{ 739{
674 struct AttributeStoreHandle *ash = cls; 740 struct AttributeStoreHandle *ash = cls;
675 struct GNUNET_MQ_Envelope *env; 741 struct GNUNET_MQ_Envelope *env;
676 struct AttributeStoreResultMessage *acr_msg; 742 struct SuccessResultMessage *acr_msg;
677 743
678 ash->ns_qe = NULL; 744 ash->ns_qe = NULL;
679 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head, 745 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
@@ -687,10 +753,8 @@ attr_store_cont (void *cls, int32_t success, const char *emsg)
687 return; 753 return;
688 } 754 }
689 755
690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 756 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
691 "Sending ATTRIBUTE_STORE_RESPONSE message\n"); 757 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
692 env = GNUNET_MQ_msg (acr_msg,
693 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE);
694 acr_msg->id = htonl (ash->r_id); 758 acr_msg->id = htonl (ash->r_id);
695 acr_msg->op_result = htonl (GNUNET_OK); 759 acr_msg->op_result = htonl (GNUNET_OK);
696 GNUNET_MQ_send (ash->client->mq, env); 760 GNUNET_MQ_send (ash->client->mq, env);
@@ -771,6 +835,220 @@ handle_attribute_store_message (void *cls,
771 GNUNET_SCHEDULER_add_now (&attr_store_task, ash); 835 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
772} 836}
773 837
838
839static void
840cleanup_adh (struct AttributeDeleteHandle *adh)
841{
842 struct TicketRecordsEntry *le;
843 if (NULL != adh->ns_it)
844 GNUNET_NAMESTORE_zone_iteration_stop (adh->ns_it);
845 if (NULL != adh->ns_qe)
846 GNUNET_NAMESTORE_cancel (adh->ns_qe);
847 if (NULL != adh->label)
848 GNUNET_free (adh->label);
849 if (NULL != adh->claim)
850 GNUNET_free (adh->claim);
851 while (NULL != (le = adh->tickets_to_update_head)) {
852 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
853 adh->tickets_to_update_tail, le);
854 if (NULL != le->label)
855 GNUNET_free (le->label);
856 if (NULL != le->data)
857 GNUNET_free (le->data);
858 GNUNET_free (le);
859 }
860 GNUNET_free (adh);
861}
862
863
864static void
865send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
866{
867 struct GNUNET_MQ_Envelope *env;
868 struct SuccessResultMessage *acr_msg;
869
870 GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
871 adh->client->delete_op_tail, adh);
872
873 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
874 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
875 acr_msg->id = htonl (adh->r_id);
876 acr_msg->op_result = htonl (success);
877 GNUNET_MQ_send (adh->client->mq, env);
878}
879
880
881static void
882ticket_iter (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
883 const char *label, unsigned int rd_count,
884 const struct GNUNET_GNSRECORD_Data *rd)
885{
886 struct AttributeDeleteHandle *adh = cls;
887 struct TicketRecordsEntry *le;
888 int has_changed = GNUNET_NO;
889
890 for (int i = 0; i < rd_count; i++) {
891 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
892 continue;
893 if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t)))
894 continue;
895 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attribute to delete found (%s)\n",
896 adh->label);
897 has_changed = GNUNET_YES;
898 break;
899 }
900 if (GNUNET_YES == has_changed) {
901 le = GNUNET_new (struct TicketRecordsEntry);
902 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
903 le->data = GNUNET_malloc (le->data_size);
904 le->rd_count = rd_count;
905 le->label = GNUNET_strdup (label);
906 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
907 GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head,
908 adh->tickets_to_update_tail, le);
909 }
910 GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
911}
912
913
914static void
915update_tickets (void *cls);
916
917
918static void
919ticket_updated (void *cls, int32_t success, const char *emsg)
920{
921 struct AttributeDeleteHandle *adh = cls;
922 adh->ns_qe = NULL;
923 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
924}
925
926static void
927update_tickets (void *cls)
928{
929 struct AttributeDeleteHandle *adh = cls;
930 struct TicketRecordsEntry *le;
931 if (NULL == adh->tickets_to_update_head) {
932 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
933 "Finished updatding tickets, success\n");
934 send_delete_response (adh, GNUNET_OK);
935 cleanup_adh (adh);
936 return;
937 }
938 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating %s\n",
939 adh->tickets_to_update_head->label);
940 le = adh->tickets_to_update_head;
941 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
942 adh->tickets_to_update_tail, le);
943 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
944 struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1];
945 GNUNET_GNSRECORD_records_deserialize (le->data_size, le->data, le->rd_count,
946 rd);
947 int j = 0;
948 for (int i = 0; i < le->rd_count; i++) {
949 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type) &&
950 (0 == memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t))))
951 continue;
952 rd_new[j] = rd[i];
953 j++;
954 }
955 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &adh->identity, le->label,
956 j, rd_new, &ticket_updated, adh);
957 GNUNET_free (le->label);
958 GNUNET_free (le->data);
959 GNUNET_free (le);
960}
961
962
963static void
964ticket_iter_fin (void *cls)
965{
966 struct AttributeDeleteHandle *adh = cls;
967 adh->ns_it = NULL;
968 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
969}
970
971
972static void
973ticket_iter_err (void *cls)
974{
975 struct AttributeDeleteHandle *adh = cls;
976 adh->ns_it = NULL;
977 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Namestore error on delete %s\n",
978 adh->label);
979 send_delete_response (adh, GNUNET_SYSERR);
980 cleanup_adh (adh);
981}
982
983
984static void
985start_ticket_update (void *cls)
986{
987 struct AttributeDeleteHandle *adh = cls;
988 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
989 nsh, &adh->identity, &ticket_iter_err, adh, &ticket_iter, adh,
990 &ticket_iter_fin, adh);
991}
992
993
994static void
995attr_delete_cont (void *cls, int32_t success, const char *emsg)
996{
997 struct AttributeDeleteHandle *adh = cls;
998 adh->ns_qe = NULL;
999 if (GNUNET_SYSERR == success) {
1000 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error deleting attribute %s (%s)\n",
1001 adh->claim->name, adh->label);
1002 send_delete_response (adh, GNUNET_SYSERR);
1003 cleanup_adh (adh);
1004 return;
1005 }
1006 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating tickets...\n");
1007 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1008}
1009
1010
1011static int
1012check_attribute_delete_message (void *cls,
1013 const struct AttributeDeleteMessage *dam)
1014{
1015 uint16_t size;
1016
1017 size = ntohs (dam->header.size);
1018 if (size <= sizeof (struct AttributeDeleteMessage)) {
1019 GNUNET_break (0);
1020 return GNUNET_SYSERR;
1021 }
1022 return GNUNET_OK;
1023}
1024
1025
1026static void
1027handle_attribute_delete_message (void *cls,
1028 const struct AttributeDeleteMessage *dam)
1029{
1030 struct AttributeDeleteHandle *adh;
1031 struct IdpClient *idp = cls;
1032 size_t data_len;
1033 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received ATTRIBUTE_DELETE message\n");
1034
1035 data_len = ntohs (dam->attr_len);
1036
1037 adh = GNUNET_new (struct AttributeDeleteHandle);
1038 adh->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *)&dam[1], data_len);
1039
1040 adh->r_id = ntohl (dam->id);
1041 adh->identity = dam->identity;
1042 adh->label =
1043 GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id, sizeof (uint64_t));
1044 GNUNET_SERVICE_client_continue (idp->client);
1045 adh->client = idp;
1046 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1047 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &adh->identity, adh->label,
1048 0, NULL, &attr_delete_cont, adh);
1049}
1050
1051
774/************************************************* 1052/*************************************************
775 * Attrubute iteration 1053 * Attrubute iteration
776 *************************************************/ 1054 *************************************************/
@@ -1013,7 +1291,6 @@ static void
1013run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, 1291run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c,
1014 struct GNUNET_SERVICE_Handle *server) 1292 struct GNUNET_SERVICE_Handle *server)
1015{ 1293{
1016 char *database;
1017 cfg = c; 1294 cfg = c;
1018 1295
1019 if (GNUNET_OK != RECLAIM_TICKETS_init (cfg)) { 1296 if (GNUNET_OK != RECLAIM_TICKETS_init (cfg)) {
@@ -1030,19 +1307,6 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c,
1030 } 1307 }
1031 1308
1032 identity_handle = GNUNET_IDENTITY_connect (cfg, NULL, NULL); 1309 identity_handle = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
1033 /* Loading DB plugin */
1034 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (
1035 cfg, "reclaim", "database", &database))
1036 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
1037 GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_reclaim_%s", database);
1038 TKT_database = GNUNET_PLUGIN_load (db_lib_name, (void *)cfg);
1039 GNUNET_free (database);
1040 if (NULL == TKT_database) {
1041 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1042 "Could not load database backend `%s'\n", db_lib_name);
1043 GNUNET_SCHEDULER_shutdown ();
1044 return;
1045 }
1046 1310
1047 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time ( 1311 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (
1048 cfg, "reclaim", "TOKEN_EXPIRATION_INTERVAL", 1312 cfg, "reclaim", "TOKEN_EXPIRATION_INTERVAL",
@@ -1075,6 +1339,7 @@ client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client,
1075 struct TicketIssueOperation *iss; 1339 struct TicketIssueOperation *iss;
1076 struct ConsumeTicketOperation *ct; 1340 struct ConsumeTicketOperation *ct;
1077 struct AttributeStoreHandle *as; 1341 struct AttributeStoreHandle *as;
1342 struct AttributeDeleteHandle *adh;
1078 1343
1079 // TODO other operations 1344 // TODO other operations
1080 1345
@@ -1095,6 +1360,10 @@ client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client,
1095 GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as); 1360 GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as);
1096 cleanup_as_handle (as); 1361 cleanup_as_handle (as);
1097 } 1362 }
1363 while (NULL != (adh = idp->delete_op_head)) {
1364 GNUNET_CONTAINER_DLL_remove (idp->delete_op_head, idp->delete_op_tail, adh);
1365 cleanup_adh (adh);
1366 }
1098 1367
1099 while (NULL != (ai = idp->attr_iter_head)) { 1368 while (NULL != (ai = idp->attr_iter_head)) {
1100 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai); 1369 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
@@ -1143,6 +1412,9 @@ GNUNET_SERVICE_MAIN (
1143 GNUNET_MQ_hd_var_size (attribute_store_message, 1412 GNUNET_MQ_hd_var_size (attribute_store_message,
1144 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE, 1413 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
1145 struct AttributeStoreMessage, NULL), 1414 struct AttributeStoreMessage, NULL),
1415 GNUNET_MQ_hd_var_size (attribute_delete_message,
1416 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
1417 struct AttributeDeleteMessage, NULL),
1146 GNUNET_MQ_hd_fixed_size ( 1418 GNUNET_MQ_hd_fixed_size (
1147 iteration_start, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START, 1419 iteration_start, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
1148 struct AttributeIterationStartMessage, NULL), 1420 struct AttributeIterationStartMessage, NULL),