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_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,
845 const struct GNUNET_RECLAIM_AttestationList *attests,
849 struct ConsumeTicketOperation *cop = cls;
850 struct ConsumeTicketResultMessage *crm;
851 struct GNUNET_MQ_Envelope *env;
856 if (GNUNET_OK != success)
858 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error consuming ticket: %s\n", emsg);
860 attrs_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
861 attests_len = GNUNET_RECLAIM_attestation_list_serialize_get_size (attests);
862 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
863 "Sending CONSUME_TICKET_RESULT message\n");
864 env = GNUNET_MQ_msg_extra (crm,
865 attrs_len + attests_len,
866 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
867 crm->id = htonl (cop->r_id);
868 crm->attrs_len = htons (attrs_len);
869 crm->attestations_len = htons (attests_len);
870 crm->identity = *identity;
871 crm->result = htonl (success);
872 data_tmp = (char *) &crm[1];
873 GNUNET_RECLAIM_attribute_list_serialize (attrs, data_tmp);
874 data_tmp += attrs_len;
875 GNUNET_RECLAIM_attestation_list_serialize (attests, data_tmp);
876 GNUNET_MQ_send (cop->client->mq, env);
877 GNUNET_CONTAINER_DLL_remove (cop->client->consume_op_head,
878 cop->client->consume_op_tail,
885 * Check a consume ticket message
888 * @param cm the message to handle
891 check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
895 size = ntohs (cm->header.size);
896 if (size != sizeof(struct ConsumeTicketMessage))
899 return GNUNET_SYSERR;
906 * Handle a consume ticket message
908 * @param cls our client handle
909 * @cm the message to handle
912 handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
914 struct ConsumeTicketOperation *cop;
915 struct IdpClient *idp = cls;
917 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CONSUME_TICKET message\n");
918 cop = GNUNET_new (struct ConsumeTicketOperation);
919 cop->r_id = ntohl (cm->id);
922 = RECLAIM_TICKETS_consume (&cm->identity, &cm->ticket, &consume_result_cb,
924 GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop);
925 GNUNET_SERVICE_client_continue (idp->client);
929 /*****************************************
931 *****************************************/
935 * Attribute store result handler
937 * @param cls our attribute store handle
938 * @param success GNUNET_OK if successful
939 * @param emsg error message (NULL if success=GNUNET_OK)
942 attr_store_cont (void *cls, int32_t success, const char *emsg)
944 struct AttributeStoreHandle *ash = cls;
945 struct GNUNET_MQ_Envelope *env;
946 struct SuccessResultMessage *acr_msg;
949 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
950 ash->client->store_op_tail,
953 if (GNUNET_SYSERR == success)
955 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
956 "Failed to store attribute %s\n",
958 cleanup_as_handle (ash);
959 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
963 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
964 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
965 acr_msg->id = htonl (ash->r_id);
966 acr_msg->op_result = htonl (GNUNET_OK);
967 GNUNET_MQ_send (ash->client->mq, env);
968 cleanup_as_handle (ash);
973 * Add a new attribute
975 * @param cls the AttributeStoreHandle
978 attr_store_task (void *cls)
980 struct AttributeStoreHandle *ash = cls;
981 struct GNUNET_GNSRECORD_Data rd[1];
986 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing attribute\n");
987 buf_size = GNUNET_RECLAIM_attribute_serialize_get_size (ash->claim);
988 buf = GNUNET_malloc (buf_size);
989 // Give the ash a new id if unset
990 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->claim->id))
991 GNUNET_RECLAIM_id_generate (&ash->claim->id);
992 GNUNET_RECLAIM_attribute_serialize (ash->claim, buf);
994 = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id,
995 sizeof (ash->claim->id));
996 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
998 rd[0].data_size = buf_size;
1000 rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE;
1001 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1002 rd[0].expiration_time = ash->exp.rel_value_us;
1003 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1011 GNUNET_free (label);
1016 * Check an attribute store message
1019 * @param sam the message to check
1022 check_attribute_store_message (void *cls,
1023 const struct AttributeStoreMessage *sam)
1027 size = ntohs (sam->header.size);
1028 if (size <= sizeof(struct AttributeStoreMessage))
1031 return GNUNET_SYSERR;
1038 * Handle an attribute store message
1040 * @param cls our client
1041 * @param sam the message to handle
1044 handle_attribute_store_message (void *cls,
1045 const struct AttributeStoreMessage *sam)
1047 struct AttributeStoreHandle *ash;
1048 struct IdpClient *idp = cls;
1051 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_STORE message\n");
1053 data_len = ntohs (sam->attr_len);
1055 ash = GNUNET_new (struct AttributeStoreHandle);
1056 ash->claim = GNUNET_RECLAIM_attribute_deserialize ((char *) &sam[1],
1059 ash->r_id = ntohl (sam->id);
1060 ash->identity = sam->identity;
1061 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1062 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1064 GNUNET_SERVICE_client_continue (idp->client);
1066 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1067 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1072 * Attestation store result handler
1074 * @param cls our attribute store handle
1075 * @param success GNUNET_OK if successful
1076 * @param emsg error message (NULL if success=GNUNET_OK)
1079 attest_store_cont (void *cls, int32_t success, const char *emsg)
1081 struct AttributeStoreHandle *ash = cls;
1082 struct GNUNET_MQ_Envelope *env;
1083 struct SuccessResultMessage *acr_msg;
1086 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1087 ash->client->store_op_tail,
1090 if (GNUNET_SYSERR == success)
1092 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1093 "Failed to store attestation %s\n",
1095 cleanup_as_handle (ash);
1096 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1100 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1101 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1102 acr_msg->id = htonl (ash->r_id);
1103 acr_msg->op_result = htonl (GNUNET_OK);
1104 GNUNET_MQ_send (ash->client->mq, env);
1105 cleanup_as_handle (ash);
1110 * Error looking up potential attestation. Abort.
1112 * @param cls our attribute store handle
1115 attest_error (void *cls)
1117 struct AttributeStoreHandle *ash = cls;
1118 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1119 "Failed to check for existing Attestation\n");
1120 cleanup_as_handle (ash);
1121 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1127 * Check for existing record before storing attestation
1129 * @param cls our attribute store handle
1130 * @param zone zone we are iterating
1131 * @param label label of the records
1132 * @param rd_count record count
1136 attest_add_cb (void *cls,
1137 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1139 unsigned int rd_count,
1140 const struct GNUNET_GNSRECORD_Data *rd)
1142 struct AttributeStoreHandle *ash = cls;
1145 buf_size = GNUNET_RECLAIM_attestation_serialize_get_size (ash->attest);
1146 buf = GNUNET_malloc (buf_size);
1147 GNUNET_RECLAIM_attestation_serialize (ash->attest, buf);
1148 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1149 "Storing new Attestation\n");
1150 struct GNUNET_GNSRECORD_Data rd_new[1];
1151 rd_new[0].data_size = buf_size;
1152 rd_new[0].data = buf;
1153 rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION;
1154 rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1155 rd_new[0].expiration_time = ash->exp.rel_value_us;
1156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1157 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1170 * Add a new attestation
1172 * @param cls the AttributeStoreHandle
1175 attest_store_task (void *cls)
1177 struct AttributeStoreHandle *ash = cls;
1180 // Give the ash a new id if unset
1181 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->attest->id))
1182 GNUNET_RECLAIM_id_generate (&ash->attest->id);
1183 label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
1184 sizeof (ash->attest->id));
1185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1186 "Looking up existing data under label %s\n", label);
1187 // Test for the content of the existing ID
1188 ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1195 GNUNET_free (label);
1200 * Check an attestation store message
1203 * @param sam the message to check
1206 check_attestation_store_message (void *cls,
1207 const struct AttributeStoreMessage *sam)
1211 size = ntohs (sam->header.size);
1212 if (size <= sizeof(struct AttributeStoreMessage))
1215 return GNUNET_SYSERR;
1222 * Handle an attestation store message
1224 * @param cls our client
1225 * @param sam the message to handle
1228 handle_attestation_store_message (void *cls,
1229 const struct AttributeStoreMessage *sam)
1231 struct AttributeStoreHandle *ash;
1232 struct IdpClient *idp = cls;
1235 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_STORE message\n");
1237 data_len = ntohs (sam->attr_len);
1239 ash = GNUNET_new (struct AttributeStoreHandle);
1240 ash->attest = GNUNET_RECLAIM_attestation_deserialize ((char *) &sam[1],
1243 ash->r_id = ntohl (sam->id);
1244 ash->identity = sam->identity;
1245 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1246 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1248 GNUNET_SERVICE_client_continue (idp->client);
1250 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1251 GNUNET_SCHEDULER_add_now (&attest_store_task, ash);
1256 * Send a deletion success response
1258 * @param adh our attribute deletion handle
1259 * @param success the success status
1262 send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
1264 struct GNUNET_MQ_Envelope *env;
1265 struct SuccessResultMessage *acr_msg;
1267 GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
1268 adh->client->delete_op_tail,
1271 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1272 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1273 acr_msg->id = htonl (adh->r_id);
1274 acr_msg->op_result = htonl (success);
1275 GNUNET_MQ_send (adh->client->mq, env);
1280 * Namestore iteration within attribute deletion.
1281 * We need to reissue tickets with the deleted attribute removed.
1283 * @param cls our attribute deletion handle
1284 * @param zone the private key of the ticket issuer
1285 * @param label the label of the record
1286 * @param rd_count number of records
1287 * @param rd record data
1290 ticket_iter (void *cls,
1291 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1293 unsigned int rd_count,
1294 const struct GNUNET_GNSRECORD_Data *rd)
1296 struct AttributeDeleteHandle *adh = cls;
1297 struct TicketRecordsEntry *le;
1298 int has_changed = GNUNET_NO;
1299 for (int i = 0; i < rd_count; i++)
1301 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF != rd[i].record_type)
1303 if (adh->claim != NULL)
1304 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
1307 if (adh->attest != NULL)
1308 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
1311 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1312 "Attribute or Attestation to delete found (%s)\n",
1314 has_changed = GNUNET_YES;
1317 if (GNUNET_YES == has_changed)
1319 le = GNUNET_new (struct TicketRecordsEntry);
1320 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1321 le->data = GNUNET_malloc (le->data_size);
1322 le->rd_count = rd_count;
1323 le->label = GNUNET_strdup (label);
1324 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
1325 GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head,
1326 adh->tickets_to_update_tail,
1329 GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
1334 * Recursion prototype for function
1335 * @param cls our deletion handle
1338 update_tickets (void *cls);
1342 * Callback called when a ticket was updated
1344 * @param cls our attribute deletion handle
1345 * @param success GNUNET_OK if successful
1346 * @param emsg error message (NULL if success=GNUNET_OK)
1349 ticket_updated (void *cls, int32_t success, const char *emsg)
1351 struct AttributeDeleteHandle *adh = cls;
1354 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1359 * Update tickets: Remove shared attribute which has just been deleted.
1360 * This method is called recursively until all tickets are processed.
1361 * Eventually, the updated tickets are stored using ``update_tickets''.
1363 * @param cls our attribute deletion handle
1366 update_tickets (void *cls)
1368 struct AttributeDeleteHandle *adh = cls;
1369 struct TicketRecordsEntry *le;
1371 if (NULL == adh->tickets_to_update_head)
1373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1374 "Finished updating tickets, success\n");
1375 send_delete_response (adh, GNUNET_OK);
1379 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1381 adh->tickets_to_update_head->label);
1382 le = adh->tickets_to_update_head;
1383 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
1384 adh->tickets_to_update_tail,
1386 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
1387 struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1];
1388 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
1393 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1394 "Unable to deserialize record data!\n");
1395 send_delete_response (adh, GNUNET_SYSERR);
1400 for (int i = 0; i < le->rd_count; i++)
1402 if (adh->claim != NULL)
1403 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type)
1404 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1407 if (adh->attest != NULL)
1408 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type)
1409 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1415 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1422 GNUNET_free (le->label);
1423 GNUNET_free (le->data);
1429 * Done collecting affected tickets, start updating.
1431 * @param cls our attribute deletion handle
1434 ticket_iter_fin (void *cls)
1436 struct AttributeDeleteHandle *adh = cls;
1438 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1443 * Error collecting affected tickets. Abort.
1445 * @param cls our attribute deletion handle
1448 ticket_iter_err (void *cls)
1450 struct AttributeDeleteHandle *adh = cls;
1453 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1454 "Namestore error on delete %s\n",
1456 send_delete_response (adh, GNUNET_SYSERR);
1462 * Start processing tickets which may still contain reference to deleted
1465 * @param cls attribute deletion handle
1468 start_ticket_update (void *cls)
1470 struct AttributeDeleteHandle *adh = cls;
1472 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1484 * Attribute deleted callback
1486 * @param cls our handle
1487 * @param success success status
1488 * @param emsg error message (NULL if success=GNUNET_OK)
1491 attr_delete_cont (void *cls, int32_t success, const char *emsg)
1493 struct AttributeDeleteHandle *adh = cls;
1496 if (GNUNET_SYSERR == success)
1498 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1499 "Error deleting attribute %s\n",
1501 send_delete_response (adh, GNUNET_SYSERR);
1505 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1506 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1511 * Check attribute delete message format
1514 * @dam message to check
1517 check_attribute_delete_message (void *cls,
1518 const struct AttributeDeleteMessage *dam)
1522 size = ntohs (dam->header.size);
1523 if (size <= sizeof(struct AttributeDeleteMessage))
1526 return GNUNET_SYSERR;
1533 * Handle attribute deletion
1535 * @param cls our client
1536 * @param dam deletion message
1539 handle_attribute_delete_message (void *cls,
1540 const struct AttributeDeleteMessage *dam)
1542 struct AttributeDeleteHandle *adh;
1543 struct IdpClient *idp = cls;
1546 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_DELETE message\n");
1548 data_len = ntohs (dam->attr_len);
1550 adh = GNUNET_new (struct AttributeDeleteHandle);
1551 adh->claim = GNUNET_RECLAIM_attribute_deserialize ((char *) &dam[1],
1555 adh->r_id = ntohl (dam->id);
1556 adh->identity = dam->identity;
1558 = GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id,
1559 sizeof(adh->claim->id));
1560 GNUNET_SERVICE_client_continue (idp->client);
1562 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1563 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1574 * Attestation deleted callback
1576 * @param cls our handle
1577 * @param success success status
1578 * @param emsg error message (NULL if success=GNUNET_OK)
1581 attest_delete_cont (void *cls, int32_t success, const char *emsg)
1583 struct AttributeDeleteHandle *adh = cls;
1586 if (GNUNET_SYSERR == success)
1588 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1589 "Error deleting attestation %s\n",
1591 send_delete_response (adh, GNUNET_SYSERR);
1595 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1596 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1601 * Check attestation delete message format
1604 * @dam message to check
1607 check_attestation_delete_message (void *cls,
1608 const struct AttributeDeleteMessage *dam)
1612 size = ntohs (dam->header.size);
1613 if (size <= sizeof(struct AttributeDeleteMessage))
1616 return GNUNET_SYSERR;
1623 * Handle attestation deletion
1625 * @param cls our client
1626 * @param dam deletion message
1629 handle_attestation_delete_message (void *cls,
1630 const struct AttributeDeleteMessage *dam)
1632 struct AttributeDeleteHandle *adh;
1633 struct IdpClient *idp = cls;
1636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_DELETE message\n");
1638 data_len = ntohs (dam->attr_len);
1640 adh = GNUNET_new (struct AttributeDeleteHandle);
1641 adh->attest = GNUNET_RECLAIM_attestation_deserialize ((char *) &dam[1],
1645 adh->r_id = ntohl (dam->id);
1646 adh->identity = dam->identity;
1648 = GNUNET_STRINGS_data_to_string_alloc (&adh->attest->id,
1649 sizeof(adh->attest->id));
1650 GNUNET_SERVICE_client_continue (idp->client);
1652 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1653 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1658 &attest_delete_cont,
1663 /*************************************************
1664 * Attrubute iteration
1665 *************************************************/
1669 * Done iterating over attributes
1671 * @param cls our iterator handle
1674 attr_iter_finished (void *cls)
1676 struct Iterator *ai = cls;
1677 struct GNUNET_MQ_Envelope *env;
1678 struct AttributeResultMessage *arm;
1680 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
1681 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1682 arm->id = htonl (ai->request_id);
1683 arm->attr_len = htons (0);
1684 GNUNET_MQ_send (ai->client->mq, env);
1685 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
1686 ai->client->attr_iter_tail,
1693 * Error iterating over attributes. Abort.
1695 * @param cls our attribute iteration handle
1698 attr_iter_error (void *cls)
1700 struct Iterator *ai = cls;
1702 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
1703 attr_iter_finished (ai);
1708 * Got record. Return if it is an attribute or attestation.
1710 * @param cls our attribute iterator
1711 * @param zone zone we are iterating
1712 * @param label label of the records
1713 * @param rd_count record count
1717 attr_iter_cb (void *cls,
1718 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1720 unsigned int rd_count,
1721 const struct GNUNET_GNSRECORD_Data *rd)
1723 struct Iterator *ai = cls;
1724 struct GNUNET_MQ_Envelope *env;
1727 if ((rd_count != 1) ||
1728 (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE != rd->record_type))
1730 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1733 struct AttributeResultMessage *arm;
1734 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n",
1736 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1737 "Sending ATTRIBUTE_RESULT message\n");
1738 env = GNUNET_MQ_msg_extra (arm,
1740 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1741 arm->id = htonl (ai->request_id);
1742 arm->attr_len = htons (rd->data_size);
1743 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
1744 data_tmp = (char *) &arm[1];
1745 GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
1746 GNUNET_MQ_send (ai->client->mq, env);
1751 * Iterate over zone to get attributes
1753 * @param cls our client
1754 * @param ais_msg the iteration message to start
1757 handle_iteration_start (void *cls,
1758 const struct AttributeIterationStartMessage *ais_msg)
1760 struct IdpClient *idp = cls;
1761 struct Iterator *ai;
1763 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1764 "Received ATTRIBUTE_ITERATION_START message\n");
1765 ai = GNUNET_new (struct Iterator);
1766 ai->request_id = ntohl (ais_msg->id);
1768 ai->identity = ais_msg->identity;
1770 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, idp->attr_iter_tail, ai);
1771 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1777 &attr_iter_finished,
1779 GNUNET_SERVICE_client_continue (idp->client);
1784 * Handle iteration stop message from client
1786 * @param cls the client
1787 * @param ais_msg the stop message
1790 handle_iteration_stop (void *cls,
1791 const struct AttributeIterationStopMessage *ais_msg)
1793 struct IdpClient *idp = cls;
1794 struct Iterator *ai;
1797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1798 "Received `%s' message\n",
1799 "ATTRIBUTE_ITERATION_STOP");
1800 rid = ntohl (ais_msg->id);
1801 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1802 if (ai->request_id == rid)
1807 GNUNET_SERVICE_client_drop (idp->client);
1810 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
1812 GNUNET_SERVICE_client_continue (idp->client);
1817 * Client requests next attribute from iterator
1819 * @param cls the client
1820 * @param ais_msg the message
1823 handle_iteration_next (void *cls,
1824 const struct AttributeIterationNextMessage *ais_msg)
1826 struct IdpClient *idp = cls;
1827 struct Iterator *ai;
1830 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1831 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1832 rid = ntohl (ais_msg->id);
1833 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1834 if (ai->request_id == rid)
1839 GNUNET_SERVICE_client_drop (idp->client);
1842 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1843 GNUNET_SERVICE_client_continue (idp->client);
1847 /*************************************************
1848 * Attestation iteration
1849 *************************************************/
1853 * Done iterating over attestations
1855 * @param cls our iterator handle
1858 attest_iter_finished (void *cls)
1860 struct Iterator *ai = cls;
1861 struct GNUNET_MQ_Envelope *env;
1862 struct AttestationResultMessage *arm;
1864 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTESTATION_RESULT message\n");
1865 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
1866 arm->id = htonl (ai->request_id);
1867 arm->attestation_len = htons (0);
1868 GNUNET_MQ_send (ai->client->mq, env);
1869 GNUNET_CONTAINER_DLL_remove (ai->client->attest_iter_head,
1870 ai->client->attest_iter_tail,
1877 * Error iterating over attestations. Abort.
1879 * @param cls our attribute iteration handle
1882 attest_iter_error (void *cls)
1884 struct Iterator *ai = cls;
1886 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attestations\n");
1887 attest_iter_finished (ai);
1892 * Got record. Return attestation.
1894 * @param cls our attribute iterator
1895 * @param zone zone we are iterating
1896 * @param label label of the records
1897 * @param rd_count record count
1901 attest_iter_cb (void *cls,
1902 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1904 unsigned int rd_count,
1905 const struct GNUNET_GNSRECORD_Data *rd)
1907 struct Iterator *ai = cls;
1908 struct GNUNET_MQ_Envelope *env;
1909 struct AttestationResultMessage *arm;
1912 if ((rd_count != 1) ||
1913 (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION != rd->record_type))
1915 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1918 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attestation under: %s\n",
1920 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1921 "Sending ATTESTATION_RESULT message\n");
1922 env = GNUNET_MQ_msg_extra (arm,
1924 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
1925 arm->id = htonl (ai->request_id);
1926 arm->attestation_len = htons (rd->data_size);
1927 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
1928 data_tmp = (char *) &arm[1];
1929 GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
1931 GNUNET_MQ_send (ai->client->mq, env);
1936 * Iterate over zone to get attributes
1938 * @param cls our client
1939 * @param ais_msg the iteration message to start
1942 handle_attestation_iteration_start (void *cls,
1944 AttestationIterationStartMessage *ais_msg)
1946 struct IdpClient *idp = cls;
1947 struct Iterator *ai;
1949 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1950 "Received ATTESTATION_ITERATION_START message\n");
1951 ai = GNUNET_new (struct Iterator);
1952 ai->request_id = ntohl (ais_msg->id);
1954 ai->identity = ais_msg->identity;
1956 GNUNET_CONTAINER_DLL_insert (idp->attest_iter_head, idp->attest_iter_tail,
1958 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1964 &attest_iter_finished,
1966 GNUNET_SERVICE_client_continue (idp->client);
1971 * Handle iteration stop message from client
1973 * @param cls the client
1974 * @param ais_msg the stop message
1977 handle_attestation_iteration_stop (void *cls,
1979 AttestationIterationStopMessage *ais_msg)
1981 struct IdpClient *idp = cls;
1982 struct Iterator *ai;
1985 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1986 "Received `%s' message\n",
1987 "ATTESTATION_ITERATION_STOP");
1988 rid = ntohl (ais_msg->id);
1989 for (ai = idp->attest_iter_head; NULL != ai; ai = ai->next)
1990 if (ai->request_id == rid)
1995 GNUNET_SERVICE_client_drop (idp->client);
1998 GNUNET_CONTAINER_DLL_remove (idp->attest_iter_head, idp->attest_iter_tail,
2001 GNUNET_SERVICE_client_continue (idp->client);
2006 * Client requests next attestation from iterator
2008 * @param cls the client
2009 * @param ais_msg the message
2012 handle_attestation_iteration_next (void *cls,
2014 AttestationIterationNextMessage *ais_msg)
2016 struct IdpClient *idp = cls;
2017 struct Iterator *ai;
2020 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2021 "Received ATTESTATION_ITERATION_NEXT message\n");
2022 rid = ntohl (ais_msg->id);
2023 for (ai = idp->attest_iter_head; NULL != ai; ai = ai->next)
2024 if (ai->request_id == rid)
2029 GNUNET_SERVICE_client_drop (idp->client);
2032 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2033 GNUNET_SERVICE_client_continue (idp->client);
2037 /******************************************************
2039 ******************************************************/
2042 * Got a ticket. Return to client
2044 * @param cls our ticket iterator
2045 * @param ticket the ticket
2048 ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
2050 struct TicketIteration *ti = cls;
2051 struct GNUNET_MQ_Envelope *env;
2052 struct TicketResultMessage *trm;
2054 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
2057 /* send empty response to indicate end of list */
2058 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2059 ti->client->ticket_iter_tail,
2064 trm->ticket = *ticket;
2066 trm->id = htonl (ti->r_id);
2067 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
2068 GNUNET_MQ_send (ti->client->mq, env);
2075 * Client requests a ticket iteration
2077 * @param cls the client
2078 * @param tis_msg the iteration request message
2081 handle_ticket_iteration_start (
2083 const struct TicketIterationStartMessage *tis_msg)
2085 struct IdpClient *client = cls;
2086 struct TicketIteration *ti;
2088 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2089 "Received TICKET_ITERATION_START message\n");
2090 ti = GNUNET_new (struct TicketIteration);
2091 ti->r_id = ntohl (tis_msg->id);
2092 ti->client = client;
2094 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2095 client->ticket_iter_tail,
2098 = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti);
2099 GNUNET_SERVICE_client_continue (client->client);
2104 * Client has had enough tickets
2106 * @param cls the client
2107 * @param tis_msg the stop message
2110 handle_ticket_iteration_stop (void *cls,
2111 const struct TicketIterationStopMessage *tis_msg)
2113 struct IdpClient *client = cls;
2114 struct TicketIteration *ti;
2117 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2118 "Received `%s' message\n",
2119 "TICKET_ITERATION_STOP");
2120 rid = ntohl (tis_msg->id);
2121 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2122 if (ti->r_id == rid)
2127 GNUNET_SERVICE_client_drop (client->client);
2130 RECLAIM_TICKETS_iteration_stop (ti->iter);
2131 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2132 client->ticket_iter_tail,
2135 GNUNET_SERVICE_client_continue (client->client);
2140 * Client requests next result.
2142 * @param cls the client
2143 * @param tis_msg the message
2146 handle_ticket_iteration_next (void *cls,
2147 const struct TicketIterationNextMessage *tis_msg)
2149 struct IdpClient *client = cls;
2150 struct TicketIteration *ti;
2153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2154 "Received TICKET_ITERATION_NEXT message\n");
2155 rid = ntohl (tis_msg->id);
2156 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2157 if (ti->r_id == rid)
2162 GNUNET_SERVICE_client_drop (client->client);
2165 RECLAIM_TICKETS_iteration_next (ti->iter);
2166 GNUNET_SERVICE_client_continue (client->client);
2171 * Main function that will be run
2173 * @param cls closure
2174 * @param c the configuration used
2175 * @param server the service handle
2179 const struct GNUNET_CONFIGURATION_Handle *c,
2180 struct GNUNET_SERVICE_Handle *server)
2184 if (GNUNET_OK != RECLAIM_TICKETS_init (cfg))
2186 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2187 "Unable to initialize TICKETS subsystem.\n");
2188 GNUNET_SCHEDULER_shutdown ();
2191 // Connect to identity and namestore services
2192 nsh = GNUNET_NAMESTORE_connect (cfg);
2195 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2196 "error connecting to namestore");
2199 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2204 * Called whenever a client is disconnected.
2206 * @param cls closure
2207 * @param client identification of the client
2208 * @param app_ctx @a client
2211 client_disconnect_cb (void *cls,
2212 struct GNUNET_SERVICE_Client *client,
2215 struct IdpClient *idp = app_ctx;
2217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
2218 GNUNET_CONTAINER_DLL_remove (client_list_head,
2221 cleanup_client (idp);
2226 * Add a client to our list of active clients.
2229 * @param client client to add
2230 * @param mq message queue for @a client
2231 * @return internal namestore client structure for this client
2234 client_connect_cb (void *cls,
2235 struct GNUNET_SERVICE_Client *client,
2236 struct GNUNET_MQ_Handle *mq)
2238 struct IdpClient *idp;
2240 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
2241 idp = GNUNET_new (struct IdpClient);
2242 idp->client = client;
2244 GNUNET_CONTAINER_DLL_insert (client_list_head,
2252 * Define "main" method using service macro.
2254 GNUNET_SERVICE_MAIN (
2256 GNUNET_SERVICE_OPTION_NONE,
2259 &client_disconnect_cb,
2261 GNUNET_MQ_hd_var_size (attribute_store_message,
2262 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
2263 struct AttributeStoreMessage,
2265 GNUNET_MQ_hd_var_size (attestation_store_message,
2266 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE,
2267 struct AttributeStoreMessage,
2269 GNUNET_MQ_hd_var_size (attribute_delete_message,
2270 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
2271 struct AttributeDeleteMessage,
2273 GNUNET_MQ_hd_var_size (attestation_delete_message,
2274 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE,
2275 struct AttributeDeleteMessage,
2277 GNUNET_MQ_hd_fixed_size (iteration_start,
2278 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
2279 struct AttributeIterationStartMessage,
2281 GNUNET_MQ_hd_fixed_size (iteration_next,
2282 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
2283 struct AttributeIterationNextMessage,
2285 GNUNET_MQ_hd_fixed_size (iteration_stop,
2286 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
2287 struct AttributeIterationStopMessage,
2289 GNUNET_MQ_hd_fixed_size (attestation_iteration_start,
2290 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_START,
2291 struct AttestationIterationStartMessage,
2293 GNUNET_MQ_hd_fixed_size (attestation_iteration_next,
2294 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_NEXT,
2295 struct AttestationIterationNextMessage,
2297 GNUNET_MQ_hd_fixed_size (attestation_iteration_stop,
2298 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_ITERATION_STOP,
2299 struct AttestationIterationStopMessage,
2302 GNUNET_MQ_hd_var_size (issue_ticket_message,
2303 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
2304 struct IssueTicketMessage,
2306 GNUNET_MQ_hd_var_size (consume_ticket_message,
2307 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
2308 struct ConsumeTicketMessage,
2310 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2311 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
2312 struct TicketIterationStartMessage,
2314 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2315 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
2316 struct TicketIterationNextMessage,
2318 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2319 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
2320 struct TicketIterationStopMessage,
2322 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2323 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
2324 struct RevokeTicketMessage,
2326 GNUNET_MQ_handler_end ());
2327 /* end of gnunet-service-reclaim.c */