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
22 * @author Martin Schanzenbach
23 * @file src/reclaim/gnunet-service-reclaim_tickets.c
24 * @brief reclaim tickets
29 #include "gnunet-service-reclaim_tickets.h"
31 struct ParallelLookup;
33 struct RECLAIM_TICKETS_ConsumeHandle
38 struct GNUNET_RECLAIM_Ticket ticket;
43 struct GNUNET_GNS_LookupRequest *lookup_request;
48 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
53 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
58 struct ParallelLookup *parallel_lookups_head;
63 struct ParallelLookup *parallel_lookups_tail;
68 struct GNUNET_SCHEDULER_Task *kill_task;
73 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
78 struct GNUNET_TIME_Absolute lookup_start_time;
83 RECLAIM_TICKETS_ConsumeCallback cb;
92 * Handle for a parallel GNS lookup job
97 struct ParallelLookup *next;
100 struct ParallelLookup *prev;
102 /* The GNS request */
103 struct GNUNET_GNS_LookupRequest *lookup_request;
105 /* The handle the return to */
106 struct RECLAIM_TICKETS_ConsumeHandle *handle;
111 struct GNUNET_TIME_Absolute lookup_start_time;
113 /* The label to look up */
119 * A reference to a ticket stored in GNS
121 struct TicketReference
126 struct TicketReference *next;
131 struct TicketReference *prev;
136 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
141 struct GNUNET_RECLAIM_Ticket ticket;
146 * Ticket issue request handle
148 struct TicketIssueHandle
151 * Attributes to issue
153 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
158 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
163 struct GNUNET_RECLAIM_Ticket ticket;
168 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
173 RECLAIM_TICKETS_TicketResult cb;
184 struct RECLAIM_TICKETS_Iterator
187 * Namestore queue entry
189 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
194 RECLAIM_TICKETS_TicketIter cb;
203 struct RevokedAttributeEntry
208 struct RevokedAttributeEntry *next;
213 struct RevokedAttributeEntry *prev;
216 * Old ID of the attribute
221 * New ID of the attribute
227 struct TicketRecordsEntry
232 struct TicketRecordsEntry *next;
237 struct TicketRecordsEntry *prev;
242 unsigned int rd_count;
261 * Ticket revocation request handle
263 struct RECLAIM_TICKETS_RevokeHandle
268 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
273 RECLAIM_TICKETS_RevokeCallback cb;
283 struct GNUNET_RECLAIM_Ticket ticket;
288 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
293 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
298 struct RevokedAttributeEntry *attrs_head;
303 struct RevokedAttributeEntry *attrs_tail;
306 * Current attribute to move
308 struct RevokedAttributeEntry *move_attr;
311 * Number of attributes in ticket
313 unsigned int ticket_attrs;
318 struct TicketRecordsEntry *tickets_to_update_head;
323 struct TicketRecordsEntry *tickets_to_update_tail;
327 /* Namestore handle */
328 static struct GNUNET_NAMESTORE_Handle *nsh;
331 static struct GNUNET_GNS_Handle *gns;
333 /* Handle to the statistics service */
334 static struct GNUNET_STATISTICS_Handle *stats;
337 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rh);
340 move_attrs_cont (void *cls)
342 move_attrs ((struct RECLAIM_TICKETS_RevokeHandle *)cls);
346 * Cleanup revoke handle
348 * @param rh the ticket revocation handle
351 cleanup_rvk (struct RECLAIM_TICKETS_RevokeHandle *rh)
353 struct RevokedAttributeEntry *ae;
354 struct TicketRecordsEntry *le;
355 if (NULL != rh->ns_qe)
356 GNUNET_NAMESTORE_cancel (rh->ns_qe);
357 if (NULL != rh->ns_it)
358 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
359 while (NULL != (ae = rh->attrs_head)) {
360 GNUNET_CONTAINER_DLL_remove (rh->attrs_head, rh->attrs_tail, ae);
363 while (NULL != (le = rh->tickets_to_update_head)) {
364 GNUNET_CONTAINER_DLL_remove (rh->tickets_to_update_head,
365 rh->tickets_to_update_head, le);
366 if (NULL != le->data)
367 GNUNET_free (le->data);
368 if (NULL != le->label)
369 GNUNET_free (le->label);
376 del_attr_finished (void *cls, int32_t success, const char *emsg)
378 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
380 if (GNUNET_SYSERR == success) {
381 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error removing attribute: %s\n",
383 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
387 rvk->move_attr = rvk->move_attr->next;
388 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
392 move_attr_finished (void *cls, int32_t success, const char *emsg)
394 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
397 if (GNUNET_SYSERR == success) {
398 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error moving attribute: %s\n", emsg);
399 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
403 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
405 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing attribute %s\n", label);
406 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, label, 0,
407 NULL, &del_attr_finished, rvk);
412 rvk_move_attr_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
413 const char *label, unsigned int rd_count,
414 const struct GNUNET_GNSRECORD_Data *rd)
416 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
417 struct RevokedAttributeEntry *le;
421 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
422 "The attribute %s no longer exists!\n", label);
424 rvk->move_attr = le->next;
425 GNUNET_CONTAINER_DLL_remove (rvk->attrs_head, rvk->attrs_tail, le);
427 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
430 /** find a new place for this attribute **/
431 rvk->move_attr->new_id =
432 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
433 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
436 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, new_label,
437 1, rd, &move_attr_finished, rvk);
438 GNUNET_free (new_label);
443 rvk_ticket_update (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
444 const char *label, unsigned int rd_count,
445 const struct GNUNET_GNSRECORD_Data *rd)
447 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
448 struct TicketRecordsEntry *le;
449 struct RevokedAttributeEntry *ae;
450 int has_changed = GNUNET_NO;
452 /** Let everything point to the old record **/
453 for (int i = 0; i < rd_count; i++) {
454 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
456 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next) {
457 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
459 has_changed = GNUNET_YES;
462 if (GNUNET_YES == has_changed)
465 if (GNUNET_YES == has_changed) {
466 le = GNUNET_new (struct TicketRecordsEntry);
467 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
468 le->data = GNUNET_malloc (le->data_size);
469 le->rd_count = rd_count;
470 le->label = GNUNET_strdup (label);
471 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
472 GNUNET_CONTAINER_DLL_insert (rvk->tickets_to_update_head,
473 rvk->tickets_to_update_tail, le);
475 GNUNET_NAMESTORE_zone_iterator_next (rvk->ns_it, 1);
480 process_tickets (void *cls);
484 ticket_processed (void *cls, int32_t success, const char *emsg)
486 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
488 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
492 process_tickets (void *cls)
494 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
495 struct TicketRecordsEntry *le;
496 struct RevokedAttributeEntry *ae;
497 if (NULL == rvk->tickets_to_update_head) {
498 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
499 "Finished updatding tickets, success\n");
500 rvk->cb (rvk->cb_cls, GNUNET_OK);
504 le = rvk->tickets_to_update_head;
505 GNUNET_CONTAINER_DLL_remove (rvk->tickets_to_update_head,
506 rvk->tickets_to_update_tail, le);
507 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
508 GNUNET_GNSRECORD_records_deserialize (le->data_size, le->data, le->rd_count,
510 for (int i = 0; i < le->rd_count; i++) {
511 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
513 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next) {
514 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
516 rd[i].data = &ae->new_id;
519 rvk->ns_qe = GNUNET_NAMESTORE_records_store (
520 nsh, &rvk->identity, le->label, le->rd_count, rd, &ticket_processed, rvk);
521 GNUNET_free (le->label);
522 GNUNET_free (le->data);
527 rvk_ticket_update_finished (void *cls)
529 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
531 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
536 rvk_ns_iter_err (void *cls)
538 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
540 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
541 "Namestore error on revocation (id=%" PRIu64 "\n",
542 rvk->move_attr->old_id);
543 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
549 rvk_ns_err (void *cls)
551 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
553 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
554 "Namestore error on revocation (id=%" PRIu64 "\n",
555 rvk->move_attr->old_id);
556 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
562 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
566 if (NULL == rvk->move_attr) {
567 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished moving attributes\n");
568 rvk->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
569 nsh, &rvk->identity, &rvk_ns_iter_err, rvk, &rvk_ticket_update, rvk,
570 &rvk_ticket_update_finished, rvk);
573 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
575 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label);
577 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (
578 nsh, &rvk->identity, label, &rvk_ns_err, rvk, &rvk_move_attr_cb, rvk);
584 remove_ticket_cont (void *cls, int32_t success, const char *emsg)
586 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
588 if (GNUNET_SYSERR == success) {
589 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
590 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
594 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted ticket\n");
595 if (0 == rvk->ticket_attrs) {
596 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
597 "No attributes to move... strange\n");
598 rvk->cb (rvk->cb_cls, GNUNET_OK);
602 rvk->move_attr = rvk->attrs_head;
608 revoke_attrs_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
609 const char *label, unsigned int rd_count,
610 const struct GNUNET_GNSRECORD_Data *rd)
613 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
614 struct RevokedAttributeEntry *le;
616 for (int i = 0; i < rd_count; i++) {
617 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
619 le = GNUNET_new (struct RevokedAttributeEntry);
620 le->old_id = *((uint64_t *)rd[i].data);
621 GNUNET_CONTAINER_DLL_insert (rvk->attrs_head, rvk->attrs_tail, le);
625 /** Now, remove ticket **/
626 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, label, 0,
627 NULL, &remove_ticket_cont, rvk);
632 rvk_attrs_err_cb (void *cls)
634 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
635 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
640 struct RECLAIM_TICKETS_RevokeHandle *
641 RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket,
642 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
643 RECLAIM_TICKETS_RevokeCallback cb, void *cb_cls)
645 struct RECLAIM_TICKETS_RevokeHandle *rvk;
648 rvk = GNUNET_new (struct RECLAIM_TICKETS_RevokeHandle);
650 rvk->cb_cls = cb_cls;
651 rvk->identity = *identity;
652 rvk->ticket = *ticket;
653 GNUNET_CRYPTO_ecdsa_key_get_public (&rvk->identity, &rvk->ticket.identity);
654 /** Get shared attributes **/
655 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof (uint64_t));
657 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (
658 nsh, identity, label, &rvk_attrs_err_cb, rvk, &revoke_attrs_cb, rvk);
664 RECLAIM_TICKETS_revoke_cancel (struct RECLAIM_TICKETS_RevokeHandle *rh)
668 /*******************************
670 *******************************/
673 * Cleanup ticket consume handle
674 * @param cth the handle to clean up
677 cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth)
679 struct ParallelLookup *lu;
680 struct ParallelLookup *tmp;
681 if (NULL != cth->lookup_request)
682 GNUNET_GNS_lookup_cancel (cth->lookup_request);
683 for (lu = cth->parallel_lookups_head; NULL != lu;) {
684 GNUNET_GNS_lookup_cancel (lu->lookup_request);
685 GNUNET_free (lu->label);
687 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
688 cth->parallel_lookups_tail, lu);
693 if (NULL != cth->attrs)
694 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (cth->attrs);
700 process_parallel_lookup_result (void *cls, uint32_t rd_count,
701 const struct GNUNET_GNSRECORD_Data *rd)
703 struct ParallelLookup *parallel_lookup = cls;
704 struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle;
705 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
706 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parallel lookup finished (count=%u)\n",
709 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
710 cth->parallel_lookups_tail, parallel_lookup);
711 GNUNET_free (parallel_lookup->label);
713 GNUNET_STATISTICS_update (
714 stats, "attribute_lookup_time_total",
715 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time)
718 GNUNET_STATISTICS_update (stats, "attribute_lookups_count", 1, GNUNET_YES);
721 GNUNET_free (parallel_lookup);
723 GNUNET_break (0); // TODO
724 if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR) {
725 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
727 GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
728 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, cth->attrs->list_tail,
731 if (NULL != cth->parallel_lookups_head)
732 return; // Wait for more
733 /* Else we are done */
735 GNUNET_SCHEDULER_cancel (cth->kill_task);
736 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
742 abort_parallel_lookups (void *cls)
744 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
745 struct ParallelLookup *lu;
746 struct ParallelLookup *tmp;
748 cth->kill_task = NULL;
749 for (lu = cth->parallel_lookups_head; NULL != lu;) {
750 GNUNET_GNS_lookup_cancel (lu->lookup_request);
751 GNUNET_free (lu->label);
753 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
754 cth->parallel_lookups_tail, lu);
758 cth->cb (cth->cb_cls, NULL, NULL, GNUNET_SYSERR, "Aborted");
763 lookup_authz_cb (void *cls, uint32_t rd_count,
764 const struct GNUNET_GNSRECORD_Data *rd)
766 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
767 struct ParallelLookup *parallel_lookup;
770 cth->lookup_request = NULL;
772 GNUNET_STATISTICS_update (
773 stats, "reclaim_authz_lookup_time_total",
774 GNUNET_TIME_absolute_get_duration (cth->lookup_start_time).rel_value_us,
776 GNUNET_STATISTICS_update (stats, "reclaim_authz_lookups_count", 1,
779 for (int i = 0; i < rd_count; i++) {
780 lbl = GNUNET_STRINGS_data_to_string_alloc (rd[i].data, rd[i].data_size);
781 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute ref found %s\n", lbl);
782 parallel_lookup = GNUNET_new (struct ParallelLookup);
783 parallel_lookup->handle = cth;
784 parallel_lookup->label = lbl;
785 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get ();
786 parallel_lookup->lookup_request = GNUNET_GNS_lookup (
787 gns, lbl, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
788 GNUNET_GNS_LO_DEFAULT, &process_parallel_lookup_result,
790 GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head,
791 cth->parallel_lookups_tail, parallel_lookup);
793 cth->kill_task = GNUNET_SCHEDULER_add_delayed (
794 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3),
795 &abort_parallel_lookups, cth);
799 struct RECLAIM_TICKETS_ConsumeHandle *
800 RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id,
801 const struct GNUNET_RECLAIM_Ticket *ticket,
802 RECLAIM_TICKETS_ConsumeCallback cb, void *cb_cls)
804 struct RECLAIM_TICKETS_ConsumeHandle *cth;
806 cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle);
809 GNUNET_CRYPTO_ecdsa_key_get_public (&cth->identity, &cth->identity_pub);
810 cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
811 cth->ticket = *ticket;
813 cth->cb_cls = cb_cls;
815 GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof (uint64_t));
816 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for AuthZ info under %s\n",
818 cth->lookup_start_time = GNUNET_TIME_absolute_get ();
819 cth->lookup_request = GNUNET_GNS_lookup (
820 gns, label, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF,
821 GNUNET_GNS_LO_DEFAULT, &lookup_authz_cb, cth);
827 RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth)
834 /*******************************
836 *******************************/
839 * Cleanup ticket consume handle
840 * @param handle the handle to clean up
843 cleanup_issue_handle (struct TicketIssueHandle *handle)
845 if (NULL != handle->ns_qe)
846 GNUNET_NAMESTORE_cancel (handle->ns_qe);
847 GNUNET_free (handle);
852 store_ticket_issue_cont (void *cls, int32_t success, const char *emsg)
854 struct TicketIssueHandle *handle = cls;
856 handle->ns_qe = NULL;
857 if (GNUNET_SYSERR == success) {
858 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_SYSERR,
859 "Error storing AuthZ ticket in GNS");
862 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_OK, NULL);
863 cleanup_issue_handle (handle);
868 issue_ticket (struct TicketIssueHandle *ih)
870 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
871 struct GNUNET_GNSRECORD_Data *attrs_record;
876 for (le = ih->attrs->list_head; NULL != le; le = le->next)
880 GNUNET_malloc (list_len * sizeof (struct GNUNET_GNSRECORD_Data));
882 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
883 attrs_record[i].data = &le->claim->id;
884 attrs_record[i].data_size = sizeof (le->claim->id);
885 attrs_record[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
886 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF;
887 attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
890 attrs_record[i].data = &ih->ticket;
891 attrs_record[i].data_size = sizeof (struct GNUNET_RECLAIM_Ticket);
892 attrs_record[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
893 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET;
894 attrs_record[i].flags =
895 GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
898 GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof (uint64_t));
900 ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &ih->identity, label,
901 list_len, attrs_record,
902 &store_ticket_issue_cont, ih);
903 GNUNET_free (attrs_record);
909 RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
910 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
911 const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
912 RECLAIM_TICKETS_TicketResult cb, void *cb_cls)
914 struct TicketIssueHandle *tih;
915 tih = GNUNET_new (struct TicketIssueHandle);
917 tih->cb_cls = cb_cls;
918 tih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
919 tih->identity = *identity;
920 GNUNET_CRYPTO_ecdsa_key_get_public (identity, &tih->ticket.identity);
922 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
923 tih->ticket.audience = *audience;
927 /************************************
929 ************************************/
932 cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter)
934 if (NULL != iter->ns_it)
935 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
941 collect_tickets_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
942 const char *label, unsigned int rd_count,
943 const struct GNUNET_GNSRECORD_Data *rd)
945 struct RECLAIM_TICKETS_Iterator *iter = cls;
947 for (int i = 0; i < rd_count; i++) {
948 if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET != rd[i].record_type)
950 iter->cb (iter->cb_cls, (struct GNUNET_RECLAIM_Ticket *)rd[i].data);
953 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
958 collect_tickets_finished_cb (void *cls)
960 struct RECLAIM_TICKETS_Iterator *iter = cls;
962 iter->cb (iter->cb_cls, NULL);
968 collect_tickets_error_cb (void *cls)
970 struct RECLAIM_TICKETS_Iterator *iter = cls;
972 iter->cb (iter->cb_cls, NULL);
978 RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter)
980 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
985 RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter)
987 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
992 struct RECLAIM_TICKETS_Iterator *
993 RECLAIM_TICKETS_iteration_start (
994 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
995 RECLAIM_TICKETS_TicketIter cb, void *cb_cls)
997 struct RECLAIM_TICKETS_Iterator *iter;
999 iter = GNUNET_new (struct RECLAIM_TICKETS_Iterator);
1001 iter->cb_cls = cb_cls;
1002 iter->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
1003 nsh, identity, &collect_tickets_error_cb, iter, &collect_tickets_cb, iter,
1004 &collect_tickets_finished_cb, iter);
1010 RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
1012 // Connect to identity and namestore services
1013 nsh = GNUNET_NAMESTORE_connect (c);
1015 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1016 "error connecting to namestore");
1017 return GNUNET_SYSERR;
1019 gns = GNUNET_GNS_connect (c);
1021 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1022 return GNUNET_SYSERR;
1024 stats = GNUNET_STATISTICS_create ("reclaim", c);
1029 RECLAIM_TICKETS_deinit (void)
1032 GNUNET_NAMESTORE_disconnect (nsh);
1035 GNUNET_GNS_disconnect (gns);
1037 if (NULL != stats) {
1038 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);