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 {
37 struct GNUNET_RECLAIM_Ticket ticket;
42 struct GNUNET_GNS_LookupRequest *lookup_request;
47 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
52 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
57 struct ParallelLookup *parallel_lookups_head;
62 struct ParallelLookup *parallel_lookups_tail;
67 struct GNUNET_SCHEDULER_Task *kill_task;
72 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
77 struct GNUNET_TIME_Absolute lookup_start_time;
82 RECLAIM_TICKETS_ConsumeCallback cb;
91 * Handle for a parallel GNS lookup job
93 struct ParallelLookup {
95 struct ParallelLookup *next;
98 struct ParallelLookup *prev;
100 /* The GNS request */
101 struct GNUNET_GNS_LookupRequest *lookup_request;
103 /* The handle the return to */
104 struct RECLAIM_TICKETS_ConsumeHandle *handle;
109 struct GNUNET_TIME_Absolute lookup_start_time;
111 /* The label to look up */
117 * A reference to a ticket stored in GNS
119 struct TicketReference {
123 struct TicketReference *next;
128 struct TicketReference *prev;
133 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
138 struct GNUNET_RECLAIM_Ticket ticket;
143 * Ticket issue request handle
145 struct TicketIssueHandle {
147 * Attributes to issue
149 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
154 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
159 struct GNUNET_RECLAIM_Ticket ticket;
164 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
169 RECLAIM_TICKETS_TicketResult cb;
180 struct RECLAIM_TICKETS_Iterator {
182 * Namestore queue entry
184 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
189 RECLAIM_TICKETS_TicketIter cb;
198 struct RevokedAttributeEntry {
202 struct RevokedAttributeEntry *next;
207 struct RevokedAttributeEntry *prev;
210 * Old ID of the attribute
215 * New ID of the attribute
221 struct TicketRecordsEntry {
225 struct TicketRecordsEntry *next;
230 struct TicketRecordsEntry *prev;
235 unsigned int rd_count;
254 * Ticket revocation request handle
256 struct RECLAIM_TICKETS_RevokeHandle {
260 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
265 RECLAIM_TICKETS_RevokeCallback cb;
275 struct GNUNET_RECLAIM_Ticket ticket;
280 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
285 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
290 struct RevokedAttributeEntry *attrs_head;
295 struct RevokedAttributeEntry *attrs_tail;
298 * Current attribute to move
300 struct RevokedAttributeEntry *move_attr;
303 * Number of attributes in ticket
305 unsigned int ticket_attrs;
310 struct TicketRecordsEntry *tickets_to_update_head;
315 struct TicketRecordsEntry *tickets_to_update_tail;
319 /* Namestore handle */
320 static struct GNUNET_NAMESTORE_Handle *nsh;
323 static struct GNUNET_GNS_Handle *gns;
325 /* Handle to the statistics service */
326 static struct GNUNET_STATISTICS_Handle *stats;
329 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rh);
332 move_attrs_cont (void *cls)
334 move_attrs ((struct RECLAIM_TICKETS_RevokeHandle *)cls);
338 * Cleanup revoke handle
340 * @param rh the ticket revocation handle
343 cleanup_rvk (struct RECLAIM_TICKETS_RevokeHandle *rh)
345 struct RevokedAttributeEntry *ae;
346 struct TicketRecordsEntry *le;
347 if (NULL != rh->ns_qe)
348 GNUNET_NAMESTORE_cancel (rh->ns_qe);
349 if (NULL != rh->ns_it)
350 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
351 while (NULL != (ae = rh->attrs_head)) {
352 GNUNET_CONTAINER_DLL_remove (rh->attrs_head, rh->attrs_tail, ae);
355 while (NULL != (le = rh->tickets_to_update_head)) {
356 GNUNET_CONTAINER_DLL_remove (rh->tickets_to_update_head,
357 rh->tickets_to_update_head, le);
358 if (NULL != le->data)
359 GNUNET_free (le->data);
360 if (NULL != le->label)
361 GNUNET_free (le->label);
368 del_attr_finished (void *cls, int32_t success, const char *emsg)
370 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
372 if (GNUNET_SYSERR == success) {
373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error removing attribute: %s\n",
375 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
379 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Continuing\n");
380 rvk->move_attr = rvk->move_attr->next;
381 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
385 move_attr_finished (void *cls, int32_t success, const char *emsg)
387 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
390 if (GNUNET_SYSERR == success) {
391 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error moving attribute: %s\n", emsg);
392 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
396 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
398 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Removing attribute %s\n", label);
399 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, label, 0,
400 NULL, &del_attr_finished, rvk);
405 rvk_move_attr_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
406 const char *label, unsigned int rd_count,
407 const struct GNUNET_GNSRECORD_Data *rd)
409 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
410 struct RevokedAttributeEntry *le;
414 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
415 "The attribute %s no longer exists!\n", label);
417 rvk->move_attr = le->next;
418 GNUNET_CONTAINER_DLL_remove (rvk->attrs_head, rvk->attrs_tail, le);
420 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
423 /** find a new place for this attribute **/
424 rvk->move_attr->new_id =
425 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
426 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
428 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding attribute %s\n", new_label);
429 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, new_label,
430 1, rd, &move_attr_finished, rvk);
431 GNUNET_free (new_label);
436 rvk_ticket_update (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
437 const char *label, unsigned int rd_count,
438 const struct GNUNET_GNSRECORD_Data *rd)
440 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
441 struct TicketRecordsEntry *le;
442 struct RevokedAttributeEntry *ae;
443 int has_changed = GNUNET_NO;
445 /** Let everything point to the old record **/
446 for (int i = 0; i < rd_count; i++) {
447 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
449 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next) {
450 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
452 has_changed = GNUNET_YES;
455 if (GNUNET_YES == has_changed)
458 if (GNUNET_YES == has_changed) {
459 le = GNUNET_new (struct TicketRecordsEntry);
460 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
461 le->data = GNUNET_malloc (le->data_size);
462 le->rd_count = rd_count;
463 le->label = GNUNET_strdup (label);
464 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
465 GNUNET_CONTAINER_DLL_insert (rvk->tickets_to_update_head,
466 rvk->tickets_to_update_tail, le);
468 GNUNET_NAMESTORE_zone_iterator_next (rvk->ns_it, 1);
473 process_tickets (void *cls);
477 ticket_processed (void *cls, int32_t success, const char *emsg)
479 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
481 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
485 process_tickets (void *cls)
487 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
488 struct TicketRecordsEntry *le;
489 struct RevokedAttributeEntry *ae;
490 if (NULL == rvk->tickets_to_update_head) {
491 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
492 "Finished updatding tickets, success\n");
493 rvk->cb (rvk->cb_cls, GNUNET_OK);
497 le = rvk->tickets_to_update_head;
498 GNUNET_CONTAINER_DLL_remove (rvk->tickets_to_update_head,
499 rvk->tickets_to_update_tail, le);
500 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
501 GNUNET_GNSRECORD_records_deserialize (le->data_size, le->data, le->rd_count,
503 for (int i = 0; i < le->rd_count; i++) {
504 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
506 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next) {
507 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
509 rd[i].data = &ae->new_id;
512 rvk->ns_qe = GNUNET_NAMESTORE_records_store (
513 nsh, &rvk->identity, le->label, le->rd_count, rd, &ticket_processed, rvk);
514 GNUNET_free (le->label);
515 GNUNET_free (le->data);
520 rvk_ticket_update_finished (void *cls)
522 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
524 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
529 rvk_ns_iter_err (void *cls)
531 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
533 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
534 "Namestore error on revocation (id=%" PRIu64 "\n",
535 rvk->move_attr->old_id);
536 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
542 rvk_ns_err (void *cls)
544 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
546 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
547 "Namestore error on revocation (id=%" PRIu64 "\n",
548 rvk->move_attr->old_id);
549 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
555 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
559 if (NULL == rvk->move_attr) {
560 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Finished moving attributes\n");
561 rvk->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
562 nsh, &rvk->identity, &rvk_ns_iter_err, rvk, &rvk_ticket_update, rvk,
563 &rvk_ticket_update_finished, rvk);
566 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
568 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Moving attribute %s\n", label);
570 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (
571 nsh, &rvk->identity, label, &rvk_ns_err, rvk, &rvk_move_attr_cb, rvk);
577 remove_ticket_cont (void *cls, int32_t success, const char *emsg)
579 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
581 if (GNUNET_SYSERR == success) {
582 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
583 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
587 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted ticket\n");
588 if (0 == rvk->ticket_attrs) {
589 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
590 "No attributes to move... strange\n");
591 rvk->cb (rvk->cb_cls, GNUNET_OK);
595 rvk->move_attr = rvk->attrs_head;
601 revoke_attrs_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
602 const char *label, unsigned int rd_count,
603 const struct GNUNET_GNSRECORD_Data *rd)
606 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
607 struct RevokedAttributeEntry *le;
609 for (int i = 0; i < rd_count; i++) {
610 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
612 le = GNUNET_new (struct RevokedAttributeEntry);
613 le->old_id = *((uint64_t *)rd[i].data);
614 GNUNET_CONTAINER_DLL_insert (rvk->attrs_head, rvk->attrs_tail, le);
618 /** Now, remove ticket **/
619 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, label, 0,
620 NULL, &remove_ticket_cont, rvk);
625 rvk_attrs_err_cb (void *cls)
627 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
628 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
633 struct RECLAIM_TICKETS_RevokeHandle *
634 RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket,
635 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
636 RECLAIM_TICKETS_RevokeCallback cb, void *cb_cls)
638 struct RECLAIM_TICKETS_RevokeHandle *rvk;
641 rvk = GNUNET_new (struct RECLAIM_TICKETS_RevokeHandle);
643 rvk->cb_cls = cb_cls;
644 rvk->identity = *identity;
645 rvk->ticket = *ticket;
646 GNUNET_CRYPTO_ecdsa_key_get_public (&rvk->identity, &rvk->ticket.identity);
647 /** Get shared attributes **/
648 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof (uint64_t));
650 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (
651 nsh, identity, label, &rvk_attrs_err_cb, rvk, &revoke_attrs_cb, rvk);
657 RECLAIM_TICKETS_revoke_cancel (struct RECLAIM_TICKETS_RevokeHandle *rh)
661 /*******************************
663 *******************************/
666 * Cleanup ticket consume handle
667 * @param cth the handle to clean up
670 cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth)
672 struct ParallelLookup *lu;
673 struct ParallelLookup *tmp;
674 if (NULL != cth->lookup_request)
675 GNUNET_GNS_lookup_cancel (cth->lookup_request);
676 for (lu = cth->parallel_lookups_head; NULL != lu;) {
677 GNUNET_GNS_lookup_cancel (lu->lookup_request);
678 GNUNET_free (lu->label);
680 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
681 cth->parallel_lookups_tail, lu);
686 if (NULL != cth->attrs)
687 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (cth->attrs);
693 process_parallel_lookup_result (void *cls, uint32_t rd_count,
694 const struct GNUNET_GNSRECORD_Data *rd)
696 struct ParallelLookup *parallel_lookup = cls;
697 struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle;
698 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
699 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parallel lookup finished (count=%u)\n",
702 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
703 cth->parallel_lookups_tail, parallel_lookup);
704 GNUNET_free (parallel_lookup->label);
706 GNUNET_STATISTICS_update (
707 stats, "attribute_lookup_time_total",
708 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time)
711 GNUNET_STATISTICS_update (stats, "attribute_lookups_count", 1, GNUNET_YES);
714 GNUNET_free (parallel_lookup);
716 GNUNET_break (0); // TODO
717 if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR) {
718 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
720 GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
721 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, cth->attrs->list_tail,
724 if (NULL != cth->parallel_lookups_head)
725 return; // Wait for more
726 /* Else we are done */
728 GNUNET_SCHEDULER_cancel (cth->kill_task);
729 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
735 abort_parallel_lookups (void *cls)
737 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
738 struct ParallelLookup *lu;
739 struct ParallelLookup *tmp;
741 cth->kill_task = NULL;
742 for (lu = cth->parallel_lookups_head; NULL != lu;) {
743 GNUNET_GNS_lookup_cancel (lu->lookup_request);
744 GNUNET_free (lu->label);
746 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
747 cth->parallel_lookups_tail, lu);
751 cth->cb (cth->cb_cls, NULL, NULL, GNUNET_SYSERR, "Aborted");
756 lookup_authz_cb (void *cls, uint32_t rd_count,
757 const struct GNUNET_GNSRECORD_Data *rd)
759 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
760 struct ParallelLookup *parallel_lookup;
763 cth->lookup_request = NULL;
765 GNUNET_STATISTICS_update (
766 stats, "reclaim_authz_lookup_time_total",
767 GNUNET_TIME_absolute_get_duration (cth->lookup_start_time).rel_value_us,
769 GNUNET_STATISTICS_update (stats, "reclaim_authz_lookups_count", 1,
772 for (int i = 0; i < rd_count; i++) {
773 lbl = GNUNET_STRINGS_data_to_string_alloc (rd[i].data, rd[i].data_size);
774 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Attribute ref found %s\n", lbl);
775 parallel_lookup = GNUNET_new (struct ParallelLookup);
776 parallel_lookup->handle = cth;
777 parallel_lookup->label = lbl;
778 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get ();
779 parallel_lookup->lookup_request = GNUNET_GNS_lookup (
780 gns, lbl, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
781 GNUNET_GNS_LO_DEFAULT, &process_parallel_lookup_result,
783 GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head,
784 cth->parallel_lookups_tail, parallel_lookup);
786 cth->kill_task = GNUNET_SCHEDULER_add_delayed (
787 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3),
788 &abort_parallel_lookups, cth);
792 struct RECLAIM_TICKETS_ConsumeHandle *
793 RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id,
794 const struct GNUNET_RECLAIM_Ticket *ticket,
795 RECLAIM_TICKETS_ConsumeCallback cb, void *cb_cls)
797 struct RECLAIM_TICKETS_ConsumeHandle *cth;
799 cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle);
802 GNUNET_CRYPTO_ecdsa_key_get_public (&cth->identity, &cth->identity_pub);
803 cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
804 cth->ticket = *ticket;
806 cth->cb_cls = cb_cls;
808 GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof (uint64_t));
809 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for AuthZ info under %s\n",
811 cth->lookup_start_time = GNUNET_TIME_absolute_get ();
812 cth->lookup_request = GNUNET_GNS_lookup (
813 gns, label, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF,
814 GNUNET_GNS_LO_DEFAULT, &lookup_authz_cb, cth);
820 RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth)
827 /*******************************
829 *******************************/
832 * Cleanup ticket consume handle
833 * @param handle the handle to clean up
836 cleanup_issue_handle (struct TicketIssueHandle *handle)
838 if (NULL != handle->ns_qe)
839 GNUNET_NAMESTORE_cancel (handle->ns_qe);
840 GNUNET_free (handle);
845 store_ticket_issue_cont (void *cls, int32_t success, const char *emsg)
847 struct TicketIssueHandle *handle = cls;
849 handle->ns_qe = NULL;
850 if (GNUNET_SYSERR == success) {
851 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_SYSERR,
852 "Error storing AuthZ ticket in GNS");
855 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_OK, NULL);
856 cleanup_issue_handle (handle);
861 issue_ticket (struct TicketIssueHandle *ih)
863 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
864 struct GNUNET_GNSRECORD_Data *attrs_record;
869 for (le = ih->attrs->list_head; NULL != le; le = le->next)
873 GNUNET_malloc (list_len * sizeof (struct GNUNET_GNSRECORD_Data));
875 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
876 attrs_record[i].data = &le->claim->id;
877 attrs_record[i].data_size = sizeof (le->claim->id);
878 attrs_record[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
879 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF;
880 attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
883 attrs_record[i].data = &ih->ticket;
884 attrs_record[i].data_size = sizeof (struct GNUNET_RECLAIM_Ticket);
885 attrs_record[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
886 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET;
887 attrs_record[i].flags =
888 GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
891 GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof (uint64_t));
893 ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &ih->identity, label,
894 list_len, attrs_record,
895 &store_ticket_issue_cont, ih);
896 GNUNET_free (attrs_record);
902 RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
903 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
904 const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
905 RECLAIM_TICKETS_TicketResult cb, void *cb_cls)
907 struct TicketIssueHandle *tih;
908 tih = GNUNET_new (struct TicketIssueHandle);
910 tih->cb_cls = cb_cls;
911 tih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
912 tih->identity = *identity;
913 GNUNET_CRYPTO_ecdsa_key_get_public (identity, &tih->ticket.identity);
915 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
916 tih->ticket.audience = *audience;
920 /************************************
922 ************************************/
925 cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter)
927 if (NULL != iter->ns_it)
928 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
934 collect_tickets_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
935 const char *label, unsigned int rd_count,
936 const struct GNUNET_GNSRECORD_Data *rd)
938 struct RECLAIM_TICKETS_Iterator *iter = cls;
940 for (int i = 0; i < rd_count; i++) {
941 if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET != rd[i].record_type)
943 iter->cb (iter->cb_cls, (struct GNUNET_RECLAIM_Ticket *)rd[i].data);
946 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
951 collect_tickets_finished_cb (void *cls)
953 struct RECLAIM_TICKETS_Iterator *iter = cls;
955 iter->cb (iter->cb_cls, NULL);
961 collect_tickets_error_cb (void *cls)
963 struct RECLAIM_TICKETS_Iterator *iter = cls;
965 iter->cb (iter->cb_cls, NULL);
971 RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter)
973 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
978 RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter)
980 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
985 struct RECLAIM_TICKETS_Iterator *
986 RECLAIM_TICKETS_iteration_start (
987 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
988 RECLAIM_TICKETS_TicketIter cb, void *cb_cls)
990 struct RECLAIM_TICKETS_Iterator *iter;
992 iter = GNUNET_new (struct RECLAIM_TICKETS_Iterator);
994 iter->cb_cls = cb_cls;
995 iter->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
996 nsh, identity, &collect_tickets_error_cb, iter, &collect_tickets_cb, iter,
997 &collect_tickets_finished_cb, iter);
1003 RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
1005 // Connect to identity and namestore services
1006 nsh = GNUNET_NAMESTORE_connect (c);
1008 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1009 "error connecting to namestore");
1010 return GNUNET_SYSERR;
1012 gns = GNUNET_GNS_connect (c);
1014 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1015 return GNUNET_SYSERR;
1017 stats = GNUNET_STATISTICS_create ("reclaim", c);
1022 RECLAIM_TICKETS_deinit (void)
1025 GNUNET_NAMESTORE_disconnect (nsh);
1028 GNUNET_GNS_disconnect (gns);
1030 if (NULL != stats) {
1031 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);