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
27 #include "gnunet_util_lib.h"
28 #include "gnunet-service-reclaim_tickets.h"
29 #include "gnunet_constants.h"
30 #include "gnunet_gnsrecord_lib.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_reclaim_attribute_lib.h"
33 #include "gnunet_reclaim_service.h"
34 #include "gnunet_signatures.h"
41 static struct GNUNET_NAMESTORE_Handle *nsh;
46 static struct GNUNET_SCHEDULER_Task *timeout_task;
51 static const struct GNUNET_CONFIGURATION_Handle *cfg;
59 * A ticket iteration operation.
61 struct TicketIteration
66 struct TicketIteration *next;
71 struct TicketIteration *prev;
74 * Client which intiated this zone iteration
76 struct IdpClient *client;
79 * The operation id fot the iteration in the response for the client
86 struct RECLAIM_TICKETS_Iterator *iter;
91 * An attribute iteration operation.
96 * Next element in the DLL
98 struct Iterator *next;
101 * Previous element in the DLL
103 struct Iterator *prev;
106 * IDP client which intiated this zone iteration
108 struct IdpClient *client;
111 * Key of the zone we are iterating over.
113 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
118 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
121 * The operation id fot the zone iteration in the response for the client
140 struct IdpClient *prev;
145 struct IdpClient *next;
150 struct GNUNET_SERVICE_Client *client;
153 * Message queue for transmission to @e client
155 struct GNUNET_MQ_Handle *mq;
159 * Attribute iteration operations in
160 * progress initiated by this client
162 struct Iterator *attr_iter_head;
166 * Attribute iteration operations
167 * in progress initiated by this client
169 struct Iterator *attr_iter_tail;
173 * Attribute iteration operations in
174 * progress initiated by this client
176 struct Iterator *attest_iter_head;
180 * Attribute iteration operations
181 * in progress initiated by this client
183 struct Iterator *attest_iter_tail;
186 * Head of DLL of ticket iteration ops
188 struct TicketIteration *ticket_iter_head;
191 * Tail of DLL of ticket iteration ops
193 struct TicketIteration *ticket_iter_tail;
196 * Head of DLL of ticket revocation ops
198 struct TicketRevocationOperation *revoke_op_head;
201 * Tail of DLL of ticket revocation ops
203 struct TicketRevocationOperation *revoke_op_tail;
206 * Head of DLL of ticket issue ops
208 struct TicketIssueOperation *issue_op_head;
211 * Tail of DLL of ticket issue ops
213 struct TicketIssueOperation *issue_op_tail;
216 * Head of DLL of ticket consume ops
218 struct ConsumeTicketOperation *consume_op_head;
221 * Tail of DLL of ticket consume ops
223 struct ConsumeTicketOperation *consume_op_tail;
226 * Head of DLL of attribute store ops
228 struct AttributeStoreHandle *store_op_head;
231 * Tail of DLL of attribute store ops
233 struct AttributeStoreHandle *store_op_tail;
235 * Head of DLL of attribute delete ops
237 struct AttributeDeleteHandle *delete_op_head;
240 * Tail of DLL of attribute delete ops
242 struct AttributeDeleteHandle *delete_op_tail;
247 * Handle for attribute deletion request
249 struct AttributeDeleteHandle
254 struct AttributeDeleteHandle *next;
259 struct AttributeDeleteHandle *prev;
264 struct IdpClient *client;
269 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
275 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
280 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
283 * The attribute to delete
285 struct GNUNET_RECLAIM_Attribute *claim;
288 * The attestation to delete
290 struct GNUNET_RECLAIM_Attestation *attest;
295 struct TicketRecordsEntry *tickets_to_update_head;
300 struct TicketRecordsEntry *tickets_to_update_tail;
315 * Handle for attribute store request
317 struct AttributeStoreHandle
322 struct AttributeStoreHandle *next;
327 struct AttributeStoreHandle *prev;
332 struct IdpClient *client;
337 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
342 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
347 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
350 * The attribute to store
352 struct GNUNET_RECLAIM_Attribute *claim;
355 * The attestation to store
357 struct GNUNET_RECLAIM_Attestation *attest;
360 * The attribute expiration interval
362 struct GNUNET_TIME_Relative exp;
372 * Handle for ticket consume request
374 struct ConsumeTicketOperation
379 struct ConsumeTicketOperation *next;
384 struct ConsumeTicketOperation *prev;
389 struct IdpClient *client;
397 * Ticket consume handle
399 struct RECLAIM_TICKETS_ConsumeHandle *ch;
404 * Ticket revocation request handle
406 struct TicketRevocationOperation
411 struct TicketRevocationOperation *prev;
416 struct TicketRevocationOperation *next;
421 struct IdpClient *client;
426 struct RECLAIM_TICKETS_RevokeHandle *rh;
436 * Ticket issue operation handle
438 struct TicketIssueOperation
443 struct TicketIssueOperation *prev;
448 struct TicketIssueOperation *next;
453 struct IdpClient *client;
465 static struct IdpClient *client_list_head = NULL;
470 static struct IdpClient *client_list_tail = NULL;
474 * Cleanup attribute delete handle
476 * @param adh the attribute to cleanup
479 cleanup_adh (struct AttributeDeleteHandle *adh)
481 struct TicketRecordsEntry *le;
483 if (NULL != adh->ns_it)
484 GNUNET_NAMESTORE_zone_iteration_stop (adh->ns_it);
485 if (NULL != adh->ns_qe)
486 GNUNET_NAMESTORE_cancel (adh->ns_qe);
487 if (NULL != adh->label)
488 GNUNET_free (adh->label);
489 if (NULL != adh->claim)
490 GNUNET_free (adh->claim);
491 if (NULL != adh->attest)
492 GNUNET_free (adh->attest);
493 while (NULL != (le = adh->tickets_to_update_head))
495 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
496 adh->tickets_to_update_tail,
498 if (NULL != le->label)
499 GNUNET_free (le->label);
500 if (NULL != le->data)
501 GNUNET_free (le->data);
509 * Cleanup attribute store handle
511 * @param handle handle to clean up
514 cleanup_as_handle (struct AttributeStoreHandle *ash)
516 if (NULL != ash->ns_qe)
517 GNUNET_NAMESTORE_cancel (ash->ns_qe);
518 if (NULL != ash->claim)
519 GNUNET_free (ash->claim);
520 if (NULL != ash->attest)
521 GNUNET_free (ash->attest);
529 * @param idp the client to clean up
532 cleanup_client (struct IdpClient *idp)
535 struct TicketIteration *ti;
536 struct TicketRevocationOperation *rop;
537 struct TicketIssueOperation *iss;
538 struct ConsumeTicketOperation *ct;
539 struct AttributeStoreHandle *as;
540 struct AttributeDeleteHandle *adh;
542 while (NULL != (iss = idp->issue_op_head))
544 GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, idp->issue_op_tail, iss);
547 while (NULL != (ct = idp->consume_op_head))
549 GNUNET_CONTAINER_DLL_remove (idp->consume_op_head,
550 idp->consume_op_tail,
553 RECLAIM_TICKETS_consume_cancel (ct->ch);
556 while (NULL != (as = idp->store_op_head))
558 GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as);
559 cleanup_as_handle (as);
561 while (NULL != (adh = idp->delete_op_head))
563 GNUNET_CONTAINER_DLL_remove (idp->delete_op_head, idp->delete_op_tail, adh);
567 while (NULL != (ai = idp->attr_iter_head))
569 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
572 while (NULL != (ai = idp->attest_iter_head))
574 GNUNET_CONTAINER_DLL_remove (idp->attest_iter_head, idp->attest_iter_tail,
579 while (NULL != (rop = idp->revoke_op_head))
581 GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, idp->revoke_op_tail, rop);
583 RECLAIM_TICKETS_revoke_cancel (rop->rh);
586 while (NULL != (ti = idp->ticket_iter_head))
588 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
589 idp->ticket_iter_tail,
591 if (NULL != ti->iter)
592 RECLAIM_TICKETS_iteration_stop (ti->iter);
605 struct IdpClient *cl;
607 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
609 while (NULL != (cl = client_list_head))
611 GNUNET_CONTAINER_DLL_remove (client_list_head,
616 RECLAIM_TICKETS_deinit ();
617 if (NULL != timeout_task)
618 GNUNET_SCHEDULER_cancel (timeout_task);
620 GNUNET_NAMESTORE_disconnect (nsh);
630 do_shutdown (void *cls)
632 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
638 * Sends a ticket result message to the client
640 * @param client the client to send to
641 * @param r_id the request message ID to reply to
642 * @param ticket the ticket to include (may be NULL)
643 * @param success the success status of the request
646 send_ticket_result (const struct IdpClient *client,
648 const struct GNUNET_RECLAIM_Ticket *ticket,
651 struct TicketResultMessage *irm;
652 struct GNUNET_MQ_Envelope *env;
654 env = GNUNET_MQ_msg (irm,
655 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
658 irm->ticket = *ticket;
660 // TODO add success member
661 irm->id = htonl (r_id);
662 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
663 GNUNET_MQ_send (client->mq, env);
668 * Issue ticket result
670 * @param cls out ticket issue operation handle
671 * @param ticket the issued ticket
672 * @param success issue success status (GNUNET_OK if successful)
673 * @param emsg error message (NULL of success is GNUNET_OK)
676 issue_ticket_result_cb (void *cls,
677 struct GNUNET_RECLAIM_Ticket *ticket,
681 struct TicketIssueOperation *tio = cls;
683 if (GNUNET_OK != success)
685 send_ticket_result (tio->client, tio->r_id, NULL, GNUNET_SYSERR);
686 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
687 tio->client->issue_op_tail,
690 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error issuing ticket: %s\n", emsg);
693 send_ticket_result (tio->client, tio->r_id, ticket, GNUNET_SYSERR);
694 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
695 tio->client->issue_op_tail,
702 * Check issue ticket message
705 * @im message to check
706 * @return GNUNET_OK if message is ok
709 check_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
713 size = ntohs (im->header.size);
714 if (size <= sizeof(struct IssueTicketMessage))
717 return GNUNET_SYSERR;
724 * Handle ticket issue message
726 * @param cls our client
727 * @param im the message
730 handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
732 struct TicketIssueOperation *tio;
733 struct IdpClient *idp = cls;
734 struct GNUNET_RECLAIM_AttributeList *attrs;
737 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ISSUE_TICKET message\n");
738 tio = GNUNET_new (struct TicketIssueOperation);
739 attrs_len = ntohs (im->attr_len);
740 attrs = GNUNET_RECLAIM_attribute_list_deserialize ((char *) &im[1],
742 tio->r_id = ntohl (im->id);
744 GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, idp->issue_op_tail, tio);
745 RECLAIM_TICKETS_issue (&im->identity,
748 &issue_ticket_result_cb,
750 GNUNET_SERVICE_client_continue (idp->client);
751 GNUNET_RECLAIM_attribute_list_destroy (attrs);
755 /**********************************************************
757 **********************************************************/
760 * Handles revocation result
762 * @param cls our revocation operation handle
763 * @param success revocation result (GNUNET_OK if successful)
766 revoke_result_cb (void *cls, int32_t success)
768 struct TicketRevocationOperation *rop = cls;
769 struct GNUNET_MQ_Envelope *env;
770 struct RevokeTicketResultMessage *trm;
772 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
773 "Sending REVOKE_TICKET_RESULT message\n");
775 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT);
776 trm->id = htonl (rop->r_id);
777 trm->success = htonl (success);
778 GNUNET_MQ_send (rop->client->mq, env);
779 GNUNET_CONTAINER_DLL_remove (rop->client->revoke_op_head,
780 rop->client->revoke_op_tail,
787 * Check revocation message format
790 * @param im the message to check
791 * @return GNUNET_OK if message is ok
794 check_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *im)
798 size = ntohs (im->header.size);
799 if (size != sizeof(struct RevokeTicketMessage))
802 return GNUNET_SYSERR;
809 * Handle a revocation message to a ticket.
811 * @param cls our client
812 * @param rm the message to handle
815 handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm)
817 struct TicketRevocationOperation *rop;
818 struct IdpClient *idp = cls;
820 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REVOKE_TICKET message\n");
821 rop = GNUNET_new (struct TicketRevocationOperation);
822 rop->r_id = ntohl (rm->id);
824 GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, idp->revoke_op_tail, rop);
826 = RECLAIM_TICKETS_revoke (&rm->ticket, &rm->identity, &revoke_result_cb,
828 GNUNET_SERVICE_client_continue (idp->client);
833 * Handle a ticket consume result
835 * @param cls our consume ticket operation handle
836 * @param identity the attribute authority
837 * @param attrs the attribute/claim list
838 * @param success GNUNET_OK if successful
839 * @param emsg error message (NULL if success=GNUNET_OK)
842 consume_result_cb (void *cls,
843 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
844 const struct GNUNET_RECLAIM_AttributeList *attrs,
848 struct ConsumeTicketOperation *cop = cls;
849 struct ConsumeTicketResultMessage *crm;
850 struct GNUNET_MQ_Envelope *env;
854 if (GNUNET_OK != success)
856 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error consuming ticket: %s\n", emsg);
858 attrs_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
859 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
860 "Sending CONSUME_TICKET_RESULT message\n");
861 env = GNUNET_MQ_msg_extra (crm,
863 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
864 crm->id = htonl (cop->r_id);
865 crm->attrs_len = htons (attrs_len);
866 crm->identity = *identity;
867 crm->result = htonl (success);
868 data_tmp = (char *) &crm[1];
869 GNUNET_RECLAIM_attribute_list_serialize (attrs, data_tmp);
870 GNUNET_MQ_send (cop->client->mq, env);
871 GNUNET_CONTAINER_DLL_remove (cop->client->consume_op_head,
872 cop->client->consume_op_tail,
879 * Check a consume ticket message
882 * @param cm the message to handle
885 check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
889 size = ntohs (cm->header.size);
890 if (size != sizeof(struct ConsumeTicketMessage))
893 return GNUNET_SYSERR;
900 * Handle a consume ticket message
902 * @param cls our client handle
903 * @cm the message to handle
906 handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
908 struct ConsumeTicketOperation *cop;
909 struct IdpClient *idp = cls;
911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CONSUME_TICKET message\n");
912 cop = GNUNET_new (struct ConsumeTicketOperation);
913 cop->r_id = ntohl (cm->id);
916 = RECLAIM_TICKETS_consume (&cm->identity, &cm->ticket, &consume_result_cb,
918 GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop);
919 GNUNET_SERVICE_client_continue (idp->client);
923 /*****************************************
925 *****************************************/
929 * Attribute store result handler
931 * @param cls our attribute store handle
932 * @param success GNUNET_OK if successful
933 * @param emsg error message (NULL if success=GNUNET_OK)
936 attr_store_cont (void *cls, int32_t success, const char *emsg)
938 struct AttributeStoreHandle *ash = cls;
939 struct GNUNET_MQ_Envelope *env;
940 struct SuccessResultMessage *acr_msg;
943 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
944 ash->client->store_op_tail,
947 if (GNUNET_SYSERR == success)
949 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
950 "Failed to store attribute %s\n",
952 cleanup_as_handle (ash);
953 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
957 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
958 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
959 acr_msg->id = htonl (ash->r_id);
960 acr_msg->op_result = htonl (GNUNET_OK);
961 GNUNET_MQ_send (ash->client->mq, env);
962 cleanup_as_handle (ash);
967 * Add a new attribute
969 * @param cls the AttributeStoreHandle
972 attr_store_task (void *cls)
974 struct AttributeStoreHandle *ash = cls;
975 struct GNUNET_GNSRECORD_Data rd[1];
980 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing attribute\n");
981 buf_size = GNUNET_RECLAIM_attribute_serialize_get_size (ash->claim);
982 buf = GNUNET_malloc (buf_size);
983 // Give the ash a new id if unset
984 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->claim->id))
985 GNUNET_RECLAIM_id_generate (&ash->claim->id);
986 GNUNET_RECLAIM_attribute_serialize (ash->claim, buf);
988 = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id,
989 sizeof (ash->claim->id));
990 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
992 rd[0].data_size = buf_size;
994 rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE;
995 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
996 rd[0].expiration_time = ash->exp.rel_value_us;
997 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1005 GNUNET_free (label);
1010 * Check an attribute store message
1013 * @param sam the message to check
1016 check_attribute_store_message (void *cls,
1017 const struct AttributeStoreMessage *sam)
1021 size = ntohs (sam->header.size);
1022 if (size <= sizeof(struct AttributeStoreMessage))
1025 return GNUNET_SYSERR;
1032 * Handle an attribute store message
1034 * @param cls our client
1035 * @param sam the message to handle
1038 handle_attribute_store_message (void *cls,
1039 const struct AttributeStoreMessage *sam)
1041 struct AttributeStoreHandle *ash;
1042 struct IdpClient *idp = cls;
1045 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_STORE message\n");
1047 data_len = ntohs (sam->attr_len);
1049 ash = GNUNET_new (struct AttributeStoreHandle);
1050 ash->claim = GNUNET_RECLAIM_attribute_deserialize ((char *) &sam[1],
1053 ash->r_id = ntohl (sam->id);
1054 ash->identity = sam->identity;
1055 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1056 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1058 GNUNET_SERVICE_client_continue (idp->client);
1060 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1061 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1066 * Attestation store result handler
1068 * @param cls our attribute store handle
1069 * @param success GNUNET_OK if successful
1070 * @param emsg error message (NULL if success=GNUNET_OK)
1073 attest_store_cont (void *cls, int32_t success, const char *emsg)
1075 struct AttributeStoreHandle *ash = cls;
1076 struct GNUNET_MQ_Envelope *env;
1077 struct SuccessResultMessage *acr_msg;
1080 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1081 ash->client->store_op_tail,
1084 if (GNUNET_SYSERR == success)
1086 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1087 "Failed to store attestation %s\n",
1089 cleanup_as_handle (ash);
1090 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1094 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1095 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1096 acr_msg->id = htonl (ash->r_id);
1097 acr_msg->op_result = htonl (GNUNET_OK);
1098 GNUNET_MQ_send (ash->client->mq, env);
1099 cleanup_as_handle (ash);
1104 * Error looking up potential attestation. Abort.
1106 * @param cls our attribute store handle
1109 attest_error (void *cls)
1111 struct AttributeStoreHandle *ash = cls;
1112 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1113 "Failed to check for existing Attestation\n");
1114 cleanup_as_handle (ash);
1115 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1121 * Check for existing record before storing attestation
1123 * @param cls our attribute store handle
1124 * @param zone zone we are iterating
1125 * @param label label of the records
1126 * @param rd_count record count
1130 attest_add_cb (void *cls,
1131 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1133 unsigned int rd_count,
1134 const struct GNUNET_GNSRECORD_Data *rd)
1136 struct AttributeStoreHandle *ash = cls;
1139 buf_size = GNUNET_RECLAIM_attestation_serialize_get_size (ash->attest);
1140 buf = GNUNET_malloc (buf_size);
1141 GNUNET_RECLAIM_attestation_serialize (ash->attest, buf);
1142 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1143 "Storing new Attestation\n");
1144 struct GNUNET_GNSRECORD_Data rd_new[1];
1145 rd_new[0].data_size = buf_size;
1146 rd_new[0].data = buf;
1147 rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION;
1148 rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1149 rd_new[0].expiration_time = ash->exp.rel_value_us;
1150 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1151 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1164 * Add a new attestation
1166 * @param cls the AttributeStoreHandle
1169 attest_store_task (void *cls)
1171 struct AttributeStoreHandle *ash = cls;
1174 // Give the ash a new id if unset
1175 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->attest->id))
1176 GNUNET_RECLAIM_id_generate (&ash->attest->id);
1177 label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
1178 sizeof (ash->attest->id));
1179 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1180 "Looking up existing data under label %s\n", label);
1181 // Test for the content of the existing ID
1182 ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1189 GNUNET_free (label);
1194 * Check an attestation store message
1197 * @param sam the message to check
1200 check_attestation_store_message (void *cls,
1201 const struct AttributeStoreMessage *sam)
1205 size = ntohs (sam->header.size);
1206 if (size <= sizeof(struct AttributeStoreMessage))
1209 return GNUNET_SYSERR;
1216 * Handle an attestation store message
1218 * @param cls our client
1219 * @param sam the message to handle
1222 handle_attestation_store_message (void *cls,
1223 const struct AttributeStoreMessage *sam)
1225 struct AttributeStoreHandle *ash;
1226 struct IdpClient *idp = cls;
1229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_STORE message\n");
1231 data_len = ntohs (sam->attr_len);
1233 ash = GNUNET_new (struct AttributeStoreHandle);
1234 ash->attest = GNUNET_RECLAIM_attestation_deserialize ((char *) &sam[1],
1237 ash->r_id = ntohl (sam->id);
1238 ash->identity = sam->identity;
1239 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1240 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1242 GNUNET_SERVICE_client_continue (idp->client);
1244 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1245 GNUNET_SCHEDULER_add_now (&attest_store_task, ash);
1250 * Send a deletion success response
1252 * @param adh our attribute deletion handle
1253 * @param success the success status
1256 send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
1258 struct GNUNET_MQ_Envelope *env;
1259 struct SuccessResultMessage *acr_msg;
1261 GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
1262 adh->client->delete_op_tail,
1265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1266 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1267 acr_msg->id = htonl (adh->r_id);
1268 acr_msg->op_result = htonl (success);
1269 GNUNET_MQ_send (adh->client->mq, env);
1274 * Namestore iteration within attribute deletion.
1275 * We need to reissue tickets with the deleted attribute removed.
1277 * @param cls our attribute deletion handle
1278 * @param zone the private key of the ticket issuer
1279 * @param label the label of the record
1280 * @param rd_count number of records
1281 * @param rd record data
1284 ticket_iter (void *cls,
1285 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1287 unsigned int rd_count,
1288 const struct GNUNET_GNSRECORD_Data *rd)
1290 struct AttributeDeleteHandle *adh = cls;
1291 struct TicketRecordsEntry *le;
1292 int has_changed = GNUNET_NO;
1293 for (int i = 0; i < rd_count; i++)
1295 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF != rd[i].record_type)
1297 if (adh->claim != NULL)
1298 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
1301 if (adh->attest != NULL)
1302 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
1305 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1306 "Attribute or Attestation to delete found (%s)\n",
1308 has_changed = GNUNET_YES;
1311 if (GNUNET_YES == has_changed)
1313 le = GNUNET_new (struct TicketRecordsEntry);
1314 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1315 le->data = GNUNET_malloc (le->data_size);
1316 le->rd_count = rd_count;
1317 le->label = GNUNET_strdup (label);
1318 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
1319 GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head,
1320 adh->tickets_to_update_tail,
1323 GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
1328 * Recursion prototype for function
1329 * @param cls our deletion handle
1332 update_tickets (void *cls);
1336 * Callback called when a ticket was updated
1338 * @param cls our attribute deletion handle
1339 * @param success GNUNET_OK if successful
1340 * @param emsg error message (NULL if success=GNUNET_OK)
1343 ticket_updated (void *cls, int32_t success, const char *emsg)
1345 struct AttributeDeleteHandle *adh = cls;
1348 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1353 * Update tickets: Remove shared attribute which has just been deleted.
1354 * This method is called recursively until all tickets are processed.
1355 * Eventually, the updated tickets are stored using ``update_tickets''.
1357 * @param cls our attribute deletion handle
1360 update_tickets (void *cls)
1362 struct AttributeDeleteHandle *adh = cls;
1363 struct TicketRecordsEntry *le;
1365 if (NULL == adh->tickets_to_update_head)
1367 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1368 "Finished updating tickets, success\n");
1369 send_delete_response (adh, GNUNET_OK);
1373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1375 adh->tickets_to_update_head->label);
1376 le = adh->tickets_to_update_head;
1377 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
1378 adh->tickets_to_update_tail,
1380 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
1381 struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1];
1382 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
1387 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1388 "Unable to deserialize record data!\n");
1389 send_delete_response (adh, GNUNET_SYSERR);
1394 for (int i = 0; i < le->rd_count; i++)
1396 if (adh->claim != NULL)
1397 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type)
1398 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1401 if (adh->attest != NULL)
1402 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type)
1403 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1409 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1416 GNUNET_free (le->label);
1417 GNUNET_free (le->data);
1423 * Done collecting affected tickets, start updating.
1425 * @param cls our attribute deletion handle
1428 ticket_iter_fin (void *cls)
1430 struct AttributeDeleteHandle *adh = cls;
1432 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1437 * Error collecting affected tickets. Abort.
1439 * @param cls our attribute deletion handle
1442 ticket_iter_err (void *cls)
1444 struct AttributeDeleteHandle *adh = cls;
1447 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1448 "Namestore error on delete %s\n",
1450 send_delete_response (adh, GNUNET_SYSERR);
1456 * Start processing tickets which may still contain reference to deleted
1459 * @param cls attribute deletion handle
1462 start_ticket_update (void *cls)
1464 struct AttributeDeleteHandle *adh = cls;
1466 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1478 * Attribute deleted callback
1480 * @param cls our handle
1481 * @param success success status
1482 * @param emsg error message (NULL if success=GNUNET_OK)
1485 attr_delete_cont (void *cls, int32_t success, const char *emsg)
1487 struct AttributeDeleteHandle *adh = cls;
1490 if (GNUNET_SYSERR == success)
1492 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1493 "Error deleting attribute %s\n",
1495 send_delete_response (adh, GNUNET_SYSERR);
1499 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1500 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1505 * Check attribute delete message format
1508 * @dam message to check
1511 check_attribute_delete_message (void *cls,
1512 const struct AttributeDeleteMessage *dam)
1516 size = ntohs (dam->header.size);
1517 if (size <= sizeof(struct AttributeDeleteMessage))
1520 return GNUNET_SYSERR;
1527 * Handle attribute deletion
1529 * @param cls our client
1530 * @param dam deletion message
1533 handle_attribute_delete_message (void *cls,
1534 const struct AttributeDeleteMessage *dam)
1536 struct AttributeDeleteHandle *adh;
1537 struct IdpClient *idp = cls;
1540 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_DELETE message\n");
1542 data_len = ntohs (dam->attr_len);
1544 adh = GNUNET_new (struct AttributeDeleteHandle);
1545 adh->claim = GNUNET_RECLAIM_attribute_deserialize ((char *) &dam[1],
1549 adh->r_id = ntohl (dam->id);
1550 adh->identity = dam->identity;
1552 = GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id,
1553 sizeof(adh->claim->id));
1554 GNUNET_SERVICE_client_continue (idp->client);
1556 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1557 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1568 * Attestation deleted callback
1570 * @param cls our handle
1571 * @param success success status
1572 * @param emsg error message (NULL if success=GNUNET_OK)
1575 attest_delete_cont (void *cls, int32_t success, const char *emsg)
1577 struct AttributeDeleteHandle *adh = cls;
1580 if (GNUNET_SYSERR == success)
1582 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1583 "Error deleting attestation %s\n",
1585 send_delete_response (adh, GNUNET_SYSERR);
1589 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1590 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1595 * Check attestation delete message format
1598 * @dam message to check
1601 check_attestation_delete_message (void *cls,
1602 const struct AttributeDeleteMessage *dam)
1606 size = ntohs (dam->header.size);
1607 if (size <= sizeof(struct AttributeDeleteMessage))
1610 return GNUNET_SYSERR;
1617 * Handle attestation deletion
1619 * @param cls our client
1620 * @param dam deletion message
1623 handle_attestation_delete_message (void *cls,
1624 const struct AttributeDeleteMessage *dam)
1626 struct AttributeDeleteHandle *adh;
1627 struct IdpClient *idp = cls;
1630 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_DELETE message\n");
1632 data_len = ntohs (dam->attr_len);
1634 adh = GNUNET_new (struct AttributeDeleteHandle);
1635 adh->attest = GNUNET_RECLAIM_attestation_deserialize ((char *) &dam[1],
1639 adh->r_id = ntohl (dam->id);
1640 adh->identity = dam->identity;
1642 = GNUNET_STRINGS_data_to_string_alloc (&adh->attest->id,
1643 sizeof(adh->attest->id));
1644 GNUNET_SERVICE_client_continue (idp->client);
1646 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1647 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1652 &attest_delete_cont,
1657 /*************************************************
1658 * Attrubute iteration
1659 *************************************************/
1663 * Done iterating over attributes
1665 * @param cls our iterator handle
1668 attr_iter_finished (void *cls)
1670 struct Iterator *ai = cls;
1671 struct GNUNET_MQ_Envelope *env;
1672 struct AttributeResultMessage *arm;
1674 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
1675 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1676 arm->id = htonl (ai->request_id);
1677 arm->attr_len = htons (0);
1678 GNUNET_MQ_send (ai->client->mq, env);
1679 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
1680 ai->client->attr_iter_tail,
1687 * Error iterating over attributes. Abort.
1689 * @param cls our attribute iteration handle
1692 attr_iter_error (void *cls)
1694 struct Iterator *ai = cls;
1696 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
1697 attr_iter_finished (ai);
1702 * Got record. Return if it is an attribute or attestation.
1704 * @param cls our attribute iterator
1705 * @param zone zone we are iterating
1706 * @param label label of the records
1707 * @param rd_count record count
1711 attr_iter_cb (void *cls,
1712 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1714 unsigned int rd_count,
1715 const struct GNUNET_GNSRECORD_Data *rd)
1717 struct Iterator *ai = cls;
1718 struct GNUNET_MQ_Envelope *env;
1721 if ((rd_count != 1) ||
1722 (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE != rd->record_type))
1724 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1727 struct AttributeResultMessage *arm;
1728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n",
1730 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1731 "Sending ATTRIBUTE_RESULT message\n");
1732 env = GNUNET_MQ_msg_extra (arm,
1734 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1735 arm->id = htonl (ai->request_id);
1736 arm->attr_len = htons (rd->data_size);
1737 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
1738 data_tmp = (char *) &arm[1];
1739 GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
1740 GNUNET_MQ_send (ai->client->mq, env);
1745 * Iterate over zone to get attributes
1747 * @param cls our client
1748 * @param ais_msg the iteration message to start
1751 handle_iteration_start (void *cls,
1752 const struct AttributeIterationStartMessage *ais_msg)
1754 struct IdpClient *idp = cls;
1755 struct Iterator *ai;
1757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1758 "Received ATTRIBUTE_ITERATION_START message\n");
1759 ai = GNUNET_new (struct Iterator);
1760 ai->request_id = ntohl (ais_msg->id);
1762 ai->identity = ais_msg->identity;
1764 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, idp->attr_iter_tail, ai);
1765 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1771 &attr_iter_finished,
1773 GNUNET_SERVICE_client_continue (idp->client);
1778 * Handle iteration stop message from client
1780 * @param cls the client
1781 * @param ais_msg the stop message
1784 handle_iteration_stop (void *cls,
1785 const struct AttributeIterationStopMessage *ais_msg)
1787 struct IdpClient *idp = cls;
1788 struct Iterator *ai;
1791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1792 "Received `%s' message\n",
1793 "ATTRIBUTE_ITERATION_STOP");
1794 rid = ntohl (ais_msg->id);
1795 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1796 if (ai->request_id == rid)
1801 GNUNET_SERVICE_client_drop (idp->client);
1804 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
1806 GNUNET_SERVICE_client_continue (idp->client);
1811 * Client requests next attribute from iterator
1813 * @param cls the client
1814 * @param ais_msg the message
1817 handle_iteration_next (void *cls,
1818 const struct AttributeIterationNextMessage *ais_msg)
1820 struct IdpClient *idp = cls;
1821 struct Iterator *ai;
1824 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1825 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1826 rid = ntohl (ais_msg->id);
1827 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1828 if (ai->request_id == rid)
1833 GNUNET_SERVICE_client_drop (idp->client);
1836 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1837 GNUNET_SERVICE_client_continue (idp->client);
1841 /*************************************************
1842 * Attestation iteration
1843 *************************************************/
1847 * Done iterating over attestations
1849 * @param cls our iterator handle
1852 attest_iter_finished (void *cls)
1854 struct Iterator *ai = cls;
1855 struct GNUNET_MQ_Envelope *env;
1856 struct AttestationResultMessage *arm;
1858 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTESTATION_RESULT message\n");
1859 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
1860 arm->id = htonl (ai->request_id);
1861 arm->attestation_len = htons (0);
1862 arm->attributes_len = htons (0);
1863 GNUNET_MQ_send (ai->client->mq, env);
1864 GNUNET_CONTAINER_DLL_remove (ai->client->attest_iter_head,
1865 ai->client->attest_iter_tail,
1872 * Error iterating over attestations. Abort.
1874 * @param cls our attribute iteration handle
1877 attest_iter_error (void *cls)
1879 struct Iterator *ai = cls;
1881 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attestations\n");
1882 attest_iter_finished (ai);
1887 * Got record. Return attestation.
1889 * @param cls our attribute iterator
1890 * @param zone zone we are iterating
1891 * @param label label of the records
1892 * @param rd_count record count
1896 attest_iter_cb (void *cls,
1897 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1899 unsigned int rd_count,
1900 const struct GNUNET_GNSRECORD_Data *rd)
1902 struct Iterator *ai = cls;
1903 struct GNUNET_MQ_Envelope *env;
1904 struct AttestationResultMessage *arm;
1905 struct GNUNET_RECLAIM_AttributeList *attrs;
1906 struct GNUNET_RECLAIM_Attestation *att;
1910 if ((rd_count != 1) ||
1911 (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION != rd->record_type))
1913 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1916 att = GNUNET_RECLAIM_attestation_deserialize (rd->data,
1918 attrs = GNUNET_RECLAIM_attestation_get_attributes (att);
1919 attrs_size = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
1920 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attestation under: %s\n",
1922 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1923 "Sending ATTESTATION_RESULT message\n");
1924 env = GNUNET_MQ_msg_extra (arm,
1925 rd->data_size + attrs_size,
1926 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
1927 arm->id = htonl (ai->request_id);
1928 arm->attestation_len = htons (rd->data_size);
1929 arm->attributes_len = htons (attrs_size);
1930 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
1931 data_tmp = (char *) &arm[1];
1932 GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
1933 data_tmp += rd->data_size;
1934 GNUNET_RECLAIM_attribute_list_serialize (attrs,
1937 GNUNET_MQ_send (ai->client->mq, env);
1942 * Iterate over zone to get attributes
1944 * @param cls our client
1945 * @param ais_msg the iteration message to start
1948 handle_attestation_iteration_start (void *cls,
1950 AttestationIterationStartMessage *ais_msg)
1952 struct IdpClient *idp = cls;
1953 struct Iterator *ai;
1955 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1956 "Received ATTESTATION_ITERATION_START message\n");
1957 ai = GNUNET_new (struct Iterator);
1958 ai->request_id = ntohl (ais_msg->id);
1960 ai->identity = ais_msg->identity;
1962 GNUNET_CONTAINER_DLL_insert (idp->attest_iter_head, idp->attest_iter_tail,
1964 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1970 &attest_iter_finished,
1972 GNUNET_SERVICE_client_continue (idp->client);
1977 * Handle iteration stop message from client
1979 * @param cls the client
1980 * @param ais_msg the stop message
1983 handle_attestation_iteration_stop (void *cls,
1985 AttestationIterationStopMessage *ais_msg)
1987 struct IdpClient *idp = cls;
1988 struct Iterator *ai;
1991 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1992 "Received `%s' message\n",
1993 "ATTESTATION_ITERATION_STOP");
1994 rid = ntohl (ais_msg->id);
1995 for (ai = idp->attest_iter_head; NULL != ai; ai = ai->next)
1996 if (ai->request_id == rid)
2001 GNUNET_SERVICE_client_drop (idp->client);
2004 GNUNET_CONTAINER_DLL_remove (idp->attest_iter_head, idp->attest_iter_tail,
2007 GNUNET_SERVICE_client_continue (idp->client);
2012 * Client requests next attestation from iterator
2014 * @param cls the client
2015 * @param ais_msg the message
2018 handle_attestation_iteration_next (void *cls,
2020 AttestationIterationNextMessage *ais_msg)
2022 struct IdpClient *idp = cls;
2023 struct Iterator *ai;
2026 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2027 "Received ATTESTATION_ITERATION_NEXT message\n");
2028 rid = ntohl (ais_msg->id);
2029 for (ai = idp->attest_iter_head; NULL != ai; ai = ai->next)
2030 if (ai->request_id == rid)
2035 GNUNET_SERVICE_client_drop (idp->client);
2038 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2039 GNUNET_SERVICE_client_continue (idp->client);
2043 /******************************************************
2045 ******************************************************/
2048 * Got a ticket. Return to client
2050 * @param cls our ticket iterator
2051 * @param ticket the ticket
2054 ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
2056 struct TicketIteration *ti = cls;
2057 struct GNUNET_MQ_Envelope *env;
2058 struct TicketResultMessage *trm;
2060 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
2063 /* send empty response to indicate end of list */
2064 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2065 ti->client->ticket_iter_tail,
2070 trm->ticket = *ticket;
2072 trm->id = htonl (ti->r_id);
2073 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
2074 GNUNET_MQ_send (ti->client->mq, env);
2081 * Client requests a ticket iteration
2083 * @param cls the client
2084 * @param tis_msg the iteration request message
2087 handle_ticket_iteration_start (
2089 const struct TicketIterationStartMessage *tis_msg)
2091 struct IdpClient *client = cls;
2092 struct TicketIteration *ti;
2094 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2095 "Received TICKET_ITERATION_START message\n");
2096 ti = GNUNET_new (struct TicketIteration);
2097 ti->r_id = ntohl (tis_msg->id);
2098 ti->client = client;
2100 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2101 client->ticket_iter_tail,
2104 = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti);
2105 GNUNET_SERVICE_client_continue (client->client);
2110 * Client has had enough tickets
2112 * @param cls the client
2113 * @param tis_msg the stop message
2116 handle_ticket_iteration_stop (void *cls,
2117 const struct TicketIterationStopMessage *tis_msg)
2119 struct IdpClient *client = cls;
2120 struct TicketIteration *ti;
2123 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2124 "Received `%s' message\n",
2125 "TICKET_ITERATION_STOP");
2126 rid = ntohl (tis_msg->id);
2127 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2128 if (ti->r_id == rid)
2133 GNUNET_SERVICE_client_drop (client->client);
2136 RECLAIM_TICKETS_iteration_stop (ti->iter);
2137 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2138 client->ticket_iter_tail,
2141 GNUNET_SERVICE_client_continue (client->client);
2146 * Client requests next result.
2148 * @param cls the client
2149 * @param tis_msg the message
2152 handle_ticket_iteration_next (void *cls,
2153 const struct TicketIterationNextMessage *tis_msg)
2155 struct IdpClient *client = cls;
2156 struct TicketIteration *ti;
2159 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2160 "Received TICKET_ITERATION_NEXT message\n");
2161 rid = ntohl (tis_msg->id);
2162 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2163 if (ti->r_id == rid)
2168 GNUNET_SERVICE_client_drop (client->client);
2171 RECLAIM_TICKETS_iteration_next (ti->iter);
2172 GNUNET_SERVICE_client_continue (client->client);
2177 * Main function that will be run
2179 * @param cls closure
2180 * @param c the configuration used
2181 * @param server the service handle
2185 const struct GNUNET_CONFIGURATION_Handle *c,
2186 struct GNUNET_SERVICE_Handle *server)
2190 if (GNUNET_OK != RECLAIM_TICKETS_init (cfg))
2192 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2193 "Unable to initialize TICKETS subsystem.\n");
2194 GNUNET_SCHEDULER_shutdown ();
2197 // Connect to identity and namestore services
2198 nsh = GNUNET_NAMESTORE_connect (cfg);
2201 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2202 "error connecting to namestore");
2205 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2210 * Called whenever a client is disconnected.
2212 * @param cls closure
2213 * @param client identification of the client
2214 * @param app_ctx @a client
2217 client_disconnect_cb (void *cls,
2218 struct GNUNET_SERVICE_Client *client,
2221 struct IdpClient *idp = app_ctx;
2223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
2224 GNUNET_CONTAINER_DLL_remove (client_list_head,
2227 cleanup_client (idp);
2232 * Add a client to our list of active clients.
2235 * @param client client to add
2236 * @param mq message queue for @a client
2237 * @return internal namestore client structure for this client
2240 client_connect_cb (void *cls,
2241 struct GNUNET_SERVICE_Client *client,
2242 struct GNUNET_MQ_Handle *mq)
2244 struct IdpClient *idp;
2246 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
2247 idp = GNUNET_new (struct IdpClient);
2248 idp->client = client;
2250 GNUNET_CONTAINER_DLL_insert (client_list_head,
2258 * Define "main" method using service macro.
2260 GNUNET_SERVICE_MAIN (
2262 GNUNET_SERVICE_OPTION_NONE,
2265 &client_disconnect_cb,
2267 GNUNET_MQ_hd_var_size (attribute_store_message,
2268 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
2269 struct AttributeStoreMessage,
2271 GNUNET_MQ_hd_var_size (attestation_store_message,
2272 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE,
2273 struct AttributeStoreMessage,
2275 GNUNET_MQ_hd_var_size (attribute_delete_message,
2276 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
2277 struct AttributeDeleteMessage,
2279 GNUNET_MQ_hd_var_size (attestation_delete_message,
2280 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE,
2281 struct AttributeDeleteMessage,
2283 GNUNET_MQ_hd_fixed_size (iteration_start,
2284 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
2285 struct AttributeIterationStartMessage,
2287 GNUNET_MQ_hd_fixed_size (iteration_next,
2288 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
2289 struct AttributeIterationNextMessage,
2291 GNUNET_MQ_hd_fixed_size (iteration_stop,
2292 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
2293 struct AttributeIterationStopMessage,
2295 GNUNET_MQ_hd_fixed_size (attestation_iteration_start,
2296 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_START,
2297 struct AttestationIterationStartMessage,
2299 GNUNET_MQ_hd_fixed_size (attestation_iteration_next,
2300 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_NEXT,
2301 struct AttestationIterationNextMessage,
2303 GNUNET_MQ_hd_fixed_size (attestation_iteration_stop,
2304 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_STOP,
2305 struct AttestationIterationStopMessage,
2308 GNUNET_MQ_hd_var_size (issue_ticket_message,
2309 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
2310 struct IssueTicketMessage,
2312 GNUNET_MQ_hd_var_size (consume_ticket_message,
2313 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
2314 struct ConsumeTicketMessage,
2316 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2317 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
2318 struct TicketIterationStartMessage,
2320 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2321 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
2322 struct TicketIterationNextMessage,
2324 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2325 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
2326 struct TicketIterationStopMessage,
2328 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2329 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
2330 struct RevokeTicketMessage,
2332 GNUNET_MQ_handler_end ());
2333 /* end of gnunet-service-reclaim.c */