2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @author Martin Schanzenbach
22 * @file src/reclaim/gnunet-service-reclaim.c
23 * @brief reclaim Service
28 #include "gnunet_util_lib.h"
30 #include "gnunet-service-reclaim_tickets.h"
31 #include "gnunet_constants.h"
32 #include "gnunet_gnsrecord_lib.h"
33 #include "gnunet_identity_service.h"
34 #include "gnunet_namestore_service.h"
35 #include "gnunet_protocols.h"
36 #include "gnunet_reclaim_attribute_lib.h"
37 #include "gnunet_reclaim_service.h"
38 #include "gnunet_signatures.h"
47 * Normal operation state
49 #define STATE_POST_INIT 1
52 * Minimum interval between updates
54 #define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
57 * Standard token expiration time
59 #define DEFAULT_TOKEN_EXPIRATION_INTERVAL GNUNET_TIME_UNIT_HOURS
64 static struct GNUNET_IDENTITY_Handle *identity_handle;
67 * Token expiration interval
69 static struct GNUNET_TIME_Relative token_expiration_interval;
74 static struct GNUNET_NAMESTORE_Handle *nsh;
79 static struct GNUNET_SCHEDULER_Task *timeout_task;
84 static struct GNUNET_SCHEDULER_Task *update_task;
89 static const struct GNUNET_CONFIGURATION_Handle *cfg;
97 * A ticket iteration operation.
99 struct TicketIteration
104 struct TicketIteration *next;
109 struct TicketIteration *prev;
112 * Client which intiated this zone iteration
114 struct IdpClient *client;
117 * The operation id fot the iteration in the response for the client
122 * The ticket iterator
124 struct RECLAIM_TICKETS_Iterator *iter;
128 * An attribute iteration operation.
130 struct AttributeIterator
133 * Next element in the DLL
135 struct AttributeIterator *next;
138 * Previous element in the DLL
140 struct AttributeIterator *prev;
143 * IDP client which intiated this zone iteration
145 struct IdpClient *client;
148 * Key of the zone we are iterating over.
150 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
155 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
158 * The operation id fot the zone iteration in the response for the client
172 struct GNUNET_SERVICE_Client *client;
175 * Message queue for transmission to @e client
177 struct GNUNET_MQ_Handle *mq;
181 * Attribute iteration operations in
182 * progress initiated by this client
184 struct AttributeIterator *attr_iter_head;
188 * Attribute iteration operations
189 * in progress initiated by this client
191 struct AttributeIterator *attr_iter_tail;
194 * Head of DLL of ticket iteration ops
196 struct TicketIteration *ticket_iter_head;
199 * Tail of DLL of ticket iteration ops
201 struct TicketIteration *ticket_iter_tail;
204 * Head of DLL of ticket revocation ops
206 struct TicketRevocationOperation *revoke_op_head;
209 * Tail of DLL of ticket revocation ops
211 struct TicketRevocationOperation *revoke_op_tail;
214 * Head of DLL of ticket issue ops
216 struct TicketIssueOperation *issue_op_head;
219 * Tail of DLL of ticket issue ops
221 struct TicketIssueOperation *issue_op_tail;
224 * Head of DLL of ticket consume ops
226 struct ConsumeTicketOperation *consume_op_head;
229 * Tail of DLL of ticket consume ops
231 struct ConsumeTicketOperation *consume_op_tail;
234 * Head of DLL of attribute store ops
236 struct AttributeStoreHandle *store_op_head;
239 * Tail of DLL of attribute store ops
241 struct AttributeStoreHandle *store_op_tail;
243 * Head of DLL of attribute delete ops
245 struct AttributeDeleteHandle *delete_op_head;
248 * Tail of DLL of attribute delete ops
250 struct AttributeDeleteHandle *delete_op_tail;
254 struct AttributeDeleteHandle
259 struct AttributeDeleteHandle *next;
264 struct AttributeDeleteHandle *prev;
269 struct IdpClient *client;
274 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
280 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
285 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
288 * The attribute to delete
290 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
295 struct TicketRecordsEntry *tickets_to_update_head;
300 struct TicketRecordsEntry *tickets_to_update_tail;
314 struct AttributeStoreHandle
319 struct AttributeStoreHandle *next;
324 struct AttributeStoreHandle *prev;
329 struct IdpClient *client;
334 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
339 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
344 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
347 * The attribute to store
349 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
352 * The attribute expiration interval
354 struct GNUNET_TIME_Relative exp;
362 struct ConsumeTicketOperation
367 struct ConsumeTicketOperation *next;
372 struct ConsumeTicketOperation *prev;
377 struct IdpClient *client;
385 * Ticket consume handle
387 struct RECLAIM_TICKETS_ConsumeHandle *ch;
391 * Updated attribute IDs
393 struct TicketAttributeUpdateEntry
398 struct TicketAttributeUpdateEntry *next;
403 struct TicketAttributeUpdateEntry *prev;
417 * Ticket revocation request handle
419 struct TicketRevocationOperation
424 struct TicketRevocationOperation *prev;
429 struct TicketRevocationOperation *next;
434 struct IdpClient *client;
439 struct RECLAIM_TICKETS_RevokeHandle *rh;
448 * Ticket issue operation handle
450 struct TicketIssueOperation
455 struct TicketIssueOperation *prev;
460 struct TicketIssueOperation *next;
465 struct IdpClient *client;
474 * DLL for ego handles to egos containing the RECLAIM_ATTRS in a
475 * map in json_t format
483 struct EgoEntry *next;
488 struct EgoEntry *prev;
493 struct GNUNET_IDENTITY_Ego *ego;
496 * Attribute map. Contains the attributes as json_t
498 struct GNUNET_CONTAINER_MultiHashMap *attr_map;
507 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
509 RECLAIM_TICKETS_deinit ();
510 if (NULL != timeout_task)
511 GNUNET_SCHEDULER_cancel (timeout_task);
512 if (NULL != update_task)
513 GNUNET_SCHEDULER_cancel (update_task);
514 if (NULL != identity_handle)
515 GNUNET_IDENTITY_disconnect (identity_handle);
517 GNUNET_NAMESTORE_disconnect (nsh);
526 do_shutdown (void *cls)
528 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
534 send_ticket_result (const struct IdpClient *client,
536 const struct GNUNET_RECLAIM_Ticket *ticket,
539 struct TicketResultMessage *irm;
540 struct GNUNET_MQ_Envelope *env;
541 struct GNUNET_RECLAIM_Ticket *ticket_buf;
543 if (NULL != ticket) {
544 env = GNUNET_MQ_msg_extra (irm,
545 sizeof (struct GNUNET_RECLAIM_Ticket),
546 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
547 ticket_buf = (struct GNUNET_RECLAIM_Ticket *)&irm[1];
548 *ticket_buf = *ticket;
550 env = GNUNET_MQ_msg (irm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
552 // TODO add success member
553 irm->id = htonl (r_id);
554 GNUNET_MQ_send (client->mq, env);
558 issue_ticket_result_cb (void *cls,
559 struct GNUNET_RECLAIM_Ticket *ticket,
563 struct TicketIssueOperation *tio = cls;
564 if (GNUNET_OK != success) {
565 send_ticket_result (tio->client, tio->r_id, NULL, GNUNET_SYSERR);
566 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
567 tio->client->issue_op_tail,
570 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error issuing ticket: %s\n", emsg);
573 send_ticket_result (tio->client, tio->r_id, ticket, GNUNET_SYSERR);
574 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
575 tio->client->issue_op_tail,
581 check_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
585 size = ntohs (im->header.size);
586 if (size <= sizeof (struct IssueTicketMessage)) {
588 return GNUNET_SYSERR;
594 handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
596 struct TicketIssueOperation *tio;
597 struct IdpClient *idp = cls;
598 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
601 tio = GNUNET_new (struct TicketIssueOperation);
602 attrs_len = ntohs (im->attr_len);
603 attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *)&im[1], attrs_len);
604 tio->r_id = ntohl (im->id);
606 GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, idp->issue_op_tail, tio);
607 RECLAIM_TICKETS_issue (&im->identity,
610 &issue_ticket_result_cb,
612 GNUNET_SERVICE_client_continue (idp->client);
613 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
616 /**********************************************************
618 **********************************************************/
621 revoke_result_cb (void *cls, int32_t success)
623 struct TicketRevocationOperation *rop = cls;
624 struct GNUNET_MQ_Envelope *env;
625 struct RevokeTicketResultMessage *trm;
628 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT);
629 trm->id = htonl (rop->r_id);
630 trm->success = htonl (success);
631 GNUNET_MQ_send (rop->client->mq, env);
632 GNUNET_CONTAINER_DLL_remove (rop->client->revoke_op_head,
633 rop->client->revoke_op_tail,
640 check_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *im)
644 size = ntohs (im->header.size);
645 if (size <= sizeof (struct RevokeTicketMessage)) {
647 return GNUNET_SYSERR;
653 handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm)
655 struct TicketRevocationOperation *rop;
656 struct IdpClient *idp = cls;
657 struct GNUNET_RECLAIM_Ticket *ticket;
659 rop = GNUNET_new (struct TicketRevocationOperation);
660 ticket = (struct GNUNET_RECLAIM_Ticket *)&rm[1];
661 rop->r_id = ntohl (rm->id);
663 GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, idp->revoke_op_tail, rop);
665 = RECLAIM_TICKETS_revoke (ticket, &rm->identity, &revoke_result_cb, rop);
666 GNUNET_SERVICE_client_continue (idp->client);
670 check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
674 size = ntohs (cm->header.size);
675 if (size <= sizeof (struct ConsumeTicketMessage)) {
677 return GNUNET_SYSERR;
683 consume_result_cb (void *cls,
684 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
685 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
689 struct ConsumeTicketOperation *cop = cls;
690 struct ConsumeTicketResultMessage *crm;
691 struct GNUNET_MQ_Envelope *env;
694 if (GNUNET_OK != success) {
695 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error consuming ticket: %s\n", emsg);
697 attrs_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
698 env = GNUNET_MQ_msg_extra (crm,
700 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
701 crm->id = htonl (cop->r_id);
702 crm->attrs_len = htons (attrs_len);
703 crm->identity = *identity;
704 crm->result = htonl (success);
705 data_tmp = (char *)&crm[1];
706 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, data_tmp);
707 GNUNET_MQ_send (cop->client->mq, env);
708 GNUNET_CONTAINER_DLL_remove (cop->client->consume_op_head,
709 cop->client->consume_op_tail,
715 handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
717 struct ConsumeTicketOperation *cop;
718 struct GNUNET_RECLAIM_Ticket *ticket;
719 struct IdpClient *idp = cls;
721 cop = GNUNET_new (struct ConsumeTicketOperation);
722 cop->r_id = ntohl (cm->id);
724 ticket = (struct GNUNET_RECLAIM_Ticket *)&cm[1];
726 = RECLAIM_TICKETS_consume (&cm->identity, ticket, &consume_result_cb, cop);
727 GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop);
728 GNUNET_SERVICE_client_continue (idp->client);
731 /*****************************************
733 *****************************************/
736 * Cleanup attribute store handle
738 * @param handle handle to clean up
741 cleanup_as_handle (struct AttributeStoreHandle *ash)
743 if (NULL != ash->ns_qe)
744 GNUNET_NAMESTORE_cancel (ash->ns_qe);
745 if (NULL != ash->claim)
746 GNUNET_free (ash->claim);
751 attr_store_cont (void *cls, int32_t success, const char *emsg)
753 struct AttributeStoreHandle *ash = cls;
754 struct GNUNET_MQ_Envelope *env;
755 struct SuccessResultMessage *acr_msg;
758 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
759 ash->client->store_op_tail,
762 if (GNUNET_SYSERR == success) {
763 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
764 "Failed to store attribute %s\n",
766 cleanup_as_handle (ash);
767 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
771 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
772 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
773 acr_msg->id = htonl (ash->r_id);
774 acr_msg->op_result = htonl (GNUNET_OK);
775 GNUNET_MQ_send (ash->client->mq, env);
776 cleanup_as_handle (ash);
780 * Adds a new attribute
782 * @param cls the AttributeStoreHandle
785 attr_store_task (void *cls)
787 struct AttributeStoreHandle *ash = cls;
788 struct GNUNET_GNSRECORD_Data rd[1];
793 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing attribute\n");
794 buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (ash->claim);
795 buf = GNUNET_malloc (buf_size);
796 // Give the ash a new id if unset
797 if (0 == ash->claim->id)
799 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
800 GNUNET_RECLAIM_ATTRIBUTE_serialize (ash->claim, buf);
802 = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id, sizeof (uint64_t));
803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
805 rd[0].data_size = buf_size;
807 rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR;
808 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
809 rd[0].expiration_time = ash->exp.rel_value_us;
810 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
821 check_attribute_store_message (void *cls,
822 const struct AttributeStoreMessage *sam)
826 size = ntohs (sam->header.size);
827 if (size <= sizeof (struct AttributeStoreMessage)) {
829 return GNUNET_SYSERR;
835 handle_attribute_store_message (void *cls,
836 const struct AttributeStoreMessage *sam)
838 struct AttributeStoreHandle *ash;
839 struct IdpClient *idp = cls;
841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_STORE message\n");
843 data_len = ntohs (sam->attr_len);
845 ash = GNUNET_new (struct AttributeStoreHandle);
846 ash->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *)&sam[1], data_len);
848 ash->r_id = ntohl (sam->id);
849 ash->identity = sam->identity;
850 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
851 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
853 GNUNET_SERVICE_client_continue (idp->client);
855 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
856 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
861 cleanup_adh (struct AttributeDeleteHandle *adh)
863 struct TicketRecordsEntry *le;
864 if (NULL != adh->ns_it)
865 GNUNET_NAMESTORE_zone_iteration_stop (adh->ns_it);
866 if (NULL != adh->ns_qe)
867 GNUNET_NAMESTORE_cancel (adh->ns_qe);
868 if (NULL != adh->label)
869 GNUNET_free (adh->label);
870 if (NULL != adh->claim)
871 GNUNET_free (adh->claim);
872 while (NULL != (le = adh->tickets_to_update_head)) {
873 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
874 adh->tickets_to_update_tail,
876 if (NULL != le->label)
877 GNUNET_free (le->label);
878 if (NULL != le->data)
879 GNUNET_free (le->data);
887 send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
889 struct GNUNET_MQ_Envelope *env;
890 struct SuccessResultMessage *acr_msg;
892 GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
893 adh->client->delete_op_tail,
896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
897 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
898 acr_msg->id = htonl (adh->r_id);
899 acr_msg->op_result = htonl (success);
900 GNUNET_MQ_send (adh->client->mq, env);
905 ticket_iter (void *cls,
906 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
908 unsigned int rd_count,
909 const struct GNUNET_GNSRECORD_Data *rd)
911 struct AttributeDeleteHandle *adh = cls;
912 struct TicketRecordsEntry *le;
913 int has_changed = GNUNET_NO;
915 for (int i = 0; i < rd_count; i++) {
916 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
918 if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t)))
920 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
921 "Attribute to delete found (%s)\n",
923 has_changed = GNUNET_YES;
926 if (GNUNET_YES == has_changed) {
927 le = GNUNET_new (struct TicketRecordsEntry);
928 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
929 le->data = GNUNET_malloc (le->data_size);
930 le->rd_count = rd_count;
931 le->label = GNUNET_strdup (label);
932 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
933 GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head,
934 adh->tickets_to_update_tail,
937 GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
942 update_tickets (void *cls);
946 ticket_updated (void *cls, int32_t success, const char *emsg)
948 struct AttributeDeleteHandle *adh = cls;
950 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
954 update_tickets (void *cls)
956 struct AttributeDeleteHandle *adh = cls;
957 struct TicketRecordsEntry *le;
958 if (NULL == adh->tickets_to_update_head) {
959 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
960 "Finished updatding tickets, success\n");
961 send_delete_response (adh, GNUNET_OK);
965 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
967 adh->tickets_to_update_head->label);
968 le = adh->tickets_to_update_head;
969 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
970 adh->tickets_to_update_tail,
972 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
973 struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1];
974 GNUNET_GNSRECORD_records_deserialize (le->data_size,
979 for (int i = 0; i < le->rd_count; i++) {
980 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
981 && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t))))
986 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
993 GNUNET_free (le->label);
994 GNUNET_free (le->data);
1000 ticket_iter_fin (void *cls)
1002 struct AttributeDeleteHandle *adh = cls;
1004 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1009 ticket_iter_err (void *cls)
1011 struct AttributeDeleteHandle *adh = cls;
1013 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1014 "Namestore error on delete %s\n",
1016 send_delete_response (adh, GNUNET_SYSERR);
1022 start_ticket_update (void *cls)
1024 struct AttributeDeleteHandle *adh = cls;
1025 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1037 attr_delete_cont (void *cls, int32_t success, const char *emsg)
1039 struct AttributeDeleteHandle *adh = cls;
1041 if (GNUNET_SYSERR == success) {
1042 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1043 "Error deleting attribute %s\n",
1045 send_delete_response (adh, GNUNET_SYSERR);
1049 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating tickets...\n");
1050 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1055 check_attribute_delete_message (void *cls,
1056 const struct AttributeDeleteMessage *dam)
1060 size = ntohs (dam->header.size);
1061 if (size <= sizeof (struct AttributeDeleteMessage)) {
1063 return GNUNET_SYSERR;
1070 handle_attribute_delete_message (void *cls,
1071 const struct AttributeDeleteMessage *dam)
1073 struct AttributeDeleteHandle *adh;
1074 struct IdpClient *idp = cls;
1076 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received ATTRIBUTE_DELETE message\n");
1078 data_len = ntohs (dam->attr_len);
1080 adh = GNUNET_new (struct AttributeDeleteHandle);
1081 adh->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *)&dam[1], data_len);
1083 adh->r_id = ntohl (dam->id);
1084 adh->identity = dam->identity;
1086 = GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id, sizeof (uint64_t));
1087 GNUNET_SERVICE_client_continue (idp->client);
1089 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1090 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1100 /*************************************************
1101 * Attrubute iteration
1102 *************************************************/
1105 cleanup_attribute_iter_handle (struct AttributeIterator *ai)
1111 attr_iter_error (void *cls)
1113 struct AttributeIterator *ai = cls;
1114 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
1115 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
1116 ai->client->attr_iter_tail,
1118 cleanup_attribute_iter_handle (ai);
1119 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1123 attr_iter_finished (void *cls)
1125 struct AttributeIterator *ai = cls;
1126 struct GNUNET_MQ_Envelope *env;
1127 struct AttributeResultMessage *arm;
1129 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1130 arm->id = htonl (ai->request_id);
1131 arm->attr_len = htons (0);
1132 GNUNET_MQ_send (ai->client->mq, env);
1133 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
1134 ai->client->attr_iter_tail,
1136 cleanup_attribute_iter_handle (ai);
1140 attr_iter_cb (void *cls,
1141 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1143 unsigned int rd_count,
1144 const struct GNUNET_GNSRECORD_Data *rd)
1146 struct AttributeIterator *ai = cls;
1147 struct AttributeResultMessage *arm;
1148 struct GNUNET_MQ_Envelope *env;
1151 if (rd_count != 1) {
1152 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1156 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd->record_type) {
1157 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1160 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n", label);
1161 env = GNUNET_MQ_msg_extra (arm,
1163 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1164 arm->id = htonl (ai->request_id);
1165 arm->attr_len = htons (rd->data_size);
1166 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
1167 data_tmp = (char *)&arm[1];
1168 GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
1169 GNUNET_MQ_send (ai->client->mq, env);
1173 handle_iteration_start (void *cls,
1174 const struct AttributeIterationStartMessage *ais_msg)
1176 struct IdpClient *idp = cls;
1177 struct AttributeIterator *ai;
1179 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1180 "Received ATTRIBUTE_ITERATION_START message\n");
1181 ai = GNUNET_new (struct AttributeIterator);
1182 ai->request_id = ntohl (ais_msg->id);
1184 ai->identity = ais_msg->identity;
1186 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, idp->attr_iter_tail, ai);
1187 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1193 &attr_iter_finished,
1195 GNUNET_SERVICE_client_continue (idp->client);
1199 handle_iteration_stop (void *cls,
1200 const struct AttributeIterationStopMessage *ais_msg)
1202 struct IdpClient *idp = cls;
1203 struct AttributeIterator *ai;
1206 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1207 "Received `%s' message\n",
1208 "ATTRIBUTE_ITERATION_STOP");
1209 rid = ntohl (ais_msg->id);
1210 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1211 if (ai->request_id == rid)
1215 GNUNET_SERVICE_client_drop (idp->client);
1218 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
1220 GNUNET_SERVICE_client_continue (idp->client);
1224 handle_iteration_next (void *cls,
1225 const struct AttributeIterationNextMessage *ais_msg)
1227 struct IdpClient *idp = cls;
1228 struct AttributeIterator *ai;
1231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1232 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1233 rid = ntohl (ais_msg->id);
1234 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1235 if (ai->request_id == rid)
1239 GNUNET_SERVICE_client_drop (idp->client);
1242 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1243 GNUNET_SERVICE_client_continue (idp->client);
1246 /******************************************************
1248 ******************************************************/
1251 ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
1253 struct TicketIteration *ti = cls;
1254 struct GNUNET_MQ_Envelope *env;
1255 struct TicketResultMessage *trm;
1257 if (NULL == ticket) {
1258 /* send empty response to indicate end of list */
1259 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
1260 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
1261 ti->client->ticket_iter_tail,
1264 env = GNUNET_MQ_msg_extra (trm,
1265 sizeof (struct GNUNET_RECLAIM_Ticket),
1266 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
1267 memcpy (&trm[1], ticket, sizeof (struct GNUNET_RECLAIM_Ticket));
1269 trm->id = htonl (ti->r_id);
1270 GNUNET_MQ_send (ti->client->mq, env);
1276 handle_ticket_iteration_start (
1278 const struct TicketIterationStartMessage *tis_msg)
1280 struct IdpClient *client = cls;
1281 struct TicketIteration *ti;
1283 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1284 "Received TICKET_ITERATION_START message\n");
1285 ti = GNUNET_new (struct TicketIteration);
1286 ti->r_id = ntohl (tis_msg->id);
1287 ti->client = client;
1289 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
1290 client->ticket_iter_tail,
1293 = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti);
1294 GNUNET_SERVICE_client_continue (client->client);
1298 handle_ticket_iteration_stop (void *cls,
1299 const struct TicketIterationStopMessage *tis_msg)
1301 struct IdpClient *client = cls;
1302 struct TicketIteration *ti;
1305 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1306 "Received `%s' message\n",
1307 "TICKET_ITERATION_STOP");
1308 rid = ntohl (tis_msg->id);
1309 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
1310 if (ti->r_id == rid)
1314 GNUNET_SERVICE_client_drop (client->client);
1317 RECLAIM_TICKETS_iteration_stop (ti->iter);
1318 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
1319 client->ticket_iter_tail,
1322 GNUNET_SERVICE_client_continue (client->client);
1326 handle_ticket_iteration_next (void *cls,
1327 const struct TicketIterationNextMessage *tis_msg)
1329 struct IdpClient *client = cls;
1330 struct TicketIteration *ti;
1333 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1334 "Received TICKET_ITERATION_NEXT message\n");
1335 rid = ntohl (tis_msg->id);
1336 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
1337 if (ti->r_id == rid)
1341 GNUNET_SERVICE_client_drop (client->client);
1344 RECLAIM_TICKETS_iteration_next (ti->iter);
1345 GNUNET_SERVICE_client_continue (client->client);
1349 * Main function that will be run
1351 * @param cls closure
1352 * @param c the configuration used
1353 * @param server the service handle
1357 const struct GNUNET_CONFIGURATION_Handle *c,
1358 struct GNUNET_SERVICE_Handle *server)
1362 if (GNUNET_OK != RECLAIM_TICKETS_init (cfg)) {
1363 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1364 "Unable to initialized TICKETS subsystem.\n");
1365 GNUNET_SCHEDULER_shutdown ();
1368 // Connect to identity and namestore services
1369 nsh = GNUNET_NAMESTORE_connect (cfg);
1371 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1372 "error connecting to namestore");
1375 identity_handle = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
1378 == GNUNET_CONFIGURATION_get_value_time (cfg,
1380 "TOKEN_EXPIRATION_INTERVAL",
1381 &token_expiration_interval)) {
1383 GNUNET_ERROR_TYPE_DEBUG,
1384 "Time window for zone iteration: %s\n",
1385 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
1388 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
1391 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
1395 * Called whenever a client is disconnected.
1397 * @param cls closure
1398 * @param client identification of the client
1399 * @param app_ctx @a client
1402 client_disconnect_cb (void *cls,
1403 struct GNUNET_SERVICE_Client *client,
1406 struct IdpClient *idp = app_ctx;
1407 struct AttributeIterator *ai;
1408 struct TicketIteration *ti;
1409 struct TicketRevocationOperation *rop;
1410 struct TicketIssueOperation *iss;
1411 struct ConsumeTicketOperation *ct;
1412 struct AttributeStoreHandle *as;
1413 struct AttributeDeleteHandle *adh;
1415 // TODO other operations
1417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1419 while (NULL != (iss = idp->issue_op_head)) {
1420 GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, idp->issue_op_tail, iss);
1423 while (NULL != (ct = idp->consume_op_head)) {
1424 GNUNET_CONTAINER_DLL_remove (idp->consume_op_head,
1425 idp->consume_op_tail,
1428 RECLAIM_TICKETS_consume_cancel (ct->ch);
1431 while (NULL != (as = idp->store_op_head)) {
1432 GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as);
1433 cleanup_as_handle (as);
1435 while (NULL != (adh = idp->delete_op_head)) {
1436 GNUNET_CONTAINER_DLL_remove (idp->delete_op_head, idp->delete_op_tail, adh);
1440 while (NULL != (ai = idp->attr_iter_head)) {
1441 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
1442 cleanup_attribute_iter_handle (ai);
1444 while (NULL != (rop = idp->revoke_op_head)) {
1445 GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, idp->revoke_op_tail, rop);
1446 if (NULL != rop->rh)
1447 RECLAIM_TICKETS_revoke_cancel (rop->rh);
1450 while (NULL != (ti = idp->ticket_iter_head)) {
1451 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
1452 idp->ticket_iter_tail,
1460 * Add a client to our list of active clients.
1463 * @param client client to add
1464 * @param mq message queue for @a client
1465 * @return internal namestore client structure for this client
1468 client_connect_cb (void *cls,
1469 struct GNUNET_SERVICE_Client *client,
1470 struct GNUNET_MQ_Handle *mq)
1472 struct IdpClient *idp;
1473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1474 idp = GNUNET_new (struct IdpClient);
1475 idp->client = client;
1481 * Define "main" method using service macro.
1483 GNUNET_SERVICE_MAIN (
1485 GNUNET_SERVICE_OPTION_NONE,
1488 &client_disconnect_cb,
1490 GNUNET_MQ_hd_var_size (attribute_store_message,
1491 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
1492 struct AttributeStoreMessage,
1494 GNUNET_MQ_hd_var_size (attribute_delete_message,
1495 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
1496 struct AttributeDeleteMessage,
1498 GNUNET_MQ_hd_fixed_size (
1500 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
1501 struct AttributeIterationStartMessage,
1503 GNUNET_MQ_hd_fixed_size (iteration_next,
1504 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
1505 struct AttributeIterationNextMessage,
1507 GNUNET_MQ_hd_fixed_size (iteration_stop,
1508 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
1509 struct AttributeIterationStopMessage,
1511 GNUNET_MQ_hd_var_size (issue_ticket_message,
1512 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
1513 struct IssueTicketMessage,
1515 GNUNET_MQ_hd_var_size (consume_ticket_message,
1516 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
1517 struct ConsumeTicketMessage,
1519 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
1520 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
1521 struct TicketIterationStartMessage,
1523 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
1524 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
1525 struct TicketIterationNextMessage,
1527 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
1528 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
1529 struct TicketIterationStopMessage,
1531 GNUNET_MQ_hd_var_size (revoke_ticket_message,
1532 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
1533 struct RevokeTicketMessage,
1535 GNUNET_MQ_handler_end ());
1536 /* end of gnunet-service-reclaim.c */