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.
93 struct AttributeIterator
96 * Next element in the DLL
98 struct AttributeIterator *next;
101 * Previous element in the DLL
103 struct AttributeIterator *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
135 struct IdpClient *prev;
140 struct IdpClient *next;
145 struct GNUNET_SERVICE_Client *client;
148 * Message queue for transmission to @e client
150 struct GNUNET_MQ_Handle *mq;
154 * Attribute iteration operations in
155 * progress initiated by this client
157 struct AttributeIterator *attr_iter_head;
161 * Attribute iteration operations
162 * in progress initiated by this client
164 struct AttributeIterator *attr_iter_tail;
167 * Head of DLL of ticket iteration ops
169 struct TicketIteration *ticket_iter_head;
172 * Tail of DLL of ticket iteration ops
174 struct TicketIteration *ticket_iter_tail;
177 * Head of DLL of ticket revocation ops
179 struct TicketRevocationOperation *revoke_op_head;
182 * Tail of DLL of ticket revocation ops
184 struct TicketRevocationOperation *revoke_op_tail;
187 * Head of DLL of ticket issue ops
189 struct TicketIssueOperation *issue_op_head;
192 * Tail of DLL of ticket issue ops
194 struct TicketIssueOperation *issue_op_tail;
197 * Head of DLL of ticket consume ops
199 struct ConsumeTicketOperation *consume_op_head;
202 * Tail of DLL of ticket consume ops
204 struct ConsumeTicketOperation *consume_op_tail;
207 * Head of DLL of attribute store ops
209 struct AttributeStoreHandle *store_op_head;
212 * Tail of DLL of attribute store ops
214 struct AttributeStoreHandle *store_op_tail;
216 * Head of DLL of attribute delete ops
218 struct AttributeDeleteHandle *delete_op_head;
221 * Tail of DLL of attribute delete ops
223 struct AttributeDeleteHandle *delete_op_tail;
228 * Handle for attribute deletion request
230 struct AttributeDeleteHandle
235 struct AttributeDeleteHandle *next;
240 struct AttributeDeleteHandle *prev;
245 struct IdpClient *client;
250 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
256 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
261 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
264 * The attribute to delete
266 struct GNUNET_RECLAIM_Attribute *claim;
269 * The attestation to delete
271 struct GNUNET_RECLAIM_Attestation *attest;
276 struct TicketRecordsEntry *tickets_to_update_head;
281 struct TicketRecordsEntry *tickets_to_update_tail;
296 * Handle for attribute store request
298 struct AttributeStoreHandle
303 struct AttributeStoreHandle *next;
308 struct AttributeStoreHandle *prev;
313 struct IdpClient *client;
318 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
323 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pkey;
328 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
331 * The attribute to store
333 struct GNUNET_RECLAIM_Attribute *claim;
336 * The attestation to store
338 struct GNUNET_RECLAIM_Attestation *attest;
341 * The attribute expiration interval
343 struct GNUNET_TIME_Relative exp;
353 * Handle for ticket consume request
355 struct ConsumeTicketOperation
360 struct ConsumeTicketOperation *next;
365 struct ConsumeTicketOperation *prev;
370 struct IdpClient *client;
378 * Ticket consume handle
380 struct RECLAIM_TICKETS_ConsumeHandle *ch;
385 * Ticket revocation request handle
387 struct TicketRevocationOperation
392 struct TicketRevocationOperation *prev;
397 struct TicketRevocationOperation *next;
402 struct IdpClient *client;
407 struct RECLAIM_TICKETS_RevokeHandle *rh;
417 * Ticket issue operation handle
419 struct TicketIssueOperation
424 struct TicketIssueOperation *prev;
429 struct TicketIssueOperation *next;
434 struct IdpClient *client;
446 static struct IdpClient *client_list_head = NULL;
451 static struct IdpClient *client_list_tail = NULL;
455 * Cleanup attribute delete handle
457 * @param adh the attribute to cleanup
460 cleanup_adh (struct AttributeDeleteHandle *adh)
462 struct TicketRecordsEntry *le;
464 if (NULL != adh->ns_it)
465 GNUNET_NAMESTORE_zone_iteration_stop (adh->ns_it);
466 if (NULL != adh->ns_qe)
467 GNUNET_NAMESTORE_cancel (adh->ns_qe);
468 if (NULL != adh->label)
469 GNUNET_free (adh->label);
470 if (NULL != adh->claim)
471 GNUNET_free (adh->claim);
472 if (NULL != adh->attest)
473 GNUNET_free (adh->attest);
474 while (NULL != (le = adh->tickets_to_update_head))
476 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
477 adh->tickets_to_update_tail,
479 if (NULL != le->label)
480 GNUNET_free (le->label);
481 if (NULL != le->data)
482 GNUNET_free (le->data);
490 * Cleanup attribute store handle
492 * @param handle handle to clean up
495 cleanup_as_handle (struct AttributeStoreHandle *ash)
497 if (NULL != ash->ns_qe)
498 GNUNET_NAMESTORE_cancel (ash->ns_qe);
499 if (NULL != ash->claim)
500 GNUNET_free (ash->claim);
501 if (NULL != ash->attest)
502 GNUNET_free (ash->attest);
510 * @param idp the client to clean up
513 cleanup_client (struct IdpClient *idp)
515 struct AttributeIterator *ai;
516 struct TicketIteration *ti;
517 struct TicketRevocationOperation *rop;
518 struct TicketIssueOperation *iss;
519 struct ConsumeTicketOperation *ct;
520 struct AttributeStoreHandle *as;
521 struct AttributeDeleteHandle *adh;
523 while (NULL != (iss = idp->issue_op_head))
525 GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, idp->issue_op_tail, iss);
528 while (NULL != (ct = idp->consume_op_head))
530 GNUNET_CONTAINER_DLL_remove (idp->consume_op_head,
531 idp->consume_op_tail,
534 RECLAIM_TICKETS_consume_cancel (ct->ch);
537 while (NULL != (as = idp->store_op_head))
539 GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as);
540 cleanup_as_handle (as);
542 while (NULL != (adh = idp->delete_op_head))
544 GNUNET_CONTAINER_DLL_remove (idp->delete_op_head, idp->delete_op_tail, adh);
548 while (NULL != (ai = idp->attr_iter_head))
550 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
553 while (NULL != (rop = idp->revoke_op_head))
555 GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, idp->revoke_op_tail, rop);
557 RECLAIM_TICKETS_revoke_cancel (rop->rh);
560 while (NULL != (ti = idp->ticket_iter_head))
562 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
563 idp->ticket_iter_tail,
565 if (NULL != ti->iter)
566 RECLAIM_TICKETS_iteration_stop (ti->iter);
579 struct IdpClient *cl;
581 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
583 while (NULL != (cl = client_list_head))
585 GNUNET_CONTAINER_DLL_remove (client_list_head,
590 RECLAIM_TICKETS_deinit ();
591 if (NULL != timeout_task)
592 GNUNET_SCHEDULER_cancel (timeout_task);
594 GNUNET_NAMESTORE_disconnect (nsh);
604 do_shutdown (void *cls)
606 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
612 * Sends a ticket result message to the client
614 * @param client the client to send to
615 * @param r_id the request message ID to reply to
616 * @param ticket the ticket to include (may be NULL)
617 * @param success the success status of the request
620 send_ticket_result (const struct IdpClient *client,
622 const struct GNUNET_RECLAIM_Ticket *ticket,
625 struct TicketResultMessage *irm;
626 struct GNUNET_MQ_Envelope *env;
628 env = GNUNET_MQ_msg (irm,
629 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
632 irm->ticket = *ticket;
634 // TODO add success member
635 irm->id = htonl (r_id);
636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
637 GNUNET_MQ_send (client->mq, env);
642 * Issue ticket result
644 * @param cls out ticket issue operation handle
645 * @param ticket the issued ticket
646 * @param success issue success status (GNUNET_OK if successful)
647 * @param emsg error message (NULL of success is GNUNET_OK)
650 issue_ticket_result_cb (void *cls,
651 struct GNUNET_RECLAIM_Ticket *ticket,
655 struct TicketIssueOperation *tio = cls;
657 if (GNUNET_OK != success)
659 send_ticket_result (tio->client, tio->r_id, NULL, GNUNET_SYSERR);
660 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
661 tio->client->issue_op_tail,
664 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error issuing ticket: %s\n", emsg);
667 send_ticket_result (tio->client, tio->r_id, ticket, GNUNET_SYSERR);
668 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
669 tio->client->issue_op_tail,
676 * Check issue ticket message
679 * @im message to check
680 * @return GNUNET_OK if message is ok
683 check_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
687 size = ntohs (im->header.size);
688 if (size <= sizeof(struct IssueTicketMessage))
691 return GNUNET_SYSERR;
698 * Handle ticket issue message
700 * @param cls our client
701 * @param im the message
704 handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
706 struct TicketIssueOperation *tio;
707 struct IdpClient *idp = cls;
708 struct GNUNET_RECLAIM_AttributeList *attrs;
711 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ISSUE_TICKET message\n");
712 tio = GNUNET_new (struct TicketIssueOperation);
713 attrs_len = ntohs (im->attr_len);
714 attrs = GNUNET_RECLAIM_attribute_list_deserialize ((char *) &im[1],
716 tio->r_id = ntohl (im->id);
718 GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, idp->issue_op_tail, tio);
719 RECLAIM_TICKETS_issue (&im->identity,
722 &issue_ticket_result_cb,
724 GNUNET_SERVICE_client_continue (idp->client);
725 GNUNET_RECLAIM_attribute_list_destroy (attrs);
729 /**********************************************************
731 **********************************************************/
734 * Handles revocation result
736 * @param cls our revocation operation handle
737 * @param success revocation result (GNUNET_OK if successful)
740 revoke_result_cb (void *cls, int32_t success)
742 struct TicketRevocationOperation *rop = cls;
743 struct GNUNET_MQ_Envelope *env;
744 struct RevokeTicketResultMessage *trm;
746 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
747 "Sending REVOKE_TICKET_RESULT message\n");
749 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT);
750 trm->id = htonl (rop->r_id);
751 trm->success = htonl (success);
752 GNUNET_MQ_send (rop->client->mq, env);
753 GNUNET_CONTAINER_DLL_remove (rop->client->revoke_op_head,
754 rop->client->revoke_op_tail,
761 * Check revocation message format
764 * @param im the message to check
765 * @return GNUNET_OK if message is ok
768 check_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *im)
772 size = ntohs (im->header.size);
773 if (size != sizeof(struct RevokeTicketMessage))
776 return GNUNET_SYSERR;
783 * Handle a revocation message to a ticket.
785 * @param cls our client
786 * @param rm the message to handle
789 handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm)
791 struct TicketRevocationOperation *rop;
792 struct IdpClient *idp = cls;
794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REVOKE_TICKET message\n");
795 rop = GNUNET_new (struct TicketRevocationOperation);
796 rop->r_id = ntohl (rm->id);
798 GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, idp->revoke_op_tail, rop);
800 = RECLAIM_TICKETS_revoke (&rm->ticket, &rm->identity, &revoke_result_cb,
802 GNUNET_SERVICE_client_continue (idp->client);
807 * Handle a ticket consume result
809 * @param cls our consume ticket operation handle
810 * @param identity the attribute authority
811 * @param attrs the attribute/claim list
812 * @param success GNUNET_OK if successful
813 * @param emsg error message (NULL if success=GNUNET_OK)
816 consume_result_cb (void *cls,
817 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
818 const struct GNUNET_RECLAIM_AttributeList *attrs,
822 struct ConsumeTicketOperation *cop = cls;
823 struct ConsumeTicketResultMessage *crm;
824 struct GNUNET_MQ_Envelope *env;
828 if (GNUNET_OK != success)
830 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error consuming ticket: %s\n", emsg);
832 attrs_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
833 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
834 "Sending CONSUME_TICKET_RESULT message\n");
835 env = GNUNET_MQ_msg_extra (crm,
837 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
838 crm->id = htonl (cop->r_id);
839 crm->attrs_len = htons (attrs_len);
840 crm->identity = *identity;
841 crm->result = htonl (success);
842 data_tmp = (char *) &crm[1];
843 GNUNET_RECLAIM_attribute_list_serialize (attrs, data_tmp);
844 GNUNET_MQ_send (cop->client->mq, env);
845 GNUNET_CONTAINER_DLL_remove (cop->client->consume_op_head,
846 cop->client->consume_op_tail,
853 * Check a consume ticket message
856 * @param cm the message to handle
859 check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
863 size = ntohs (cm->header.size);
864 if (size != sizeof(struct ConsumeTicketMessage))
867 return GNUNET_SYSERR;
874 * Handle a consume ticket message
876 * @param cls our client handle
877 * @cm the message to handle
880 handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
882 struct ConsumeTicketOperation *cop;
883 struct IdpClient *idp = cls;
885 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CONSUME_TICKET message\n");
886 cop = GNUNET_new (struct ConsumeTicketOperation);
887 cop->r_id = ntohl (cm->id);
890 = RECLAIM_TICKETS_consume (&cm->identity, &cm->ticket, &consume_result_cb,
892 GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop);
893 GNUNET_SERVICE_client_continue (idp->client);
897 /*****************************************
899 *****************************************/
903 * Attribute store result handler
905 * @param cls our attribute store handle
906 * @param success GNUNET_OK if successful
907 * @param emsg error message (NULL if success=GNUNET_OK)
910 attr_store_cont (void *cls, int32_t success, const char *emsg)
912 struct AttributeStoreHandle *ash = cls;
913 struct GNUNET_MQ_Envelope *env;
914 struct SuccessResultMessage *acr_msg;
917 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
918 ash->client->store_op_tail,
921 if (GNUNET_SYSERR == success)
923 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
924 "Failed to store attribute %s\n",
926 cleanup_as_handle (ash);
927 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
931 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
932 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
933 acr_msg->id = htonl (ash->r_id);
934 acr_msg->op_result = htonl (GNUNET_OK);
935 GNUNET_MQ_send (ash->client->mq, env);
936 cleanup_as_handle (ash);
941 * Add a new attribute
943 * @param cls the AttributeStoreHandle
946 attr_store_task (void *cls)
948 struct AttributeStoreHandle *ash = cls;
949 struct GNUNET_GNSRECORD_Data rd[1];
954 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing attribute\n");
955 buf_size = GNUNET_RECLAIM_attribute_serialize_get_size (ash->claim);
956 buf = GNUNET_malloc (buf_size);
957 // Give the ash a new id if unset
958 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->claim->id))
959 GNUNET_RECLAIM_id_generate (&ash->claim->id);
960 GNUNET_RECLAIM_attribute_serialize (ash->claim, buf);
962 = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id,
963 sizeof (ash->claim->id));
964 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
966 rd[0].data_size = buf_size;
968 rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE;
969 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
970 rd[0].expiration_time = ash->exp.rel_value_us;
971 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
984 * Check an attribute store message
987 * @param sam the message to check
990 check_attribute_store_message (void *cls,
991 const struct AttributeStoreMessage *sam)
995 size = ntohs (sam->header.size);
996 if (size <= sizeof(struct AttributeStoreMessage))
999 return GNUNET_SYSERR;
1006 * Handle an attribute store message
1008 * @param cls our client
1009 * @param sam the message to handle
1012 handle_attribute_store_message (void *cls,
1013 const struct AttributeStoreMessage *sam)
1015 struct AttributeStoreHandle *ash;
1016 struct IdpClient *idp = cls;
1019 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_STORE message\n");
1021 data_len = ntohs (sam->attr_len);
1023 ash = GNUNET_new (struct AttributeStoreHandle);
1024 ash->claim = GNUNET_RECLAIM_attribute_deserialize ((char *) &sam[1],
1027 ash->r_id = ntohl (sam->id);
1028 ash->identity = sam->identity;
1029 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1030 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1032 GNUNET_SERVICE_client_continue (idp->client);
1034 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1035 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1040 * Attestation store result handler
1042 * @param cls our attribute store handle
1043 * @param success GNUNET_OK if successful
1044 * @param emsg error message (NULL if success=GNUNET_OK)
1047 attest_store_cont (void *cls, int32_t success, const char *emsg)
1049 struct AttributeStoreHandle *ash = cls;
1050 struct GNUNET_MQ_Envelope *env;
1051 struct SuccessResultMessage *acr_msg;
1054 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1055 ash->client->store_op_tail,
1058 if (GNUNET_SYSERR == success)
1060 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1061 "Failed to store attestation %s\n",
1063 cleanup_as_handle (ash);
1064 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1068 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1069 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1070 acr_msg->id = htonl (ash->r_id);
1071 acr_msg->op_result = htonl (GNUNET_OK);
1072 GNUNET_MQ_send (ash->client->mq, env);
1073 cleanup_as_handle (ash);
1078 * Error looking up potential attestation. Abort.
1080 * @param cls our attribute store handle
1083 attest_error (void *cls)
1085 struct AttributeStoreHandle *ash = cls;
1086 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1087 "Failed to check for existing Attestation\n");
1088 cleanup_as_handle (ash);
1089 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1095 * Check for existing record before storing attestation
1097 * @param cls our attribute store handle
1098 * @param zone zone we are iterating
1099 * @param label label of the records
1100 * @param rd_count record count
1104 attest_add_cb (void *cls,
1105 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1107 unsigned int rd_count,
1108 const struct GNUNET_GNSRECORD_Data *rd)
1110 struct AttributeStoreHandle *ash = cls;
1113 buf_size = GNUNET_RECLAIM_attestation_serialize_get_size (ash->attest);
1114 buf = GNUNET_malloc (buf_size);
1115 GNUNET_RECLAIM_attestation_serialize (ash->attest, buf);
1116 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1117 "Storing new Attestation\n");
1118 struct GNUNET_GNSRECORD_Data rd_new[1];
1119 rd_new[0].data_size = buf_size;
1120 rd_new[0].data = buf;
1121 rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION;
1122 rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1123 rd_new[0].expiration_time = ash->exp.rel_value_us;
1124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1125 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1138 * Add a new attestation
1140 * @param cls the AttributeStoreHandle
1143 attest_store_task (void *cls)
1145 struct AttributeStoreHandle *ash = cls;
1148 // Give the ash a new id if unset
1149 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->attest->id))
1150 GNUNET_RECLAIM_id_generate (&ash->attest->id);
1151 label = GNUNET_STRINGS_data_to_string_alloc (&ash->attest->id,
1152 sizeof (ash->attest->id));
1153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1154 "Looking up existing data under label %s\n", label);
1155 // Test for the content of the existing ID
1156 ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1163 GNUNET_free (label);
1168 * Check an attestation store message
1171 * @param sam the message to check
1174 check_attestation_store_message (void *cls,
1175 const struct AttributeStoreMessage *sam)
1179 size = ntohs (sam->header.size);
1180 if (size <= sizeof(struct AttributeStoreMessage))
1183 return GNUNET_SYSERR;
1190 * Handle an attestation store message
1192 * @param cls our client
1193 * @param sam the message to handle
1196 handle_attestation_store_message (void *cls,
1197 const struct AttributeStoreMessage *sam)
1199 struct AttributeStoreHandle *ash;
1200 struct IdpClient *idp = cls;
1203 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_STORE message\n");
1205 data_len = ntohs (sam->attr_len);
1207 ash = GNUNET_new (struct AttributeStoreHandle);
1208 ash->attest = GNUNET_RECLAIM_attestation_deserialize ((char *) &sam[1],
1211 ash->r_id = ntohl (sam->id);
1212 ash->identity = sam->identity;
1213 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1214 GNUNET_CRYPTO_ecdsa_key_get_public (&sam->identity, &ash->identity_pkey);
1216 GNUNET_SERVICE_client_continue (idp->client);
1218 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1219 GNUNET_SCHEDULER_add_now (&attest_store_task, ash);
1224 * Send a deletion success response
1226 * @param adh our attribute deletion handle
1227 * @param success the success status
1230 send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
1232 struct GNUNET_MQ_Envelope *env;
1233 struct SuccessResultMessage *acr_msg;
1235 GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
1236 adh->client->delete_op_tail,
1239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1240 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1241 acr_msg->id = htonl (adh->r_id);
1242 acr_msg->op_result = htonl (success);
1243 GNUNET_MQ_send (adh->client->mq, env);
1248 * Namestore iteration within attribute deletion.
1249 * We need to reissue tickets with the deleted attribute removed.
1251 * @param cls our attribute deletion handle
1252 * @param zone the private key of the ticket issuer
1253 * @param label the label of the record
1254 * @param rd_count number of records
1255 * @param rd record data
1258 ticket_iter (void *cls,
1259 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1261 unsigned int rd_count,
1262 const struct GNUNET_GNSRECORD_Data *rd)
1264 struct AttributeDeleteHandle *adh = cls;
1265 struct TicketRecordsEntry *le;
1266 int has_changed = GNUNET_NO;
1267 for (int i = 0; i < rd_count; i++)
1269 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF != rd[i].record_type)
1271 if (adh->claim != NULL)
1272 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
1275 if (adh->attest != NULL)
1276 if (GNUNET_YES != GNUNET_RECLAIM_id_is_equal (rd[i].data,
1279 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1280 "Attribute or Attestation to delete found (%s)\n",
1282 has_changed = GNUNET_YES;
1285 if (GNUNET_YES == has_changed)
1287 le = GNUNET_new (struct TicketRecordsEntry);
1288 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1289 le->data = GNUNET_malloc (le->data_size);
1290 le->rd_count = rd_count;
1291 le->label = GNUNET_strdup (label);
1292 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
1293 GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head,
1294 adh->tickets_to_update_tail,
1297 GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
1302 * Recursion prototype for function
1303 * @param cls our deletion handle
1306 update_tickets (void *cls);
1310 * Callback called when a ticket was updated
1312 * @param cls our attribute deletion handle
1313 * @param success GNUNET_OK if successful
1314 * @param emsg error message (NULL if success=GNUNET_OK)
1317 ticket_updated (void *cls, int32_t success, const char *emsg)
1319 struct AttributeDeleteHandle *adh = cls;
1322 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1327 * Update tickets: Remove shared attribute which has just been deleted.
1328 * This method is called recursively until all tickets are processed.
1329 * Eventually, the updated tickets are stored using ``update_tickets''.
1331 * @param cls our attribute deletion handle
1334 update_tickets (void *cls)
1336 struct AttributeDeleteHandle *adh = cls;
1337 struct TicketRecordsEntry *le;
1339 if (NULL == adh->tickets_to_update_head)
1341 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1342 "Finished updating tickets, success\n");
1343 send_delete_response (adh, GNUNET_OK);
1347 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1349 adh->tickets_to_update_head->label);
1350 le = adh->tickets_to_update_head;
1351 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
1352 adh->tickets_to_update_tail,
1354 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
1355 struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1];
1356 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
1361 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1362 "Unable to deserialize record data!\n");
1363 send_delete_response (adh, GNUNET_SYSERR);
1368 for (int i = 0; i < le->rd_count; i++)
1370 if (adh->claim != NULL)
1371 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type)
1372 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1375 if (adh->attest != NULL)
1376 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[i].record_type)
1377 && (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1383 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1390 GNUNET_free (le->label);
1391 GNUNET_free (le->data);
1397 * Done collecting affected tickets, start updating.
1399 * @param cls our attribute deletion handle
1402 ticket_iter_fin (void *cls)
1404 struct AttributeDeleteHandle *adh = cls;
1406 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1411 * Error collecting affected tickets. Abort.
1413 * @param cls our attribute deletion handle
1416 ticket_iter_err (void *cls)
1418 struct AttributeDeleteHandle *adh = cls;
1421 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1422 "Namestore error on delete %s\n",
1424 send_delete_response (adh, GNUNET_SYSERR);
1430 * Start processing tickets which may still contain reference to deleted
1433 * @param cls attribute deletion handle
1436 start_ticket_update (void *cls)
1438 struct AttributeDeleteHandle *adh = cls;
1440 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1452 * Attribute deleted callback
1454 * @param cls our handle
1455 * @param success success status
1456 * @param emsg error message (NULL if success=GNUNET_OK)
1459 attr_delete_cont (void *cls, int32_t success, const char *emsg)
1461 struct AttributeDeleteHandle *adh = cls;
1464 if (GNUNET_SYSERR == success)
1466 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1467 "Error deleting attribute %s\n",
1469 send_delete_response (adh, GNUNET_SYSERR);
1473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1474 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1479 * Check attribute delete message format
1482 * @dam message to check
1485 check_attribute_delete_message (void *cls,
1486 const struct AttributeDeleteMessage *dam)
1490 size = ntohs (dam->header.size);
1491 if (size <= sizeof(struct AttributeDeleteMessage))
1494 return GNUNET_SYSERR;
1501 * Handle attribute deletion
1503 * @param cls our client
1504 * @param dam deletion message
1507 handle_attribute_delete_message (void *cls,
1508 const struct AttributeDeleteMessage *dam)
1510 struct AttributeDeleteHandle *adh;
1511 struct IdpClient *idp = cls;
1514 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_DELETE message\n");
1516 data_len = ntohs (dam->attr_len);
1518 adh = GNUNET_new (struct AttributeDeleteHandle);
1519 adh->claim = GNUNET_RECLAIM_attribute_deserialize ((char *) &dam[1],
1523 adh->r_id = ntohl (dam->id);
1524 adh->identity = dam->identity;
1526 = GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id,
1527 sizeof(adh->claim->id));
1528 GNUNET_SERVICE_client_continue (idp->client);
1530 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1531 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1542 * Attestation deleted callback
1544 * @param cls our handle
1545 * @param success success status
1546 * @param emsg error message (NULL if success=GNUNET_OK)
1549 attest_delete_cont (void *cls, int32_t success, const char *emsg)
1551 struct AttributeDeleteHandle *adh = cls;
1554 if (GNUNET_SYSERR == success)
1556 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1557 "Error deleting attestation %s\n",
1559 send_delete_response (adh, GNUNET_SYSERR);
1563 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1564 GNUNET_SCHEDULER_add_now (&start_ticket_update, adh);
1569 * Check attestation delete message format
1572 * @dam message to check
1575 check_attestation_delete_message (void *cls,
1576 const struct AttributeDeleteMessage *dam)
1580 size = ntohs (dam->header.size);
1581 if (size <= sizeof(struct AttributeDeleteMessage))
1584 return GNUNET_SYSERR;
1591 * Handle attestation deletion
1593 * @param cls our client
1594 * @param dam deletion message
1597 handle_attestation_delete_message (void *cls,
1598 const struct AttributeDeleteMessage *dam)
1600 struct AttributeDeleteHandle *adh;
1601 struct IdpClient *idp = cls;
1604 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTESTATION_DELETE message\n");
1606 data_len = ntohs (dam->attr_len);
1608 adh = GNUNET_new (struct AttributeDeleteHandle);
1609 adh->attest = GNUNET_RECLAIM_attestation_deserialize ((char *) &dam[1],
1613 adh->r_id = ntohl (dam->id);
1614 adh->identity = dam->identity;
1616 = GNUNET_STRINGS_data_to_string_alloc (&adh->attest->id,
1617 sizeof(adh->attest->id));
1618 GNUNET_SERVICE_client_continue (idp->client);
1620 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1621 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1626 &attest_delete_cont,
1631 /*************************************************
1632 * Attrubute iteration
1633 *************************************************/
1637 * Done iterating over attributes
1639 * @param cls our iterator handle
1642 attr_iter_finished (void *cls)
1644 struct AttributeIterator *ai = cls;
1645 struct GNUNET_MQ_Envelope *env;
1646 struct AttributeResultMessage *arm;
1648 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
1649 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1650 arm->id = htonl (ai->request_id);
1651 arm->attr_len = htons (0);
1652 GNUNET_MQ_send (ai->client->mq, env);
1653 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
1654 ai->client->attr_iter_tail,
1661 * Error iterating over attributes. Abort.
1663 * @param cls our attribute iteration handle
1666 attr_iter_error (void *cls)
1668 struct AttributeIterator *ai = cls;
1670 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
1671 attr_iter_finished (ai);
1676 * Got record. Return if it is an attribute or attestation.
1678 * @param cls our attribute iterator
1679 * @param zone zone we are iterating
1680 * @param label label of the records
1681 * @param rd_count record count
1685 attr_iter_cb (void *cls,
1686 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1688 unsigned int rd_count,
1689 const struct GNUNET_GNSRECORD_Data *rd)
1691 struct AttributeIterator *ai = cls;
1692 struct GNUNET_MQ_Envelope *env;
1697 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1702 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF == rd[0].record_type)
1704 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1705 "Found Ticket. Ignoring.\n");
1706 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1709 else if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION != rd[0].record_type)
1711 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1712 "Non-Attestation record with multiple entries found: %u\n",
1714 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1719 for (int i = 0; i<rd_count; i++)
1721 if ((GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE != rd[i].record_type) &&
1722 (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION != rd[i].record_type))
1724 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1727 // FIXME Send attribute TOGETHER with respective attestation if applicable
1728 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE == rd[i].record_type)
1730 struct AttributeResultMessage *arm;
1731 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n",
1733 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1734 "Sending ATTRIBUTE_RESULT message\n");
1735 env = GNUNET_MQ_msg_extra (arm,
1737 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1738 arm->id = htonl (ai->request_id);
1739 arm->attr_len = htons (rd[i].data_size);
1740 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
1741 data_tmp = (char *) &arm[1];
1742 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
1743 GNUNET_MQ_send (ai->client->mq, env);
1747 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTESTATION == rd[i].record_type)
1749 struct AttributeResultMessage *arm;
1750 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attestation under: %s\n",
1752 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1753 "Sending ATTESTATION_RESULT message\n");
1754 env = GNUNET_MQ_msg_extra (arm,
1756 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_RESULT);
1757 arm->id = htonl (ai->request_id);
1758 arm->attr_len = htons (rd[i].data_size);
1759 GNUNET_CRYPTO_ecdsa_key_get_public (zone, &arm->identity);
1760 data_tmp = (char *) &arm[1];
1761 GNUNET_memcpy (data_tmp, rd[i].data, rd[i].data_size);
1762 GNUNET_MQ_send (ai->client->mq, env);
1770 * Iterate over zone to get attributes
1772 * @param cls our client
1773 * @param ais_msg the iteration message to start
1776 handle_iteration_start (void *cls,
1777 const struct AttributeIterationStartMessage *ais_msg)
1779 struct IdpClient *idp = cls;
1780 struct AttributeIterator *ai;
1782 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1783 "Received ATTRIBUTE_ITERATION_START message\n");
1784 ai = GNUNET_new (struct AttributeIterator);
1785 ai->request_id = ntohl (ais_msg->id);
1787 ai->identity = ais_msg->identity;
1789 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, idp->attr_iter_tail, ai);
1790 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1796 &attr_iter_finished,
1798 GNUNET_SERVICE_client_continue (idp->client);
1803 * Handle iteration stop message from client
1805 * @param cls the client
1806 * @param ais_msg the stop message
1809 handle_iteration_stop (void *cls,
1810 const struct AttributeIterationStopMessage *ais_msg)
1812 struct IdpClient *idp = cls;
1813 struct AttributeIterator *ai;
1816 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1817 "Received `%s' message\n",
1818 "ATTRIBUTE_ITERATION_STOP");
1819 rid = ntohl (ais_msg->id);
1820 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1821 if (ai->request_id == rid)
1826 GNUNET_SERVICE_client_drop (idp->client);
1829 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
1831 GNUNET_SERVICE_client_continue (idp->client);
1836 * Client requests next attribute from iterator
1838 * @param cls the client
1839 * @param ais_msg the message
1842 handle_iteration_next (void *cls,
1843 const struct AttributeIterationNextMessage *ais_msg)
1845 struct IdpClient *idp = cls;
1846 struct AttributeIterator *ai;
1849 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1850 "Received ATTRIBUTE_ITERATION_NEXT message\n");
1851 rid = ntohl (ais_msg->id);
1852 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1853 if (ai->request_id == rid)
1858 GNUNET_SERVICE_client_drop (idp->client);
1861 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1862 GNUNET_SERVICE_client_continue (idp->client);
1866 /******************************************************
1868 ******************************************************/
1871 * Got a ticket. Return to client
1873 * @param cls our ticket iterator
1874 * @param ticket the ticket
1877 ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
1879 struct TicketIteration *ti = cls;
1880 struct GNUNET_MQ_Envelope *env;
1881 struct TicketResultMessage *trm;
1883 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
1886 /* send empty response to indicate end of list */
1887 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
1888 ti->client->ticket_iter_tail,
1893 trm->ticket = *ticket;
1895 trm->id = htonl (ti->r_id);
1896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
1897 GNUNET_MQ_send (ti->client->mq, env);
1904 * Client requests a ticket iteration
1906 * @param cls the client
1907 * @param tis_msg the iteration request message
1910 handle_ticket_iteration_start (
1912 const struct TicketIterationStartMessage *tis_msg)
1914 struct IdpClient *client = cls;
1915 struct TicketIteration *ti;
1917 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1918 "Received TICKET_ITERATION_START message\n");
1919 ti = GNUNET_new (struct TicketIteration);
1920 ti->r_id = ntohl (tis_msg->id);
1921 ti->client = client;
1923 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
1924 client->ticket_iter_tail,
1927 = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti);
1928 GNUNET_SERVICE_client_continue (client->client);
1933 * Client has had enough tickets
1935 * @param cls the client
1936 * @param tis_msg the stop message
1939 handle_ticket_iteration_stop (void *cls,
1940 const struct TicketIterationStopMessage *tis_msg)
1942 struct IdpClient *client = cls;
1943 struct TicketIteration *ti;
1946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1947 "Received `%s' message\n",
1948 "TICKET_ITERATION_STOP");
1949 rid = ntohl (tis_msg->id);
1950 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
1951 if (ti->r_id == rid)
1956 GNUNET_SERVICE_client_drop (client->client);
1959 RECLAIM_TICKETS_iteration_stop (ti->iter);
1960 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
1961 client->ticket_iter_tail,
1964 GNUNET_SERVICE_client_continue (client->client);
1969 * Client requests next result.
1971 * @param cls the client
1972 * @param tis_msg the message
1975 handle_ticket_iteration_next (void *cls,
1976 const struct TicketIterationNextMessage *tis_msg)
1978 struct IdpClient *client = cls;
1979 struct TicketIteration *ti;
1982 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1983 "Received TICKET_ITERATION_NEXT message\n");
1984 rid = ntohl (tis_msg->id);
1985 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
1986 if (ti->r_id == rid)
1991 GNUNET_SERVICE_client_drop (client->client);
1994 RECLAIM_TICKETS_iteration_next (ti->iter);
1995 GNUNET_SERVICE_client_continue (client->client);
2000 * Main function that will be run
2002 * @param cls closure
2003 * @param c the configuration used
2004 * @param server the service handle
2008 const struct GNUNET_CONFIGURATION_Handle *c,
2009 struct GNUNET_SERVICE_Handle *server)
2013 if (GNUNET_OK != RECLAIM_TICKETS_init (cfg))
2015 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2016 "Unable to initialize TICKETS subsystem.\n");
2017 GNUNET_SCHEDULER_shutdown ();
2020 // Connect to identity and namestore services
2021 nsh = GNUNET_NAMESTORE_connect (cfg);
2024 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2025 "error connecting to namestore");
2028 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2033 * Called whenever a client is disconnected.
2035 * @param cls closure
2036 * @param client identification of the client
2037 * @param app_ctx @a client
2040 client_disconnect_cb (void *cls,
2041 struct GNUNET_SERVICE_Client *client,
2044 struct IdpClient *idp = app_ctx;
2046 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
2047 GNUNET_CONTAINER_DLL_remove (client_list_head,
2050 cleanup_client (idp);
2055 * Add a client to our list of active clients.
2058 * @param client client to add
2059 * @param mq message queue for @a client
2060 * @return internal namestore client structure for this client
2063 client_connect_cb (void *cls,
2064 struct GNUNET_SERVICE_Client *client,
2065 struct GNUNET_MQ_Handle *mq)
2067 struct IdpClient *idp;
2069 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
2070 idp = GNUNET_new (struct IdpClient);
2071 idp->client = client;
2073 GNUNET_CONTAINER_DLL_insert (client_list_head,
2081 * Define "main" method using service macro.
2083 GNUNET_SERVICE_MAIN (
2085 GNUNET_SERVICE_OPTION_NONE,
2088 &client_disconnect_cb,
2090 GNUNET_MQ_hd_var_size (attribute_store_message,
2091 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
2092 struct AttributeStoreMessage,
2094 GNUNET_MQ_hd_var_size (attestation_store_message,
2095 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_STORE,
2096 struct AttributeStoreMessage,
2098 GNUNET_MQ_hd_var_size (attribute_delete_message,
2099 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
2100 struct AttributeDeleteMessage,
2102 GNUNET_MQ_hd_var_size (attestation_delete_message,
2103 GNUNET_MESSAGE_TYPE_RECLAIM_ATTESTATION_DELETE,
2104 struct AttributeDeleteMessage,
2106 GNUNET_MQ_hd_fixed_size (iteration_start,
2107 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
2108 struct AttributeIterationStartMessage,
2110 GNUNET_MQ_hd_fixed_size (iteration_next,
2111 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
2112 struct AttributeIterationNextMessage,
2114 GNUNET_MQ_hd_fixed_size (iteration_stop,
2115 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
2116 struct AttributeIterationStopMessage,
2118 GNUNET_MQ_hd_var_size (issue_ticket_message,
2119 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
2120 struct IssueTicketMessage,
2122 GNUNET_MQ_hd_var_size (consume_ticket_message,
2123 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
2124 struct ConsumeTicketMessage,
2126 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2127 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
2128 struct TicketIterationStartMessage,
2130 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2131 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
2132 struct TicketIterationNextMessage,
2134 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2135 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
2136 struct TicketIterationStopMessage,
2138 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2139 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
2140 struct RevokeTicketMessage,
2142 GNUNET_MQ_handler_end ());
2143 /* end of gnunet-service-reclaim.c */