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 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
180 RECLAIM_TICKETS_TicketResult cb;
191 struct RECLAIM_TICKETS_Iterator
194 * Namestore queue entry
196 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
201 RECLAIM_TICKETS_TicketIter cb;
210 struct RevokedAttributeEntry
215 struct RevokedAttributeEntry *next;
220 struct RevokedAttributeEntry *prev;
223 * Old ID of the attribute
228 * New ID of the attribute
235 * Ticket revocation request handle
237 struct RECLAIM_TICKETS_RevokeHandle
242 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
247 RECLAIM_TICKETS_RevokeCallback cb;
257 struct GNUNET_RECLAIM_Ticket ticket;
262 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
267 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
272 struct RevokedAttributeEntry *attrs_head;
277 struct RevokedAttributeEntry *attrs_tail;
280 * Current attribute to move
282 struct RevokedAttributeEntry *move_attr;
285 * Number of attributes in ticket
287 unsigned int ticket_attrs;
292 struct TicketRecordsEntry *tickets_to_update_head;
297 struct TicketRecordsEntry *tickets_to_update_tail;
301 * Ticket expiration interval
303 static struct GNUNET_TIME_Relative ticket_refresh_interval;
305 /* Namestore handle */
306 static struct GNUNET_NAMESTORE_Handle *nsh;
309 static struct GNUNET_GNS_Handle *gns;
311 /* Handle to the statistics service */
312 static struct GNUNET_STATISTICS_Handle *stats;
315 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rh);
318 move_attrs_cont (void *cls)
320 move_attrs ((struct RECLAIM_TICKETS_RevokeHandle *) cls);
324 * Cleanup revoke handle
326 * @param rh the ticket revocation handle
329 cleanup_rvk (struct RECLAIM_TICKETS_RevokeHandle *rh)
331 struct RevokedAttributeEntry *ae;
332 struct TicketRecordsEntry *le;
333 if (NULL != rh->ns_qe)
334 GNUNET_NAMESTORE_cancel (rh->ns_qe);
335 if (NULL != rh->ns_it)
336 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
337 while (NULL != (ae = rh->attrs_head))
339 GNUNET_CONTAINER_DLL_remove (rh->attrs_head, rh->attrs_tail, ae);
342 while (NULL != (le = rh->tickets_to_update_head))
344 GNUNET_CONTAINER_DLL_remove (rh->tickets_to_update_head,
345 rh->tickets_to_update_head,
347 if (NULL != le->data)
348 GNUNET_free (le->data);
349 if (NULL != le->label)
350 GNUNET_free (le->label);
357 del_attr_finished (void *cls, int32_t success, const char *emsg)
359 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
361 if (GNUNET_SYSERR == success)
363 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
364 "Error removing attribute: %s\n",
366 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
370 rvk->move_attr = rvk->move_attr->next;
371 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
375 move_attr_finished (void *cls, int32_t success, const char *emsg)
377 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
380 if (GNUNET_SYSERR == success)
382 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error moving attribute: %s\n", emsg);
383 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
387 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
389 GNUNET_assert (NULL != label);
390 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing attribute %s\n", label);
391 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
403 rvk_move_attr_cb (void *cls,
404 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
406 unsigned int rd_count,
407 const struct GNUNET_GNSRECORD_Data *rd)
409 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
410 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
411 struct GNUNET_GNSRECORD_Data new_rd;
412 struct RevokedAttributeEntry *le;
418 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
419 "The attribute %s no longer exists!\n",
422 rvk->move_attr = le->next;
423 GNUNET_CONTAINER_DLL_remove (rvk->attrs_head, rvk->attrs_tail, le);
425 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
428 /** find a new place for this attribute **/
429 rvk->move_attr->new_id =
430 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
432 claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
433 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
434 "Attribute to update: Name=%s, ID=%" PRIu64 "\n",
437 claim->id = rvk->move_attr->new_id;
438 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
439 attr_data = GNUNET_malloc (rd->data_size);
440 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
441 new_rd.data = attr_data;
442 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
444 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
445 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
452 GNUNET_free (new_label);
454 GNUNET_free (attr_data);
459 rvk_ticket_update (void *cls,
460 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
462 unsigned int rd_count,
463 const struct GNUNET_GNSRECORD_Data *rd)
465 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
466 struct TicketRecordsEntry *le;
467 struct RevokedAttributeEntry *ae;
468 int has_changed = GNUNET_NO;
470 /** Let everything point to the old record **/
471 for (int i = 0; i < rd_count; i++)
473 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
475 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next)
477 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
479 has_changed = GNUNET_YES;
482 if (GNUNET_YES == has_changed)
485 if (GNUNET_YES == has_changed)
487 le = GNUNET_new (struct TicketRecordsEntry);
488 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
489 le->data = GNUNET_malloc (le->data_size);
490 le->rd_count = rd_count;
491 le->label = GNUNET_strdup (label);
492 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
493 GNUNET_CONTAINER_DLL_insert (rvk->tickets_to_update_head,
494 rvk->tickets_to_update_tail,
497 GNUNET_NAMESTORE_zone_iterator_next (rvk->ns_it, 1);
502 process_tickets (void *cls);
506 ticket_processed (void *cls, int32_t success, const char *emsg)
508 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
510 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
514 process_tickets (void *cls)
516 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
517 struct TicketRecordsEntry *le;
518 struct RevokedAttributeEntry *ae;
519 if (NULL == rvk->tickets_to_update_head)
521 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
522 "Finished updatding tickets, success\n");
523 rvk->cb (rvk->cb_cls, GNUNET_OK);
527 le = rvk->tickets_to_update_head;
528 GNUNET_CONTAINER_DLL_remove (rvk->tickets_to_update_head,
529 rvk->tickets_to_update_tail,
531 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
532 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
537 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
538 "Unable to deserialize ticket record(s)\n");
539 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
543 for (int i = 0; i < le->rd_count; i++)
545 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
547 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next)
549 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
551 rd[i].data = &ae->new_id;
554 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
561 GNUNET_free (le->label);
562 GNUNET_free (le->data);
567 rvk_ticket_update_finished (void *cls)
569 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
571 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
576 rvk_ns_iter_err (void *cls)
578 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
580 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
581 "Namestore error on revocation (id=%" PRIu64 "\n",
582 rvk->move_attr->old_id);
583 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
589 rvk_ns_err (void *cls)
591 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
593 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
594 "Namestore error on revocation (id=%" PRIu64 "\n",
595 rvk->move_attr->old_id);
596 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
602 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
606 if (NULL == rvk->move_attr)
608 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished moving attributes\n");
610 GNUNET_NAMESTORE_zone_iteration_start (nsh,
616 &rvk_ticket_update_finished,
620 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label);
624 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
636 remove_ticket_cont (void *cls, int32_t success, const char *emsg)
638 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
640 if (GNUNET_SYSERR == success)
642 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
643 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
647 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted ticket\n");
648 if (0 == rvk->ticket_attrs)
650 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
651 "No attributes to move... strange\n");
652 rvk->cb (rvk->cb_cls, GNUNET_OK);
656 rvk->move_attr = rvk->attrs_head;
662 revoke_attrs_cb (void *cls,
663 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
665 unsigned int rd_count,
666 const struct GNUNET_GNSRECORD_Data *rd)
669 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
670 struct RevokedAttributeEntry *le;
672 for (int i = 0; i < rd_count; i++)
674 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
676 le = GNUNET_new (struct RevokedAttributeEntry);
677 le->old_id = *((uint64_t *) rd[i].data);
678 GNUNET_CONTAINER_DLL_insert (rvk->attrs_head, rvk->attrs_tail, le);
682 /** Now, remove ticket **/
683 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
694 rvk_attrs_err_cb (void *cls)
696 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
697 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
702 struct RECLAIM_TICKETS_RevokeHandle *
703 RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket,
704 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
705 RECLAIM_TICKETS_RevokeCallback cb,
708 struct RECLAIM_TICKETS_RevokeHandle *rvk;
711 rvk = GNUNET_new (struct RECLAIM_TICKETS_RevokeHandle);
713 rvk->cb_cls = cb_cls;
714 rvk->identity = *identity;
715 rvk->ticket = *ticket;
716 GNUNET_CRYPTO_ecdsa_key_get_public (&rvk->identity, &rvk->ticket.identity);
717 /** Get shared attributes **/
718 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof (uint64_t));
719 GNUNET_assert (NULL != label);
720 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
733 RECLAIM_TICKETS_revoke_cancel (struct RECLAIM_TICKETS_RevokeHandle *rh)
737 /*******************************
739 *******************************/
742 * Cleanup ticket consume handle
743 * @param cth the handle to clean up
746 cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth)
748 struct ParallelLookup *lu;
749 if (NULL != cth->lookup_request)
750 GNUNET_GNS_lookup_cancel (cth->lookup_request);
751 if (NULL != cth->kill_task)
752 GNUNET_SCHEDULER_cancel (cth->kill_task);
753 while (NULL != (lu = cth->parallel_lookups_head))
755 if (NULL != lu->lookup_request)
756 GNUNET_GNS_lookup_cancel (lu->lookup_request);
757 GNUNET_free_non_null (lu->label);
758 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
759 cth->parallel_lookups_tail,
764 if (NULL != cth->attrs)
765 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (cth->attrs);
771 process_parallel_lookup_result (void *cls,
773 const struct GNUNET_GNSRECORD_Data *rd)
775 struct ParallelLookup *parallel_lookup = cls;
776 struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle;
777 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
778 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
779 "Parallel lookup finished (count=%u)\n",
782 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
783 cth->parallel_lookups_tail,
785 GNUNET_free (parallel_lookup->label);
787 GNUNET_STATISTICS_update (stats,
788 "attribute_lookup_time_total",
789 GNUNET_TIME_absolute_get_duration (
790 parallel_lookup->lookup_start_time)
793 GNUNET_STATISTICS_update (stats, "attribute_lookups_count", 1, GNUNET_YES);
796 GNUNET_free (parallel_lookup);
798 GNUNET_break (0); // TODO
799 if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR)
801 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
803 GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
804 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
805 cth->attrs->list_tail,
808 if (NULL != cth->parallel_lookups_head)
809 return; // Wait for more
810 /* Else we are done */
812 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
818 abort_parallel_lookups (void *cls)
820 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
821 struct ParallelLookup *lu;
822 struct ParallelLookup *tmp;
824 cth->kill_task = NULL;
825 for (lu = cth->parallel_lookups_head; NULL != lu;)
827 GNUNET_GNS_lookup_cancel (lu->lookup_request);
828 GNUNET_free (lu->label);
830 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
831 cth->parallel_lookups_tail,
836 cth->cb (cth->cb_cls, NULL, NULL, GNUNET_SYSERR, "Aborted");
841 lookup_authz_cb (void *cls,
843 const struct GNUNET_GNSRECORD_Data *rd)
845 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
846 struct ParallelLookup *parallel_lookup;
849 cth->lookup_request = NULL;
851 GNUNET_STATISTICS_update (stats,
852 "reclaim_authz_lookup_time_total",
853 GNUNET_TIME_absolute_get_duration (
854 cth->lookup_start_time)
857 GNUNET_STATISTICS_update (stats,
858 "reclaim_authz_lookups_count",
862 for (int i = 0; i < rd_count; i++)
864 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
866 lbl = GNUNET_STRINGS_data_to_string_alloc (rd[i].data, rd[i].data_size);
867 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute ref found %s\n", lbl);
868 parallel_lookup = GNUNET_new (struct ParallelLookup);
869 parallel_lookup->handle = cth;
870 parallel_lookup->label = lbl;
871 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get ();
872 parallel_lookup->lookup_request =
873 GNUNET_GNS_lookup (gns,
875 &cth->ticket.identity,
876 GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
877 GNUNET_GNS_LO_DEFAULT,
878 &process_parallel_lookup_result,
880 GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head,
881 cth->parallel_lookups_tail,
884 if (NULL != cth->parallel_lookups_head)
886 cth->kill_task = GNUNET_SCHEDULER_add_delayed (
887 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3),
888 &abort_parallel_lookups,
892 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
897 struct RECLAIM_TICKETS_ConsumeHandle *
898 RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id,
899 const struct GNUNET_RECLAIM_Ticket *ticket,
900 RECLAIM_TICKETS_ConsumeCallback cb,
903 struct RECLAIM_TICKETS_ConsumeHandle *cth;
905 cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle);
908 GNUNET_CRYPTO_ecdsa_key_get_public (&cth->identity, &cth->identity_pub);
909 cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
910 cth->ticket = *ticket;
912 cth->cb_cls = cb_cls;
914 GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof (uint64_t));
915 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
916 "Looking for AuthZ info under %s\n",
918 cth->lookup_start_time = GNUNET_TIME_absolute_get ();
919 cth->lookup_request =
920 GNUNET_GNS_lookup (gns,
922 &cth->ticket.identity,
923 GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF,
924 GNUNET_GNS_LO_DEFAULT,
932 RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth)
939 /*******************************
941 *******************************/
944 * Cleanup ticket consume handle
945 * @param handle the handle to clean up
948 cleanup_issue_handle (struct TicketIssueHandle *handle)
950 if (NULL != handle->ns_qe)
951 GNUNET_NAMESTORE_cancel (handle->ns_qe);
952 GNUNET_free (handle);
957 store_ticket_issue_cont (void *cls, int32_t success, const char *emsg)
959 struct TicketIssueHandle *handle = cls;
961 handle->ns_qe = NULL;
962 if (GNUNET_SYSERR == success)
964 handle->cb (handle->cb_cls,
967 "Error storing AuthZ ticket in GNS");
970 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_OK, NULL);
971 cleanup_issue_handle (handle);
976 issue_ticket (struct TicketIssueHandle *ih)
978 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
979 struct GNUNET_GNSRECORD_Data *attrs_record;
984 for (le = ih->attrs->list_head; NULL != le; le = le->next)
988 GNUNET_malloc (list_len * sizeof (struct GNUNET_GNSRECORD_Data));
990 for (le = ih->attrs->list_head; NULL != le; le = le->next)
992 attrs_record[i].data = &le->claim->id;
993 attrs_record[i].data_size = sizeof (le->claim->id);
994 //FIXME: Should this be the attribute expiration time or ticket refresh intv
995 attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us;
996 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF;
997 attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1000 attrs_record[i].data = &ih->ticket;
1001 attrs_record[i].data_size = sizeof (struct GNUNET_RECLAIM_Ticket);
1002 attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us;
1003 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET;
1004 attrs_record[i].flags =
1005 GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
1008 GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof (uint64_t));
1010 ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1015 &store_ticket_issue_cont,
1017 GNUNET_free (attrs_record);
1018 GNUNET_free (label);
1021 /*************************************************
1022 * Ticket iteration (finding a specific ticket)
1023 *************************************************/
1026 filter_tickets_error_cb (void *cls)
1028 struct TicketIssueHandle *tih = cls;
1030 tih->cb (tih->cb_cls, &tih->ticket, GNUNET_SYSERR, "Error storing AuthZ ticket in GNS");
1031 cleanup_issue_handle (tih);
1035 filter_tickets_cb (void *cls,
1036 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1038 unsigned int rd_count,
1039 const struct GNUNET_GNSRECORD_Data *rd)
1041 struct TicketIssueHandle *tih = cls;
1042 struct GNUNET_RECLAIM_Ticket *ticket = NULL;
1044 // figure out the number of requested attributes
1045 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
1046 unsigned int attr_cnt = 0;
1047 for (le = tih->attrs->list_head; NULL != le; le = le->next)
1051 unsigned int found_attrs_cnt = 0;
1053 for (int i = 0; i < rd_count; i++)
1056 if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET == rd[i].record_type)
1058 ticket = (struct GNUNET_RECLAIM_Ticket *) rd[i].data;
1060 if (0 == memcmp (&tih->ticket.audience,
1062 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1064 tih->ticket = *ticket;
1070 // cmp requested attributes with ticket attributes
1071 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
1073 for (le = tih->attrs->list_head; NULL != le; le = le->next)
1075 // cmp attr_ref id with requested attr id
1076 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1077 " %" PRIu64 "\n %" PRIu64 "\n",
1078 *((uint64_t *) rd[i].data), le->claim->id);
1081 if (0 == memcmp (rd[i].data,
1088 if (attr_cnt == found_attrs_cnt && NULL != ticket)
1090 GNUNET_NAMESTORE_zone_iteration_stop (tih->ns_it);
1091 tih->cb (tih->cb_cls, &tih->ticket, GNUNET_OK, NULL);
1092 cleanup_issue_handle (tih);
1096 // ticket not found in current record
1097 GNUNET_NAMESTORE_zone_iterator_next (tih->ns_it, 1);
1102 filter_tickets_finished_cb (void *cls)
1104 struct TicketIssueHandle *tih = cls;
1105 GNUNET_CRYPTO_ecdsa_key_get_public (&tih->identity, &tih->ticket.identity);
1106 tih->ticket.rnd = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
1111 RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1112 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
1113 const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
1114 RECLAIM_TICKETS_TicketResult cb,
1117 struct TicketIssueHandle *tih;
1118 tih = GNUNET_new (struct TicketIssueHandle);
1120 tih->cb_cls = cb_cls;
1121 tih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
1122 tih->identity = *identity;
1123 tih->ticket.audience = *audience;
1125 // check whether the ticket has already been issued
1127 GNUNET_NAMESTORE_zone_iteration_start (nsh,
1129 &filter_tickets_error_cb,
1133 &filter_tickets_finished_cb,
1137 /************************************
1139 ************************************/
1142 cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter)
1144 if (NULL != iter->ns_it)
1145 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
1151 collect_tickets_cb (void *cls,
1152 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
1154 unsigned int rd_count,
1155 const struct GNUNET_GNSRECORD_Data *rd)
1157 struct RECLAIM_TICKETS_Iterator *iter = cls;
1159 for (int i = 0; i < rd_count; i++)
1161 if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET != rd[i].record_type)
1163 iter->cb (iter->cb_cls, (struct GNUNET_RECLAIM_Ticket *) rd[i].data);
1166 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
1171 collect_tickets_finished_cb (void *cls)
1173 struct RECLAIM_TICKETS_Iterator *iter = cls;
1175 iter->cb (iter->cb_cls, NULL);
1176 cleanup_iter (iter);
1181 collect_tickets_error_cb (void *cls)
1183 struct RECLAIM_TICKETS_Iterator *iter = cls;
1185 iter->cb (iter->cb_cls, NULL);
1186 cleanup_iter (iter);
1191 RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter)
1193 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
1198 RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter)
1200 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
1201 cleanup_iter (iter);
1205 struct RECLAIM_TICKETS_Iterator *
1206 RECLAIM_TICKETS_iteration_start (
1207 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1208 RECLAIM_TICKETS_TicketIter cb,
1211 struct RECLAIM_TICKETS_Iterator *iter;
1213 iter = GNUNET_new (struct RECLAIM_TICKETS_Iterator);
1215 iter->cb_cls = cb_cls;
1217 GNUNET_NAMESTORE_zone_iteration_start (nsh,
1219 &collect_tickets_error_cb,
1221 &collect_tickets_cb,
1223 &collect_tickets_finished_cb,
1230 RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
1232 // Get ticket expiration time (relative) from config
1234 GNUNET_CONFIGURATION_get_value_time (c,
1236 "TICKET_REFRESH_INTERVAL",
1237 &ticket_refresh_interval))
1239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1240 "Configured refresh interval for tickets: %s\n",
1241 GNUNET_STRINGS_relative_time_to_string (ticket_refresh_interval,
1246 ticket_refresh_interval = DEFAULT_TICKET_REFRESH_INTERVAL;
1248 // Connect to identity and namestore services
1249 nsh = GNUNET_NAMESTORE_connect (c);
1252 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1253 "error connecting to namestore");
1254 return GNUNET_SYSERR;
1256 gns = GNUNET_GNS_connect (c);
1259 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1260 return GNUNET_SYSERR;
1262 stats = GNUNET_STATISTICS_create ("reclaim", c);
1267 RECLAIM_TICKETS_deinit (void)
1270 GNUNET_NAMESTORE_disconnect (nsh);
1273 GNUNET_GNS_disconnect (gns);
1277 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);