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
28 #include "gnunet-service-reclaim_tickets.h"
30 #define DEFAULT_TICKET_REFRESH_INTERVAL GNUNET_TIME_UNIT_HOURS
32 struct ParallelLookup;
36 * A reference to a ticket stored in GNS
38 struct TicketReference
43 struct TicketReference *next;
48 struct TicketReference *prev;
53 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
58 struct GNUNET_RECLAIM_Ticket ticket;
62 struct RECLAIM_TICKETS_ConsumeHandle
67 struct GNUNET_RECLAIM_Ticket ticket;
72 struct GNUNET_GNS_LookupRequest *lookup_request;
77 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
82 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
87 struct ParallelLookup *parallel_lookups_head;
92 struct ParallelLookup *parallel_lookups_tail;
97 struct GNUNET_SCHEDULER_Task *kill_task;
102 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
107 struct GNUNET_TIME_Absolute lookup_start_time;
112 RECLAIM_TICKETS_ConsumeCallback cb;
121 * Handle for a parallel GNS lookup job
123 struct ParallelLookup
126 struct ParallelLookup *next;
129 struct ParallelLookup *prev;
131 /* The GNS request */
132 struct GNUNET_GNS_LookupRequest *lookup_request;
134 /* The handle the return to */
135 struct RECLAIM_TICKETS_ConsumeHandle *handle;
140 struct GNUNET_TIME_Absolute lookup_start_time;
142 /* The label to look up */
148 * Ticket issue request handle
150 struct TicketIssueHandle
153 * Attributes to issue
155 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
160 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
165 struct GNUNET_RECLAIM_Ticket ticket;
170 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
175 RECLAIM_TICKETS_TicketResult cb;
186 struct RECLAIM_TICKETS_Iterator
189 * Namestore queue entry
191 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
196 RECLAIM_TICKETS_TicketIter cb;
205 struct RevokedAttributeEntry
210 struct RevokedAttributeEntry *next;
215 struct RevokedAttributeEntry *prev;
218 * Old ID of the attribute
223 * New ID of the attribute
230 * Ticket revocation request handle
232 struct RECLAIM_TICKETS_RevokeHandle
237 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
242 RECLAIM_TICKETS_RevokeCallback cb;
252 struct GNUNET_RECLAIM_Ticket ticket;
257 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
262 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
267 struct RevokedAttributeEntry *attrs_head;
272 struct RevokedAttributeEntry *attrs_tail;
275 * Current attribute to move
277 struct RevokedAttributeEntry *move_attr;
280 * Number of attributes in ticket
282 unsigned int ticket_attrs;
287 struct TicketRecordsEntry *tickets_to_update_head;
292 struct TicketRecordsEntry *tickets_to_update_tail;
296 * Ticket expiration interval
298 static struct GNUNET_TIME_Relative ticket_refresh_interval;
300 /* Namestore handle */
301 static struct GNUNET_NAMESTORE_Handle *nsh;
304 static struct GNUNET_GNS_Handle *gns;
306 /* Handle to the statistics service */
307 static struct GNUNET_STATISTICS_Handle *stats;
310 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rh);
313 move_attrs_cont (void *cls)
315 move_attrs ((struct RECLAIM_TICKETS_RevokeHandle *) cls);
319 * Cleanup revoke handle
321 * @param rh the ticket revocation handle
324 cleanup_rvk (struct RECLAIM_TICKETS_RevokeHandle *rh)
326 struct RevokedAttributeEntry *ae;
327 struct TicketRecordsEntry *le;
328 if (NULL != rh->ns_qe)
329 GNUNET_NAMESTORE_cancel (rh->ns_qe);
330 if (NULL != rh->ns_it)
331 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
332 while (NULL != (ae = rh->attrs_head))
334 GNUNET_CONTAINER_DLL_remove (rh->attrs_head, rh->attrs_tail, ae);
337 while (NULL != (le = rh->tickets_to_update_head))
339 GNUNET_CONTAINER_DLL_remove (rh->tickets_to_update_head,
340 rh->tickets_to_update_head,
342 if (NULL != le->data)
343 GNUNET_free (le->data);
344 if (NULL != le->label)
345 GNUNET_free (le->label);
352 del_attr_finished (void *cls, int32_t success, const char *emsg)
354 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
356 if (GNUNET_SYSERR == success)
358 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
359 "Error removing attribute: %s\n",
361 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
365 rvk->move_attr = rvk->move_attr->next;
366 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
370 move_attr_finished (void *cls, int32_t success, const char *emsg)
372 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
375 if (GNUNET_SYSERR == success)
377 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error moving attribute: %s\n", emsg);
378 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
382 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
384 GNUNET_assert (NULL != label);
385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing attribute %s\n", label);
386 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
398 rvk_move_attr_cb (void *cls,
399 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
401 unsigned int rd_count,
402 const struct GNUNET_GNSRECORD_Data *rd)
404 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
405 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
406 struct GNUNET_GNSRECORD_Data new_rd;
407 struct RevokedAttributeEntry *le;
413 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
414 "The attribute %s no longer exists!\n",
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);
427 claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
428 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
429 "Attribute to update: Name=%s, ID=%" PRIu64 "\n",
432 claim->id = rvk->move_attr->new_id;
433 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
434 attr_data = GNUNET_malloc (rd->data_size);
435 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
436 new_rd.data = attr_data;
437 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
440 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
447 GNUNET_free (new_label);
449 GNUNET_free (attr_data);
454 rvk_ticket_update (void *cls,
455 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
457 unsigned int rd_count,
458 const struct GNUNET_GNSRECORD_Data *rd)
460 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
461 struct TicketRecordsEntry *le;
462 struct RevokedAttributeEntry *ae;
463 int has_changed = GNUNET_NO;
465 /** Let everything point to the old record **/
466 for (int i = 0; i < rd_count; i++)
468 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
470 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next)
472 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
474 has_changed = GNUNET_YES;
477 if (GNUNET_YES == has_changed)
480 if (GNUNET_YES == has_changed)
482 le = GNUNET_new (struct TicketRecordsEntry);
483 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
484 le->data = GNUNET_malloc (le->data_size);
485 le->rd_count = rd_count;
486 le->label = GNUNET_strdup (label);
487 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
488 GNUNET_CONTAINER_DLL_insert (rvk->tickets_to_update_head,
489 rvk->tickets_to_update_tail,
492 GNUNET_NAMESTORE_zone_iterator_next (rvk->ns_it, 1);
497 process_tickets (void *cls);
501 ticket_processed (void *cls, int32_t success, const char *emsg)
503 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
505 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
509 process_tickets (void *cls)
511 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
512 struct TicketRecordsEntry *le;
513 struct RevokedAttributeEntry *ae;
514 if (NULL == rvk->tickets_to_update_head)
516 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
517 "Finished updatding tickets, success\n");
518 rvk->cb (rvk->cb_cls, GNUNET_OK);
522 le = rvk->tickets_to_update_head;
523 GNUNET_CONTAINER_DLL_remove (rvk->tickets_to_update_head,
524 rvk->tickets_to_update_tail,
526 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
527 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
532 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
533 "Unable to deserialize ticket record(s)\n");
534 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
538 for (int i = 0; i < le->rd_count; i++)
540 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
542 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next)
544 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
546 rd[i].data = &ae->new_id;
549 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
556 GNUNET_free (le->label);
557 GNUNET_free (le->data);
562 rvk_ticket_update_finished (void *cls)
564 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
566 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
571 rvk_ns_iter_err (void *cls)
573 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
575 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
576 "Namestore error on revocation (id=%" PRIu64 "\n",
577 rvk->move_attr->old_id);
578 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
584 rvk_ns_err (void *cls)
586 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
588 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
589 "Namestore error on revocation (id=%" PRIu64 "\n",
590 rvk->move_attr->old_id);
591 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
597 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
601 if (NULL == rvk->move_attr)
603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished moving attributes\n");
605 GNUNET_NAMESTORE_zone_iteration_start (nsh,
611 &rvk_ticket_update_finished,
615 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
617 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label);
619 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
631 remove_ticket_cont (void *cls, int32_t success, const char *emsg)
633 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
635 if (GNUNET_SYSERR == success)
637 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
638 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
642 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted ticket\n");
643 if (0 == rvk->ticket_attrs)
645 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
646 "No attributes to move... strange\n");
647 rvk->cb (rvk->cb_cls, GNUNET_OK);
651 rvk->move_attr = rvk->attrs_head;
657 revoke_attrs_cb (void *cls,
658 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
660 unsigned int rd_count,
661 const struct GNUNET_GNSRECORD_Data *rd)
664 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
665 struct RevokedAttributeEntry *le;
667 for (int i = 0; i < rd_count; i++)
669 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
671 le = GNUNET_new (struct RevokedAttributeEntry);
672 le->old_id = *((uint64_t *) rd[i].data);
673 GNUNET_CONTAINER_DLL_insert (rvk->attrs_head, rvk->attrs_tail, le);
677 /** Now, remove ticket **/
678 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
689 rvk_attrs_err_cb (void *cls)
691 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
692 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
697 struct RECLAIM_TICKETS_RevokeHandle *
698 RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket,
699 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
700 RECLAIM_TICKETS_RevokeCallback cb,
703 struct RECLAIM_TICKETS_RevokeHandle *rvk;
706 rvk = GNUNET_new (struct RECLAIM_TICKETS_RevokeHandle);
708 rvk->cb_cls = cb_cls;
709 rvk->identity = *identity;
710 rvk->ticket = *ticket;
711 GNUNET_CRYPTO_ecdsa_key_get_public (&rvk->identity, &rvk->ticket.identity);
712 /** Get shared attributes **/
713 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof (uint64_t));
714 GNUNET_assert (NULL != label);
715 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
728 RECLAIM_TICKETS_revoke_cancel (struct RECLAIM_TICKETS_RevokeHandle *rh)
732 /*******************************
734 *******************************/
737 * Cleanup ticket consume handle
738 * @param cth the handle to clean up
741 cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth)
743 struct ParallelLookup *lu;
744 if (NULL != cth->lookup_request)
745 GNUNET_GNS_lookup_cancel (cth->lookup_request);
746 if (NULL != cth->kill_task)
747 GNUNET_SCHEDULER_cancel (cth->kill_task);
748 while (NULL != (lu = cth->parallel_lookups_head))
750 if (NULL != lu->lookup_request)
751 GNUNET_GNS_lookup_cancel (lu->lookup_request);
752 GNUNET_free_non_null (lu->label);
753 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
754 cth->parallel_lookups_tail,
759 if (NULL != cth->attrs)
760 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (cth->attrs);
766 process_parallel_lookup_result (void *cls,
768 const struct GNUNET_GNSRECORD_Data *rd)
770 struct ParallelLookup *parallel_lookup = cls;
771 struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle;
772 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
773 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
774 "Parallel lookup finished (count=%u)\n",
777 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
778 cth->parallel_lookups_tail,
780 GNUNET_free (parallel_lookup->label);
782 GNUNET_STATISTICS_update (stats,
783 "attribute_lookup_time_total",
784 GNUNET_TIME_absolute_get_duration (
785 parallel_lookup->lookup_start_time)
788 GNUNET_STATISTICS_update (stats, "attribute_lookups_count", 1, GNUNET_YES);
791 GNUNET_free (parallel_lookup);
793 GNUNET_break (0); // TODO
794 if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR)
796 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
798 GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
799 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
800 cth->attrs->list_tail,
803 if (NULL != cth->parallel_lookups_head)
804 return; // Wait for more
805 /* Else we are done */
807 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
813 abort_parallel_lookups (void *cls)
815 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
816 struct ParallelLookup *lu;
817 struct ParallelLookup *tmp;
819 cth->kill_task = NULL;
820 for (lu = cth->parallel_lookups_head; NULL != lu;)
822 GNUNET_GNS_lookup_cancel (lu->lookup_request);
823 GNUNET_free (lu->label);
825 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
826 cth->parallel_lookups_tail,
831 cth->cb (cth->cb_cls, NULL, NULL, GNUNET_SYSERR, "Aborted");
836 lookup_authz_cb (void *cls,
838 const struct GNUNET_GNSRECORD_Data *rd)
840 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
841 struct ParallelLookup *parallel_lookup;
844 cth->lookup_request = NULL;
846 GNUNET_STATISTICS_update (stats,
847 "reclaim_authz_lookup_time_total",
848 GNUNET_TIME_absolute_get_duration (
849 cth->lookup_start_time)
852 GNUNET_STATISTICS_update (stats,
853 "reclaim_authz_lookups_count",
857 for (int i = 0; i < rd_count; i++)
859 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
861 lbl = GNUNET_STRINGS_data_to_string_alloc (rd[i].data, rd[i].data_size);
862 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute ref found %s\n", lbl);
863 parallel_lookup = GNUNET_new (struct ParallelLookup);
864 parallel_lookup->handle = cth;
865 parallel_lookup->label = lbl;
866 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get ();
867 parallel_lookup->lookup_request =
868 GNUNET_GNS_lookup (gns,
870 &cth->ticket.identity,
871 GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
872 GNUNET_GNS_LO_DEFAULT,
873 &process_parallel_lookup_result,
875 GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head,
876 cth->parallel_lookups_tail,
879 if (NULL != cth->parallel_lookups_head)
881 cth->kill_task = GNUNET_SCHEDULER_add_delayed (
882 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3),
883 &abort_parallel_lookups,
887 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
892 struct RECLAIM_TICKETS_ConsumeHandle *
893 RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id,
894 const struct GNUNET_RECLAIM_Ticket *ticket,
895 RECLAIM_TICKETS_ConsumeCallback cb,
898 struct RECLAIM_TICKETS_ConsumeHandle *cth;
900 cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle);
903 GNUNET_CRYPTO_ecdsa_key_get_public (&cth->identity, &cth->identity_pub);
904 cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
905 cth->ticket = *ticket;
907 cth->cb_cls = cb_cls;
909 GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof (uint64_t));
910 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
911 "Looking for AuthZ info under %s\n",
913 cth->lookup_start_time = GNUNET_TIME_absolute_get ();
914 cth->lookup_request =
915 GNUNET_GNS_lookup (gns,
917 &cth->ticket.identity,
918 GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF,
919 GNUNET_GNS_LO_DEFAULT,
927 RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth)
934 /*******************************
936 *******************************/
939 * Cleanup ticket consume handle
940 * @param handle the handle to clean up
943 cleanup_issue_handle (struct TicketIssueHandle *handle)
945 if (NULL != handle->ns_qe)
946 GNUNET_NAMESTORE_cancel (handle->ns_qe);
947 GNUNET_free (handle);
952 store_ticket_issue_cont (void *cls, int32_t success, const char *emsg)
954 struct TicketIssueHandle *handle = cls;
956 handle->ns_qe = NULL;
957 if (GNUNET_SYSERR == success)
959 handle->cb (handle->cb_cls,
962 "Error storing AuthZ ticket in GNS");
965 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_OK, NULL);
966 cleanup_issue_handle (handle);
971 issue_ticket (struct TicketIssueHandle *ih)
973 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
974 struct GNUNET_GNSRECORD_Data *attrs_record;
979 for (le = ih->attrs->list_head; NULL != le; le = le->next)
983 GNUNET_malloc (list_len * sizeof (struct GNUNET_GNSRECORD_Data));
985 for (le = ih->attrs->list_head; NULL != le; le = le->next)
987 attrs_record[i].data = &le->claim->id;
988 attrs_record[i].data_size = sizeof (le->claim->id);
989 //FIXME: Should this be the attribute expiration time or ticket refresh intv
990 attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us;
991 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF;
992 attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
995 attrs_record[i].data = &ih->ticket;
996 attrs_record[i].data_size = sizeof (struct GNUNET_RECLAIM_Ticket);
997 attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us;
998 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET;
999 attrs_record[i].flags =
1000 GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
1003 GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof (uint64_t));
1005 ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1010 &store_ticket_issue_cont,
1012 GNUNET_free (attrs_record);
1013 GNUNET_free (label);
1018 RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1019 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
1020 const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
1021 RECLAIM_TICKETS_TicketResult cb,
1024 struct TicketIssueHandle *tih;
1025 tih = GNUNET_new (struct TicketIssueHandle);
1027 tih->cb_cls = cb_cls;
1028 tih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
1029 tih->identity = *identity;
1030 GNUNET_CRYPTO_ecdsa_key_get_public (identity, &tih->ticket.identity);
1032 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
1033 tih->ticket.audience = *audience;
1037 /************************************
1039 ************************************/
1042 cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter)
1044 if (NULL != iter->ns_it)
1045 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
1051 collect_tickets_cb (void *cls,
1052 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1054 unsigned int rd_count,
1055 const struct GNUNET_GNSRECORD_Data *rd)
1057 struct RECLAIM_TICKETS_Iterator *iter = cls;
1059 for (int i = 0; i < rd_count; i++)
1061 if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET != rd[i].record_type)
1063 iter->cb (iter->cb_cls, (struct GNUNET_RECLAIM_Ticket *) rd[i].data);
1066 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
1071 collect_tickets_finished_cb (void *cls)
1073 struct RECLAIM_TICKETS_Iterator *iter = cls;
1075 iter->cb (iter->cb_cls, NULL);
1076 cleanup_iter (iter);
1081 collect_tickets_error_cb (void *cls)
1083 struct RECLAIM_TICKETS_Iterator *iter = cls;
1085 iter->cb (iter->cb_cls, NULL);
1086 cleanup_iter (iter);
1091 RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter)
1093 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
1098 RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter)
1100 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
1101 cleanup_iter (iter);
1105 struct RECLAIM_TICKETS_Iterator *
1106 RECLAIM_TICKETS_iteration_start (
1107 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1108 RECLAIM_TICKETS_TicketIter cb,
1111 struct RECLAIM_TICKETS_Iterator *iter;
1113 iter = GNUNET_new (struct RECLAIM_TICKETS_Iterator);
1115 iter->cb_cls = cb_cls;
1117 GNUNET_NAMESTORE_zone_iteration_start (nsh,
1119 &collect_tickets_error_cb,
1121 &collect_tickets_cb,
1123 &collect_tickets_finished_cb,
1130 RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
1132 // Get ticket expiration time (relative) from config
1134 GNUNET_CONFIGURATION_get_value_time (c,
1136 "TICKET_REFRESH_INTERVAL",
1137 &ticket_refresh_interval))
1139 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1140 "Configured refresh interval for tickets: %s\n",
1141 GNUNET_STRINGS_relative_time_to_string (ticket_refresh_interval,
1146 ticket_refresh_interval = DEFAULT_TICKET_REFRESH_INTERVAL;
1148 // Connect to identity and namestore services
1149 nsh = GNUNET_NAMESTORE_connect (c);
1152 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1153 "error connecting to namestore");
1154 return GNUNET_SYSERR;
1156 gns = GNUNET_GNS_connect (c);
1159 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1160 return GNUNET_SYSERR;
1162 stats = GNUNET_STATISTICS_create ("reclaim", c);
1167 RECLAIM_TICKETS_deinit (void)
1170 GNUNET_NAMESTORE_disconnect (nsh);
1173 GNUNET_GNS_disconnect (gns);
1177 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);