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 #define DEFAULT_TICKET_REFRESH_INTERVAL GNUNET_TIME_UNIT_HOURS
33 struct ParallelLookup;
37 * A reference to a ticket stored in GNS
39 struct TicketReference
44 struct TicketReference *next;
49 struct TicketReference *prev;
54 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
59 struct GNUNET_RECLAIM_Ticket ticket;
63 struct RECLAIM_TICKETS_ConsumeHandle
68 struct GNUNET_RECLAIM_Ticket ticket;
73 struct GNUNET_GNS_LookupRequest *lookup_request;
78 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
83 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
88 struct ParallelLookup *parallel_lookups_head;
93 struct ParallelLookup *parallel_lookups_tail;
98 struct GNUNET_SCHEDULER_Task *kill_task;
103 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
108 struct GNUNET_TIME_Absolute lookup_start_time;
113 RECLAIM_TICKETS_ConsumeCallback cb;
122 * Handle for a parallel GNS lookup job
124 struct ParallelLookup
127 struct ParallelLookup *next;
130 struct ParallelLookup *prev;
132 /* The GNS request */
133 struct GNUNET_GNS_LookupRequest *lookup_request;
135 /* The handle the return to */
136 struct RECLAIM_TICKETS_ConsumeHandle *handle;
141 struct GNUNET_TIME_Absolute lookup_start_time;
143 /* The label to look up */
149 * Ticket issue request handle
151 struct TicketIssueHandle
154 * Attributes to issue
156 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
161 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
166 struct GNUNET_RECLAIM_Ticket ticket;
171 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
176 RECLAIM_TICKETS_TicketResult cb;
187 struct RECLAIM_TICKETS_Iterator
190 * Namestore queue entry
192 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
197 RECLAIM_TICKETS_TicketIter cb;
206 struct RevokedAttributeEntry
211 struct RevokedAttributeEntry *next;
216 struct RevokedAttributeEntry *prev;
219 * Old ID of the attribute
224 * New ID of the attribute
231 * Ticket revocation request handle
233 struct RECLAIM_TICKETS_RevokeHandle
238 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
243 RECLAIM_TICKETS_RevokeCallback cb;
253 struct GNUNET_RECLAIM_Ticket ticket;
258 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
263 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
268 struct RevokedAttributeEntry *attrs_head;
273 struct RevokedAttributeEntry *attrs_tail;
276 * Current attribute to move
278 struct RevokedAttributeEntry *move_attr;
281 * Number of attributes in ticket
283 unsigned int ticket_attrs;
288 struct TicketRecordsEntry *tickets_to_update_head;
293 struct TicketRecordsEntry *tickets_to_update_tail;
297 * Ticket expiration interval
299 static struct GNUNET_TIME_Relative ticket_refresh_interval;
301 /* Namestore handle */
302 static struct GNUNET_NAMESTORE_Handle *nsh;
305 static struct GNUNET_GNS_Handle *gns;
307 /* Handle to the statistics service */
308 static struct GNUNET_STATISTICS_Handle *stats;
311 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rh);
314 move_attrs_cont (void *cls)
316 move_attrs ((struct RECLAIM_TICKETS_RevokeHandle *)cls);
320 * Cleanup revoke handle
322 * @param rh the ticket revocation handle
325 cleanup_rvk (struct RECLAIM_TICKETS_RevokeHandle *rh)
327 struct RevokedAttributeEntry *ae;
328 struct TicketRecordsEntry *le;
329 if (NULL != rh->ns_qe)
330 GNUNET_NAMESTORE_cancel (rh->ns_qe);
331 if (NULL != rh->ns_it)
332 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
333 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)) {
338 GNUNET_CONTAINER_DLL_remove (rh->tickets_to_update_head,
339 rh->tickets_to_update_head, le);
340 if (NULL != le->data)
341 GNUNET_free (le->data);
342 if (NULL != le->label)
343 GNUNET_free (le->label);
350 del_attr_finished (void *cls, int32_t success, const char *emsg)
352 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
354 if (GNUNET_SYSERR == success) {
355 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error removing attribute: %s\n",
357 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
361 rvk->move_attr = rvk->move_attr->next;
362 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
366 move_attr_finished (void *cls, int32_t success, const char *emsg)
368 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
371 if (GNUNET_SYSERR == success) {
372 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error moving attribute: %s\n", emsg);
373 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
377 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
379 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing attribute %s\n", label);
380 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, label, 0,
381 NULL, &del_attr_finished, rvk);
386 rvk_move_attr_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
387 const char *label, unsigned int rd_count,
388 const struct GNUNET_GNSRECORD_Data *rd)
390 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
391 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
392 struct GNUNET_GNSRECORD_Data new_rd;
393 struct RevokedAttributeEntry *le;
398 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
399 "The attribute %s no longer exists!\n", label);
401 rvk->move_attr = le->next;
402 GNUNET_CONTAINER_DLL_remove (rvk->attrs_head, rvk->attrs_tail, le);
404 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
407 /** find a new place for this attribute **/
408 rvk->move_attr->new_id =
409 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
411 claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
413 "Attribute to update: Name=%s, ID=%" PRIu64 "\n", claim->name,
415 claim->id = rvk->move_attr->new_id;
416 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
417 attr_data = GNUNET_malloc (rd->data_size);
418 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
419 new_rd.data = attr_data;
420 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
423 rvk->ns_qe = GNUNET_NAMESTORE_records_store (
424 nsh, &rvk->identity, new_label, 1, &new_rd, &move_attr_finished, rvk);
425 GNUNET_free (new_label);
427 GNUNET_free (attr_data);
432 rvk_ticket_update (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
433 const char *label, unsigned int rd_count,
434 const struct GNUNET_GNSRECORD_Data *rd)
436 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
437 struct TicketRecordsEntry *le;
438 struct RevokedAttributeEntry *ae;
439 int has_changed = GNUNET_NO;
441 /** Let everything point to the old record **/
442 for (int i = 0; i < rd_count; i++) {
443 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
445 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next) {
446 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
448 has_changed = GNUNET_YES;
451 if (GNUNET_YES == has_changed)
454 if (GNUNET_YES == has_changed) {
455 le = GNUNET_new (struct TicketRecordsEntry);
456 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
457 le->data = GNUNET_malloc (le->data_size);
458 le->rd_count = rd_count;
459 le->label = GNUNET_strdup (label);
460 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
461 GNUNET_CONTAINER_DLL_insert (rvk->tickets_to_update_head,
462 rvk->tickets_to_update_tail, le);
464 GNUNET_NAMESTORE_zone_iterator_next (rvk->ns_it, 1);
469 process_tickets (void *cls);
473 ticket_processed (void *cls, int32_t success, const char *emsg)
475 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
477 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
481 process_tickets (void *cls)
483 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
484 struct TicketRecordsEntry *le;
485 struct RevokedAttributeEntry *ae;
486 if (NULL == rvk->tickets_to_update_head) {
487 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
488 "Finished updatding tickets, success\n");
489 rvk->cb (rvk->cb_cls, GNUNET_OK);
493 le = rvk->tickets_to_update_head;
494 GNUNET_CONTAINER_DLL_remove (rvk->tickets_to_update_head,
495 rvk->tickets_to_update_tail, le);
496 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
497 GNUNET_GNSRECORD_records_deserialize (le->data_size, le->data, le->rd_count,
499 for (int i = 0; i < le->rd_count; i++) {
500 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
502 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next) {
503 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
505 rd[i].data = &ae->new_id;
508 rvk->ns_qe = GNUNET_NAMESTORE_records_store (
509 nsh, &rvk->identity, le->label, le->rd_count, rd, &ticket_processed, rvk);
510 GNUNET_free (le->label);
511 GNUNET_free (le->data);
516 rvk_ticket_update_finished (void *cls)
518 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
520 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
525 rvk_ns_iter_err (void *cls)
527 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
529 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
530 "Namestore error on revocation (id=%" PRIu64 "\n",
531 rvk->move_attr->old_id);
532 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
538 rvk_ns_err (void *cls)
540 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
542 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
543 "Namestore error on revocation (id=%" PRIu64 "\n",
544 rvk->move_attr->old_id);
545 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
551 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
555 if (NULL == rvk->move_attr) {
556 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished moving attributes\n");
557 rvk->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
558 nsh, &rvk->identity, &rvk_ns_iter_err, rvk, &rvk_ticket_update, rvk,
559 &rvk_ticket_update_finished, rvk);
562 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
564 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label);
566 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (
567 nsh, &rvk->identity, label, &rvk_ns_err, rvk, &rvk_move_attr_cb, rvk);
573 remove_ticket_cont (void *cls, int32_t success, const char *emsg)
575 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
577 if (GNUNET_SYSERR == success) {
578 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
579 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
583 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted ticket\n");
584 if (0 == rvk->ticket_attrs) {
585 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
586 "No attributes to move... strange\n");
587 rvk->cb (rvk->cb_cls, GNUNET_OK);
591 rvk->move_attr = rvk->attrs_head;
597 revoke_attrs_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
598 const char *label, unsigned int rd_count,
599 const struct GNUNET_GNSRECORD_Data *rd)
602 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
603 struct RevokedAttributeEntry *le;
605 for (int i = 0; i < rd_count; i++) {
606 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
608 le = GNUNET_new (struct RevokedAttributeEntry);
609 le->old_id = *((uint64_t *)rd[i].data);
610 GNUNET_CONTAINER_DLL_insert (rvk->attrs_head, rvk->attrs_tail, le);
614 /** Now, remove ticket **/
615 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, label, 0,
616 NULL, &remove_ticket_cont, rvk);
621 rvk_attrs_err_cb (void *cls)
623 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
624 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
629 struct RECLAIM_TICKETS_RevokeHandle *
630 RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket,
631 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
632 RECLAIM_TICKETS_RevokeCallback cb, void *cb_cls)
634 struct RECLAIM_TICKETS_RevokeHandle *rvk;
637 rvk = GNUNET_new (struct RECLAIM_TICKETS_RevokeHandle);
639 rvk->cb_cls = cb_cls;
640 rvk->identity = *identity;
641 rvk->ticket = *ticket;
642 GNUNET_CRYPTO_ecdsa_key_get_public (&rvk->identity, &rvk->ticket.identity);
643 /** Get shared attributes **/
644 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof (uint64_t));
646 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (
647 nsh, identity, label, &rvk_attrs_err_cb, rvk, &revoke_attrs_cb, rvk);
653 RECLAIM_TICKETS_revoke_cancel (struct RECLAIM_TICKETS_RevokeHandle *rh)
657 /*******************************
659 *******************************/
662 * Cleanup ticket consume handle
663 * @param cth the handle to clean up
666 cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth)
668 struct ParallelLookup *lu;
669 if (NULL != cth->lookup_request)
670 GNUNET_GNS_lookup_cancel (cth->lookup_request);
671 if (NULL != cth->kill_task)
672 GNUNET_SCHEDULER_cancel (cth->kill_task);
673 while (NULL != (lu = cth->parallel_lookups_head)) {
674 if (NULL != lu->lookup_request)
675 GNUNET_GNS_lookup_cancel (lu->lookup_request);
676 GNUNET_free_non_null (lu->label);
677 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
678 cth->parallel_lookups_tail, lu);
682 if (NULL != cth->attrs)
683 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (cth->attrs);
689 process_parallel_lookup_result (void *cls, uint32_t rd_count,
690 const struct GNUNET_GNSRECORD_Data *rd)
692 struct ParallelLookup *parallel_lookup = cls;
693 struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle;
694 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
695 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parallel lookup finished (count=%u)\n",
698 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
699 cth->parallel_lookups_tail, parallel_lookup);
700 GNUNET_free (parallel_lookup->label);
702 GNUNET_STATISTICS_update (
703 stats, "attribute_lookup_time_total",
704 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time)
707 GNUNET_STATISTICS_update (stats, "attribute_lookups_count", 1, GNUNET_YES);
710 GNUNET_free (parallel_lookup);
712 GNUNET_break (0); // TODO
713 if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR) {
714 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
716 GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
717 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, cth->attrs->list_tail,
720 if (NULL != cth->parallel_lookups_head)
721 return; // Wait for more
722 /* Else we are done */
724 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
730 abort_parallel_lookups (void *cls)
732 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
733 struct ParallelLookup *lu;
734 struct ParallelLookup *tmp;
736 cth->kill_task = NULL;
737 for (lu = cth->parallel_lookups_head; NULL != lu;) {
738 GNUNET_GNS_lookup_cancel (lu->lookup_request);
739 GNUNET_free (lu->label);
741 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
742 cth->parallel_lookups_tail, lu);
746 cth->cb (cth->cb_cls, NULL, NULL, GNUNET_SYSERR, "Aborted");
751 lookup_authz_cb (void *cls, uint32_t rd_count,
752 const struct GNUNET_GNSRECORD_Data *rd)
754 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
755 struct ParallelLookup *parallel_lookup;
758 cth->lookup_request = NULL;
760 GNUNET_STATISTICS_update (
761 stats, "reclaim_authz_lookup_time_total",
762 GNUNET_TIME_absolute_get_duration (cth->lookup_start_time).rel_value_us,
764 GNUNET_STATISTICS_update (stats, "reclaim_authz_lookups_count", 1,
767 for (int i = 0; i < rd_count; i++) {
768 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
770 lbl = GNUNET_STRINGS_data_to_string_alloc (rd[i].data, rd[i].data_size);
771 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute ref found %s\n", lbl);
772 parallel_lookup = GNUNET_new (struct ParallelLookup);
773 parallel_lookup->handle = cth;
774 parallel_lookup->label = lbl;
775 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get ();
776 parallel_lookup->lookup_request = GNUNET_GNS_lookup (
777 gns, lbl, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
778 GNUNET_GNS_LO_DEFAULT, &process_parallel_lookup_result,
780 GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head,
781 cth->parallel_lookups_tail, parallel_lookup);
783 if (NULL != cth->parallel_lookups_head) {
784 cth->kill_task = GNUNET_SCHEDULER_add_delayed (
785 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3),
786 &abort_parallel_lookups, cth);
789 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
794 struct RECLAIM_TICKETS_ConsumeHandle *
795 RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id,
796 const struct GNUNET_RECLAIM_Ticket *ticket,
797 RECLAIM_TICKETS_ConsumeCallback cb, void *cb_cls)
799 struct RECLAIM_TICKETS_ConsumeHandle *cth;
801 cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle);
804 GNUNET_CRYPTO_ecdsa_key_get_public (&cth->identity, &cth->identity_pub);
805 cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
806 cth->ticket = *ticket;
808 cth->cb_cls = cb_cls;
810 GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof (uint64_t));
811 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for AuthZ info under %s\n",
813 cth->lookup_start_time = GNUNET_TIME_absolute_get ();
814 cth->lookup_request = GNUNET_GNS_lookup (
815 gns, label, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF,
816 GNUNET_GNS_LO_DEFAULT, &lookup_authz_cb, cth);
822 RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth)
829 /*******************************
831 *******************************/
834 * Cleanup ticket consume handle
835 * @param handle the handle to clean up
838 cleanup_issue_handle (struct TicketIssueHandle *handle)
840 if (NULL != handle->ns_qe)
841 GNUNET_NAMESTORE_cancel (handle->ns_qe);
842 GNUNET_free (handle);
847 store_ticket_issue_cont (void *cls, int32_t success, const char *emsg)
849 struct TicketIssueHandle *handle = cls;
851 handle->ns_qe = NULL;
852 if (GNUNET_SYSERR == success) {
853 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_SYSERR,
854 "Error storing AuthZ ticket in GNS");
857 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_OK, NULL);
858 cleanup_issue_handle (handle);
863 issue_ticket (struct TicketIssueHandle *ih)
865 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
866 struct GNUNET_GNSRECORD_Data *attrs_record;
871 for (le = ih->attrs->list_head; NULL != le; le = le->next)
875 GNUNET_malloc (list_len * sizeof (struct GNUNET_GNSRECORD_Data));
877 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
878 attrs_record[i].data = &le->claim->id;
879 attrs_record[i].data_size = sizeof (le->claim->id);
880 //FIXME: Should this be the attribute expiration time or ticket refresh intv
881 attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us;
882 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF;
883 attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
886 attrs_record[i].data = &ih->ticket;
887 attrs_record[i].data_size = sizeof (struct GNUNET_RECLAIM_Ticket);
888 attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us;
889 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET;
890 attrs_record[i].flags =
891 GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
894 GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof (uint64_t));
896 ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &ih->identity, label,
897 list_len, attrs_record,
898 &store_ticket_issue_cont, ih);
899 GNUNET_free (attrs_record);
905 RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
906 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
907 const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
908 RECLAIM_TICKETS_TicketResult cb, void *cb_cls)
910 struct TicketIssueHandle *tih;
911 tih = GNUNET_new (struct TicketIssueHandle);
913 tih->cb_cls = cb_cls;
914 tih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
915 tih->identity = *identity;
916 GNUNET_CRYPTO_ecdsa_key_get_public (identity, &tih->ticket.identity);
918 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
919 tih->ticket.audience = *audience;
923 /************************************
925 ************************************/
928 cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter)
930 if (NULL != iter->ns_it)
931 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
937 collect_tickets_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
938 const char *label, unsigned int rd_count,
939 const struct GNUNET_GNSRECORD_Data *rd)
941 struct RECLAIM_TICKETS_Iterator *iter = cls;
943 for (int i = 0; i < rd_count; i++) {
944 if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET != rd[i].record_type)
946 iter->cb (iter->cb_cls, (struct GNUNET_RECLAIM_Ticket *)rd[i].data);
949 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
954 collect_tickets_finished_cb (void *cls)
956 struct RECLAIM_TICKETS_Iterator *iter = cls;
958 iter->cb (iter->cb_cls, NULL);
964 collect_tickets_error_cb (void *cls)
966 struct RECLAIM_TICKETS_Iterator *iter = cls;
968 iter->cb (iter->cb_cls, NULL);
974 RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter)
976 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
981 RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter)
983 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
988 struct RECLAIM_TICKETS_Iterator *
989 RECLAIM_TICKETS_iteration_start (
990 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
991 RECLAIM_TICKETS_TicketIter cb, void *cb_cls)
993 struct RECLAIM_TICKETS_Iterator *iter;
995 iter = GNUNET_new (struct RECLAIM_TICKETS_Iterator);
997 iter->cb_cls = cb_cls;
998 iter->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
999 nsh, identity, &collect_tickets_error_cb, iter, &collect_tickets_cb, iter,
1000 &collect_tickets_finished_cb, iter);
1006 RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
1008 // Get ticket expiration time (relative) from config
1010 == GNUNET_CONFIGURATION_get_value_time (c,
1012 "TICKET_REFRESH_INTERVAL",
1013 &ticket_refresh_interval)) {
1015 GNUNET_ERROR_TYPE_DEBUG,
1016 "Configured refresh interval for tickets: %s\n",
1017 GNUNET_STRINGS_relative_time_to_string (ticket_refresh_interval,
1020 ticket_refresh_interval = DEFAULT_TICKET_REFRESH_INTERVAL;
1022 // Connect to identity and namestore services
1023 nsh = GNUNET_NAMESTORE_connect (c);
1025 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1026 "error connecting to namestore");
1027 return GNUNET_SYSERR;
1029 gns = GNUNET_GNS_connect (c);
1031 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1032 return GNUNET_SYSERR;
1034 stats = GNUNET_STATISTICS_create ("reclaim", c);
1039 RECLAIM_TICKETS_deinit (void)
1042 GNUNET_NAMESTORE_disconnect (nsh);
1045 GNUNET_GNS_disconnect (gns);
1047 if (NULL != stats) {
1048 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);