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_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
555 GNUNET_MQ_send (client->mq, env);
559 issue_ticket_result_cb (void *cls,
560 struct GNUNET_RECLAIM_Ticket *ticket,
564 struct TicketIssueOperation *tio = cls;
565 if (GNUNET_OK != success) {
566 send_ticket_result (tio->client, tio->r_id, NULL, GNUNET_SYSERR);
567 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
568 tio->client->issue_op_tail,
571 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error issuing ticket: %s\n", emsg);
574 send_ticket_result (tio->client, tio->r_id, ticket, GNUNET_SYSERR);
575 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
576 tio->client->issue_op_tail,
582 check_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
586 size = ntohs (im->header.size);
587 if (size <= sizeof (struct IssueTicketMessage)) {
589 return GNUNET_SYSERR;
595 handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
597 struct TicketIssueOperation *tio;
598 struct IdpClient *idp = cls;
599 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
602 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ISSUE_TICKET message\n");
603 tio = GNUNET_new (struct TicketIssueOperation);
604 attrs_len = ntohs (im->attr_len);
605 attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *)&im[1], attrs_len);
606 tio->r_id = ntohl (im->id);
608 GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, idp->issue_op_tail, tio);
609 RECLAIM_TICKETS_issue (&im->identity,
612 &issue_ticket_result_cb,
614 GNUNET_SERVICE_client_continue (idp->client);
615 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
618 /**********************************************************
620 **********************************************************/
623 revoke_result_cb (void *cls, int32_t success)
625 struct TicketRevocationOperation *rop = cls;
626 struct GNUNET_MQ_Envelope *env;
627 struct RevokeTicketResultMessage *trm;
629 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending REVOKE_TICKET_RESULT message\n");
631 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT);
632 trm->id = htonl (rop->r_id);
633 trm->success = htonl (success);
634 GNUNET_MQ_send (rop->client->mq, env);
635 GNUNET_CONTAINER_DLL_remove (rop->client->revoke_op_head,
636 rop->client->revoke_op_tail,
643 check_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *im)
647 size = ntohs (im->header.size);
648 if (size <= sizeof (struct RevokeTicketMessage)) {
650 return GNUNET_SYSERR;
656 handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm)
658 struct TicketRevocationOperation *rop;
659 struct IdpClient *idp = cls;
660 struct GNUNET_RECLAIM_Ticket *ticket;
662 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REVOKE_TICKET message\n");
663 rop = GNUNET_new (struct TicketRevocationOperation);
664 ticket = (struct GNUNET_RECLAIM_Ticket *)&rm[1];
665 rop->r_id = ntohl (rm->id);
667 GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, idp->revoke_op_tail, rop);
669 = RECLAIM_TICKETS_revoke (ticket, &rm->identity, &revoke_result_cb, rop);
670 GNUNET_SERVICE_client_continue (idp->client);
674 check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
678 size = ntohs (cm->header.size);
679 if (size <= sizeof (struct ConsumeTicketMessage)) {
681 return GNUNET_SYSERR;
687 consume_result_cb (void *cls,
688 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
689 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
693 struct ConsumeTicketOperation *cop = cls;
694 struct ConsumeTicketResultMessage *crm;
695 struct GNUNET_MQ_Envelope *env;
698 if (GNUNET_OK != success) {
699 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error consuming ticket: %s\n", emsg);
701 attrs_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
702 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CONSUME_TICKET_RESULT message\n");
703 env = GNUNET_MQ_msg_extra (crm,
705 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
706 crm->id = htonl (cop->r_id);
707 crm->attrs_len = htons (attrs_len);
708 crm->identity = *identity;
709 crm->result = htonl (success);
710 data_tmp = (char *)&crm[1];
711 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, data_tmp);
712 GNUNET_MQ_send (cop->client->mq, env);
713 GNUNET_CONTAINER_DLL_remove (cop->client->consume_op_head,
714 cop->client->consume_op_tail,
720 handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
722 struct ConsumeTicketOperation *cop;
723 struct GNUNET_RECLAIM_Ticket *ticket;
724 struct IdpClient *idp = cls;
726 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CONSUME_TICKET message\n");
727 cop = GNUNET_new (struct ConsumeTicketOperation);
728 cop->r_id = ntohl (cm->id);
730 ticket = (struct GNUNET_RECLAIM_Ticket *)&cm[1];
732 = RECLAIM_TICKETS_consume (&cm->identity, ticket, &consume_result_cb, cop);
733 GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop);
734 GNUNET_SERVICE_client_continue (idp->client);
737 /*****************************************
739 *****************************************/
742 * Cleanup attribute store handle
744 * @param handle handle to clean up
747 cleanup_as_handle (struct AttributeStoreHandle *ash)
749 if (NULL != ash->ns_qe)
750 GNUNET_NAMESTORE_cancel (ash->ns_qe);
751 if (NULL != ash->claim)
752 GNUNET_free (ash->claim);
757 attr_store_cont (void *cls, int32_t success, const char *emsg)
759 struct AttributeStoreHandle *ash = cls;
760 struct GNUNET_MQ_Envelope *env;
761 struct SuccessResultMessage *acr_msg;
764 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
765 ash->client->store_op_tail,
768 if (GNUNET_SYSERR == success) {
769 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
770 "Failed to store attribute %s\n",
772 cleanup_as_handle (ash);
773 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
777 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
778 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
779 acr_msg->id = htonl (ash->r_id);
780 acr_msg->op_result = htonl (GNUNET_OK);
781 GNUNET_MQ_send (ash->client->mq, env);
782 cleanup_as_handle (ash);
786 * Adds a new attribute
788 * @param cls the AttributeStoreHandle
791 attr_store_task (void *cls)
793 struct AttributeStoreHandle *ash = cls;
794 struct GNUNET_GNSRECORD_Data rd[1];
799 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing attribute\n");
800 buf_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (ash->claim);
801 buf = GNUNET_malloc (buf_size);
802 // Give the ash a new id if unset
803 if (0 == ash->claim->id)
805 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
806 GNUNET_RECLAIM_ATTRIBUTE_serialize (ash->claim, buf);
808 = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id, sizeof (uint64_t));
809 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
811 rd[0].data_size = buf_size;
813 rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR;
814 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
815 rd[0].expiration_time = ash->exp.rel_value_us;
816 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
827 check_attribute_store_message (void *cls,
828 const struct AttributeStoreMessage *sam)
832 size = ntohs (sam->header.size);
833 if (size <= sizeof (struct AttributeStoreMessage)) {
835 return GNUNET_SYSERR;
841 handle_attribute_store_message (void *cls,
842 const struct AttributeStoreMessage *sam)
844 struct AttributeStoreHandle *ash;
845 struct IdpClient *idp = cls;
847 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_STORE message\n");
849 data_len = ntohs (sam->attr_len);
851 ash = GNUNET_new (struct AttributeStoreHandle);
852 ash->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *)&sam[1], data_len);
854 ash->r_id = ntohl (sam->id);
855 ash->identity = sam->identity;
856 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
857 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
859 GNUNET_SERVICE_client_continue (idp->client);
861 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
862 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
867 cleanup_adh (struct AttributeDeleteHandle *adh)
869 struct TicketRecordsEntry *le;
870 if (NULL != adh->ns_it)
871 GNUNET_NAMESTORE_zone_iteration_stop (adh->ns_it);
872 if (NULL != adh->ns_qe)
873 GNUNET_NAMESTORE_cancel (adh->ns_qe);
874 if (NULL != adh->label)
875 GNUNET_free (adh->label);
876 if (NULL != adh->claim)
877 GNUNET_free (adh->claim);
878 while (NULL != (le = adh->tickets_to_update_head)) {
879 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
880 adh->tickets_to_update_tail,
882 if (NULL != le->label)
883 GNUNET_free (le->label);
884 if (NULL != le->data)
885 GNUNET_free (le->data);
893 send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
895 struct GNUNET_MQ_Envelope *env;
896 struct SuccessResultMessage *acr_msg;
898 GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
899 adh->client->delete_op_tail,
902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
903 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
904 acr_msg->id = htonl (adh->r_id);
905 acr_msg->op_result = htonl (success);
906 GNUNET_MQ_send (adh->client->mq, env);
911 ticket_iter (void *cls,
912 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
914 unsigned int rd_count,
915 const struct GNUNET_GNSRECORD_Data *rd)
917 struct AttributeDeleteHandle *adh = cls;
918 struct TicketRecordsEntry *le;
919 int has_changed = GNUNET_NO;
921 for (int i = 0; i < rd_count; i++) {
922 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
924 if (0 != memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t)))
926 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
927 "Attribute to delete found (%s)\n",
929 has_changed = GNUNET_YES;
932 if (GNUNET_YES == has_changed) {
933 le = GNUNET_new (struct TicketRecordsEntry);
934 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
935 le->data = GNUNET_malloc (le->data_size);
936 le->rd_count = rd_count;
937 le->label = GNUNET_strdup (label);
938 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
939 GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head,
940 adh->tickets_to_update_tail,
943 GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
948 update_tickets (void *cls);
952 ticket_updated (void *cls, int32_t success, const char *emsg)
954 struct AttributeDeleteHandle *adh = cls;
956 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
960 update_tickets (void *cls)
962 struct AttributeDeleteHandle *adh = cls;
963 struct TicketRecordsEntry *le;
964 if (NULL == adh->tickets_to_update_head) {
965 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
966 "Finished updatding tickets, success\n");
967 send_delete_response (adh, GNUNET_OK);
971 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
973 adh->tickets_to_update_head->label);
974 le = adh->tickets_to_update_head;
975 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
976 adh->tickets_to_update_tail,
978 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
979 struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1];
980 GNUNET_GNSRECORD_records_deserialize (le->data_size,
985 for (int i = 0; i < le->rd_count; i++) {
986 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF == rd[i].record_type)
987 && (0 == memcmp (rd[i].data, &adh->claim->id, sizeof (uint64_t))))
992 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
999 GNUNET_free (le->label);
1000 GNUNET_free (le->data);
1006 ticket_iter_fin (void *cls)
1008 struct AttributeDeleteHandle *adh = cls;
1010 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1015 ticket_iter_err (void *cls)
1017 struct AttributeDeleteHandle *adh = cls;
1019 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1020 "Namestore error on delete %s\n",
1022 send_delete_response (adh, GNUNET_SYSERR);
1028 start_ticket_update (void *cls)
1030 struct AttributeDeleteHandle *adh = cls;
1031 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1043 attr_delete_cont (void *cls, int32_t success, const char *emsg)
1045 struct AttributeDeleteHandle *adh = cls;
1047 if (GNUNET_SYSERR == success) {
1048 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1049 "Error deleting attribute %s\n",
1051 send_delete_response (adh, GNUNET_SYSERR);
1055 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating tickets...\n");
1056 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1061 check_attribute_delete_message (void *cls,
1062 const struct AttributeDeleteMessage *dam)
1066 size = ntohs (dam->header.size);
1067 if (size <= sizeof (struct AttributeDeleteMessage)) {
1069 return GNUNET_SYSERR;
1076 handle_attribute_delete_message (void *cls,
1077 const struct AttributeDeleteMessage *dam)
1079 struct AttributeDeleteHandle *adh;
1080 struct IdpClient *idp = cls;
1082 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_DELETE message\n");
1084 data_len = ntohs (dam->attr_len);
1086 adh = GNUNET_new (struct AttributeDeleteHandle);
1087 adh->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *)&dam[1], data_len);
1089 adh->r_id = ntohl (dam->id);
1090 adh->identity = dam->identity;
1092 = GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id, sizeof (uint64_t));
1093 GNUNET_SERVICE_client_continue (idp->client);
1095 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1096 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1106 /*************************************************
1107 * Attrubute iteration
1108 *************************************************/
1111 cleanup_attribute_iter_handle (struct AttributeIterator *ai)
1117 attr_iter_error (void *cls)
1119 struct AttributeIterator *ai = cls;
1120 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
1121 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
1122 ai->client->attr_iter_tail,
1124 cleanup_attribute_iter_handle (ai);
1125 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1129 attr_iter_finished (void *cls)
1131 struct AttributeIterator *ai = cls;
1132 struct GNUNET_MQ_Envelope *env;
1133 struct AttributeResultMessage *arm;
1135 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
1136 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1137 arm->id = htonl (ai->request_id);
1138 arm->attr_len = htons (0);
1139 GNUNET_MQ_send (ai->client->mq, env);
1140 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
1141 ai->client->attr_iter_tail,
1143 cleanup_attribute_iter_handle (ai);
1147 attr_iter_cb (void *cls,
1148 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1150 unsigned int rd_count,
1151 const struct GNUNET_GNSRECORD_Data *rd)
1153 struct AttributeIterator *ai = cls;
1154 struct AttributeResultMessage *arm;
1155 struct GNUNET_MQ_Envelope *env;
1158 if (rd_count != 1) {
1159 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1163 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR != rd->record_type) {
1164 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n", label);
1168 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
1169 env = GNUNET_MQ_msg_extra (arm,
1171 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1172 arm->id = htonl (ai->request_id);
1173 arm->attr_len = htons (rd->data_size);
1174 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
1175 data_tmp = (char *)&arm[1];
1176 GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
1177 GNUNET_MQ_send (ai->client->mq, env);
1181 handle_iteration_start (void *cls,
1182 const struct AttributeIterationStartMessage *ais_msg)
1184 struct IdpClient *idp = cls;
1185 struct AttributeIterator *ai;
1187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1188 "Received ATTRIBUTE_ITERATION_START message\n");
1189 ai = GNUNET_new (struct AttributeIterator);
1190 ai->request_id = ntohl (ais_msg->id);
1192 ai->identity = ais_msg->identity;
1194 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, idp->attr_iter_tail, ai);
1195 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1201 &attr_iter_finished,
1203 GNUNET_SERVICE_client_continue (idp->client);
1207 handle_iteration_stop (void *cls,
1208 const struct AttributeIterationStopMessage *ais_msg)
1210 struct IdpClient *idp = cls;
1211 struct AttributeIterator *ai;
1214 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1215 "Received `%s' message\n",
1216 "ATTRIBUTE_ITERATION_STOP");
1217 rid = ntohl (ais_msg->id);
1218 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1219 if (ai->request_id == rid)
1223 GNUNET_SERVICE_client_drop (idp->client);
1226 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
1228 GNUNET_SERVICE_client_continue (idp->client);
1232 handle_iteration_next (void *cls,
1233 const struct AttributeIterationNextMessage *ais_msg)
1235 struct IdpClient *idp = cls;
1236 struct AttributeIterator *ai;
1239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1240 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1241 rid = ntohl (ais_msg->id);
1242 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1243 if (ai->request_id == rid)
1247 GNUNET_SERVICE_client_drop (idp->client);
1250 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1251 GNUNET_SERVICE_client_continue (idp->client);
1254 /******************************************************
1256 ******************************************************/
1259 ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
1261 struct TicketIteration *ti = cls;
1262 struct GNUNET_MQ_Envelope *env;
1263 struct TicketResultMessage *trm;
1265 if (NULL == ticket) {
1266 /* send empty response to indicate end of list */
1267 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
1268 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
1269 ti->client->ticket_iter_tail,
1272 env = GNUNET_MQ_msg_extra (trm,
1273 sizeof (struct GNUNET_RECLAIM_Ticket),
1274 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
1275 memcpy (&trm[1], ticket, sizeof (struct GNUNET_RECLAIM_Ticket));
1277 trm->id = htonl (ti->r_id);
1278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
1279 GNUNET_MQ_send (ti->client->mq, env);
1285 handle_ticket_iteration_start (
1287 const struct TicketIterationStartMessage *tis_msg)
1289 struct IdpClient *client = cls;
1290 struct TicketIteration *ti;
1292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1293 "Received TICKET_ITERATION_START message\n");
1294 ti = GNUNET_new (struct TicketIteration);
1295 ti->r_id = ntohl (tis_msg->id);
1296 ti->client = client;
1298 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
1299 client->ticket_iter_tail,
1302 = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti);
1303 GNUNET_SERVICE_client_continue (client->client);
1307 handle_ticket_iteration_stop (void *cls,
1308 const struct TicketIterationStopMessage *tis_msg)
1310 struct IdpClient *client = cls;
1311 struct TicketIteration *ti;
1314 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1315 "Received `%s' message\n",
1316 "TICKET_ITERATION_STOP");
1317 rid = ntohl (tis_msg->id);
1318 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
1319 if (ti->r_id == rid)
1323 GNUNET_SERVICE_client_drop (client->client);
1326 RECLAIM_TICKETS_iteration_stop (ti->iter);
1327 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
1328 client->ticket_iter_tail,
1331 GNUNET_SERVICE_client_continue (client->client);
1335 handle_ticket_iteration_next (void *cls,
1336 const struct TicketIterationNextMessage *tis_msg)
1338 struct IdpClient *client = cls;
1339 struct TicketIteration *ti;
1342 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1343 "Received TICKET_ITERATION_NEXT message\n");
1344 rid = ntohl (tis_msg->id);
1345 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
1346 if (ti->r_id == rid)
1350 GNUNET_SERVICE_client_drop (client->client);
1353 RECLAIM_TICKETS_iteration_next (ti->iter);
1354 GNUNET_SERVICE_client_continue (client->client);
1358 * Main function that will be run
1360 * @param cls closure
1361 * @param c the configuration used
1362 * @param server the service handle
1366 const struct GNUNET_CONFIGURATION_Handle *c,
1367 struct GNUNET_SERVICE_Handle *server)
1371 if (GNUNET_OK != RECLAIM_TICKETS_init (cfg)) {
1372 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1373 "Unable to initialized TICKETS subsystem.\n");
1374 GNUNET_SCHEDULER_shutdown ();
1377 // Connect to identity and namestore services
1378 nsh = GNUNET_NAMESTORE_connect (cfg);
1380 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1381 "error connecting to namestore");
1384 identity_handle = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
1387 == GNUNET_CONFIGURATION_get_value_time (cfg,
1389 "TOKEN_EXPIRATION_INTERVAL",
1390 &token_expiration_interval)) {
1392 GNUNET_ERROR_TYPE_DEBUG,
1393 "Time window for zone iteration: %s\n",
1394 GNUNET_STRINGS_relative_time_to_string (token_expiration_interval,
1397 token_expiration_interval = DEFAULT_TOKEN_EXPIRATION_INTERVAL;
1400 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
1404 * Called whenever a client is disconnected.
1406 * @param cls closure
1407 * @param client identification of the client
1408 * @param app_ctx @a client
1411 client_disconnect_cb (void *cls,
1412 struct GNUNET_SERVICE_Client *client,
1415 struct IdpClient *idp = app_ctx;
1416 struct AttributeIterator *ai;
1417 struct TicketIteration *ti;
1418 struct TicketRevocationOperation *rop;
1419 struct TicketIssueOperation *iss;
1420 struct ConsumeTicketOperation *ct;
1421 struct AttributeStoreHandle *as;
1422 struct AttributeDeleteHandle *adh;
1424 // TODO other operations
1426 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1428 while (NULL != (iss = idp->issue_op_head)) {
1429 GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, idp->issue_op_tail, iss);
1432 while (NULL != (ct = idp->consume_op_head)) {
1433 GNUNET_CONTAINER_DLL_remove (idp->consume_op_head,
1434 idp->consume_op_tail,
1437 RECLAIM_TICKETS_consume_cancel (ct->ch);
1440 while (NULL != (as = idp->store_op_head)) {
1441 GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as);
1442 cleanup_as_handle (as);
1444 while (NULL != (adh = idp->delete_op_head)) {
1445 GNUNET_CONTAINER_DLL_remove (idp->delete_op_head, idp->delete_op_tail, adh);
1449 while (NULL != (ai = idp->attr_iter_head)) {
1450 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
1451 cleanup_attribute_iter_handle (ai);
1453 while (NULL != (rop = idp->revoke_op_head)) {
1454 GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, idp->revoke_op_tail, rop);
1455 if (NULL != rop->rh)
1456 RECLAIM_TICKETS_revoke_cancel (rop->rh);
1459 while (NULL != (ti = idp->ticket_iter_head)) {
1460 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
1461 idp->ticket_iter_tail,
1469 * Add a client to our list of active clients.
1472 * @param client client to add
1473 * @param mq message queue for @a client
1474 * @return internal namestore client structure for this client
1477 client_connect_cb (void *cls,
1478 struct GNUNET_SERVICE_Client *client,
1479 struct GNUNET_MQ_Handle *mq)
1481 struct IdpClient *idp;
1482 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1483 idp = GNUNET_new (struct IdpClient);
1484 idp->client = client;
1490 * Define "main" method using service macro.
1492 GNUNET_SERVICE_MAIN (
1494 GNUNET_SERVICE_OPTION_NONE,
1497 &client_disconnect_cb,
1499 GNUNET_MQ_hd_var_size (attribute_store_message,
1500 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
1501 struct AttributeStoreMessage,
1503 GNUNET_MQ_hd_var_size (attribute_delete_message,
1504 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
1505 struct AttributeDeleteMessage,
1507 GNUNET_MQ_hd_fixed_size (
1509 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
1510 struct AttributeIterationStartMessage,
1512 GNUNET_MQ_hd_fixed_size (iteration_next,
1513 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
1514 struct AttributeIterationNextMessage,
1516 GNUNET_MQ_hd_fixed_size (iteration_stop,
1517 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
1518 struct AttributeIterationStopMessage,
1520 GNUNET_MQ_hd_var_size (issue_ticket_message,
1521 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
1522 struct IssueTicketMessage,
1524 GNUNET_MQ_hd_var_size (consume_ticket_message,
1525 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
1526 struct ConsumeTicketMessage,
1528 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
1529 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
1530 struct TicketIterationStartMessage,
1532 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
1533 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
1534 struct TicketIterationNextMessage,
1536 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
1537 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
1538 struct TicketIterationStopMessage,
1540 GNUNET_MQ_hd_var_size (revoke_ticket_message,
1541 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
1542 struct RevokeTicketMessage,
1544 GNUNET_MQ_handler_end ());
1545 /* end of gnunet-service-reclaim.c */