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;
35 * A reference to a ticket stored in GNS
37 struct TicketReference
42 struct TicketReference *next;
47 struct TicketReference *prev;
52 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
57 struct GNUNET_RECLAIM_Ticket ticket;
61 struct RECLAIM_TICKETS_ConsumeHandle
66 struct GNUNET_RECLAIM_Ticket ticket;
71 struct GNUNET_GNS_LookupRequest *lookup_request;
76 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
81 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
86 struct ParallelLookup *parallel_lookups_head;
91 struct ParallelLookup *parallel_lookups_tail;
96 struct GNUNET_SCHEDULER_Task *kill_task;
101 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
106 struct GNUNET_TIME_Absolute lookup_start_time;
111 RECLAIM_TICKETS_ConsumeCallback cb;
120 * Handle for a parallel GNS lookup job
122 struct ParallelLookup
125 struct ParallelLookup *next;
128 struct ParallelLookup *prev;
130 /* The GNS request */
131 struct GNUNET_GNS_LookupRequest *lookup_request;
133 /* The handle the return to */
134 struct RECLAIM_TICKETS_ConsumeHandle *handle;
139 struct GNUNET_TIME_Absolute lookup_start_time;
141 /* The label to look up */
147 * Ticket issue request handle
149 struct TicketIssueHandle
152 * Attributes to issue
154 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
159 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
164 struct GNUNET_RECLAIM_Ticket ticket;
169 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
174 RECLAIM_TICKETS_TicketResult cb;
185 struct RECLAIM_TICKETS_Iterator
188 * Namestore queue entry
190 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
195 RECLAIM_TICKETS_TicketIter cb;
204 struct RevokedAttributeEntry
209 struct RevokedAttributeEntry *next;
214 struct RevokedAttributeEntry *prev;
217 * Old ID of the attribute
222 * New ID of the attribute
229 * Ticket revocation request handle
231 struct RECLAIM_TICKETS_RevokeHandle
236 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
241 RECLAIM_TICKETS_RevokeCallback cb;
251 struct GNUNET_RECLAIM_Ticket ticket;
256 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
261 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
266 struct RevokedAttributeEntry *attrs_head;
271 struct RevokedAttributeEntry *attrs_tail;
274 * Current attribute to move
276 struct RevokedAttributeEntry *move_attr;
279 * Number of attributes in ticket
281 unsigned int ticket_attrs;
286 struct TicketRecordsEntry *tickets_to_update_head;
291 struct TicketRecordsEntry *tickets_to_update_tail;
295 /* Namestore handle */
296 static struct GNUNET_NAMESTORE_Handle *nsh;
299 static struct GNUNET_GNS_Handle *gns;
301 /* Handle to the statistics service */
302 static struct GNUNET_STATISTICS_Handle *stats;
305 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rh);
308 move_attrs_cont (void *cls)
310 move_attrs ((struct RECLAIM_TICKETS_RevokeHandle *)cls);
314 * Cleanup revoke handle
316 * @param rh the ticket revocation handle
319 cleanup_rvk (struct RECLAIM_TICKETS_RevokeHandle *rh)
321 struct RevokedAttributeEntry *ae;
322 struct TicketRecordsEntry *le;
323 if (NULL != rh->ns_qe)
324 GNUNET_NAMESTORE_cancel (rh->ns_qe);
325 if (NULL != rh->ns_it)
326 GNUNET_NAMESTORE_zone_iteration_stop (rh->ns_it);
327 while (NULL != (ae = rh->attrs_head)) {
328 GNUNET_CONTAINER_DLL_remove (rh->attrs_head, rh->attrs_tail, ae);
331 while (NULL != (le = rh->tickets_to_update_head)) {
332 GNUNET_CONTAINER_DLL_remove (rh->tickets_to_update_head,
333 rh->tickets_to_update_head, le);
334 if (NULL != le->data)
335 GNUNET_free (le->data);
336 if (NULL != le->label)
337 GNUNET_free (le->label);
344 del_attr_finished (void *cls, int32_t success, const char *emsg)
346 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
348 if (GNUNET_SYSERR == success) {
349 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error removing attribute: %s\n",
351 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
355 rvk->move_attr = rvk->move_attr->next;
356 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
360 move_attr_finished (void *cls, int32_t success, const char *emsg)
362 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
365 if (GNUNET_SYSERR == success) {
366 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error moving attribute: %s\n", emsg);
367 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
371 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
373 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing attribute %s\n", label);
374 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, label, 0,
375 NULL, &del_attr_finished, rvk);
380 rvk_move_attr_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
381 const char *label, unsigned int rd_count,
382 const struct GNUNET_GNSRECORD_Data *rd)
384 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
385 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
386 struct GNUNET_GNSRECORD_Data new_rd;
387 struct RevokedAttributeEntry *le;
392 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
393 "The attribute %s no longer exists!\n", label);
395 rvk->move_attr = le->next;
396 GNUNET_CONTAINER_DLL_remove (rvk->attrs_head, rvk->attrs_tail, le);
398 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
401 /** find a new place for this attribute **/
402 rvk->move_attr->new_id =
403 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
405 claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
406 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
407 "Attribute to update: Name=%s, ID=%" PRIu64 "\n", claim->name,
409 claim->id = rvk->move_attr->new_id;
410 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
411 attr_data = GNUNET_malloc (rd->data_size);
412 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
413 new_rd.data = attr_data;
414 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
416 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
417 rvk->ns_qe = GNUNET_NAMESTORE_records_store (
418 nsh, &rvk->identity, new_label, 1, &new_rd, &move_attr_finished, rvk);
419 GNUNET_free (new_label);
421 GNUNET_free (attr_data);
426 rvk_ticket_update (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
427 const char *label, unsigned int rd_count,
428 const struct GNUNET_GNSRECORD_Data *rd)
430 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
431 struct TicketRecordsEntry *le;
432 struct RevokedAttributeEntry *ae;
433 int has_changed = GNUNET_NO;
435 /** Let everything point to the old record **/
436 for (int i = 0; i < rd_count; i++) {
437 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
439 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next) {
440 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
442 has_changed = GNUNET_YES;
445 if (GNUNET_YES == has_changed)
448 if (GNUNET_YES == has_changed) {
449 le = GNUNET_new (struct TicketRecordsEntry);
450 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
451 le->data = GNUNET_malloc (le->data_size);
452 le->rd_count = rd_count;
453 le->label = GNUNET_strdup (label);
454 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
455 GNUNET_CONTAINER_DLL_insert (rvk->tickets_to_update_head,
456 rvk->tickets_to_update_tail, le);
458 GNUNET_NAMESTORE_zone_iterator_next (rvk->ns_it, 1);
463 process_tickets (void *cls);
467 ticket_processed (void *cls, int32_t success, const char *emsg)
469 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
471 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
475 process_tickets (void *cls)
477 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
478 struct TicketRecordsEntry *le;
479 struct RevokedAttributeEntry *ae;
480 if (NULL == rvk->tickets_to_update_head) {
481 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
482 "Finished updatding tickets, success\n");
483 rvk->cb (rvk->cb_cls, GNUNET_OK);
487 le = rvk->tickets_to_update_head;
488 GNUNET_CONTAINER_DLL_remove (rvk->tickets_to_update_head,
489 rvk->tickets_to_update_tail, le);
490 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
491 GNUNET_GNSRECORD_records_deserialize (le->data_size, le->data, le->rd_count,
493 for (int i = 0; i < le->rd_count; i++) {
494 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
496 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next) {
497 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
499 rd[i].data = &ae->new_id;
502 rvk->ns_qe = GNUNET_NAMESTORE_records_store (
503 nsh, &rvk->identity, le->label, le->rd_count, rd, &ticket_processed, rvk);
504 GNUNET_free (le->label);
505 GNUNET_free (le->data);
510 rvk_ticket_update_finished (void *cls)
512 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
514 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
519 rvk_ns_iter_err (void *cls)
521 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
523 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
524 "Namestore error on revocation (id=%" PRIu64 "\n",
525 rvk->move_attr->old_id);
526 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
532 rvk_ns_err (void *cls)
534 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
536 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
537 "Namestore error on revocation (id=%" PRIu64 "\n",
538 rvk->move_attr->old_id);
539 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
545 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
549 if (NULL == rvk->move_attr) {
550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished moving attributes\n");
551 rvk->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
552 nsh, &rvk->identity, &rvk_ns_iter_err, rvk, &rvk_ticket_update, rvk,
553 &rvk_ticket_update_finished, rvk);
556 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
558 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label);
560 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (
561 nsh, &rvk->identity, label, &rvk_ns_err, rvk, &rvk_move_attr_cb, rvk);
567 remove_ticket_cont (void *cls, int32_t success, const char *emsg)
569 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
571 if (GNUNET_SYSERR == success) {
572 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
573 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted ticket\n");
578 if (0 == rvk->ticket_attrs) {
579 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
580 "No attributes to move... strange\n");
581 rvk->cb (rvk->cb_cls, GNUNET_OK);
585 rvk->move_attr = rvk->attrs_head;
591 revoke_attrs_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
592 const char *label, unsigned int rd_count,
593 const struct GNUNET_GNSRECORD_Data *rd)
596 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
597 struct RevokedAttributeEntry *le;
599 for (int i = 0; i < rd_count; i++) {
600 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
602 le = GNUNET_new (struct RevokedAttributeEntry);
603 le->old_id = *((uint64_t *)rd[i].data);
604 GNUNET_CONTAINER_DLL_insert (rvk->attrs_head, rvk->attrs_tail, le);
608 /** Now, remove ticket **/
609 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, label, 0,
610 NULL, &remove_ticket_cont, rvk);
615 rvk_attrs_err_cb (void *cls)
617 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
618 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
623 struct RECLAIM_TICKETS_RevokeHandle *
624 RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket,
625 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
626 RECLAIM_TICKETS_RevokeCallback cb, void *cb_cls)
628 struct RECLAIM_TICKETS_RevokeHandle *rvk;
631 rvk = GNUNET_new (struct RECLAIM_TICKETS_RevokeHandle);
633 rvk->cb_cls = cb_cls;
634 rvk->identity = *identity;
635 rvk->ticket = *ticket;
636 GNUNET_CRYPTO_ecdsa_key_get_public (&rvk->identity, &rvk->ticket.identity);
637 /** Get shared attributes **/
638 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof (uint64_t));
640 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (
641 nsh, identity, label, &rvk_attrs_err_cb, rvk, &revoke_attrs_cb, rvk);
647 RECLAIM_TICKETS_revoke_cancel (struct RECLAIM_TICKETS_RevokeHandle *rh)
651 /*******************************
653 *******************************/
656 * Cleanup ticket consume handle
657 * @param cth the handle to clean up
660 cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth)
662 struct ParallelLookup *lu;
663 struct ParallelLookup *tmp;
664 if (NULL != cth->lookup_request)
665 GNUNET_GNS_lookup_cancel (cth->lookup_request);
666 for (lu = cth->parallel_lookups_head; NULL != lu;) {
667 GNUNET_GNS_lookup_cancel (lu->lookup_request);
668 GNUNET_free (lu->label);
670 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
671 cth->parallel_lookups_tail, lu);
676 if (NULL != cth->attrs)
677 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (cth->attrs);
683 process_parallel_lookup_result (void *cls, uint32_t rd_count,
684 const struct GNUNET_GNSRECORD_Data *rd)
686 struct ParallelLookup *parallel_lookup = cls;
687 struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle;
688 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
689 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parallel lookup finished (count=%u)\n",
692 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
693 cth->parallel_lookups_tail, parallel_lookup);
694 GNUNET_free (parallel_lookup->label);
696 GNUNET_STATISTICS_update (
697 stats, "attribute_lookup_time_total",
698 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time)
701 GNUNET_STATISTICS_update (stats, "attribute_lookups_count", 1, GNUNET_YES);
704 GNUNET_free (parallel_lookup);
706 GNUNET_break (0); // TODO
707 if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR) {
708 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
710 GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
711 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, cth->attrs->list_tail,
714 if (NULL != cth->parallel_lookups_head)
715 return; // Wait for more
716 /* Else we are done */
718 GNUNET_SCHEDULER_cancel (cth->kill_task);
719 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
725 abort_parallel_lookups (void *cls)
727 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
728 struct ParallelLookup *lu;
729 struct ParallelLookup *tmp;
731 cth->kill_task = NULL;
732 for (lu = cth->parallel_lookups_head; NULL != lu;) {
733 GNUNET_GNS_lookup_cancel (lu->lookup_request);
734 GNUNET_free (lu->label);
736 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
737 cth->parallel_lookups_tail, lu);
741 cth->cb (cth->cb_cls, NULL, NULL, GNUNET_SYSERR, "Aborted");
746 lookup_authz_cb (void *cls, uint32_t rd_count,
747 const struct GNUNET_GNSRECORD_Data *rd)
749 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
750 struct ParallelLookup *parallel_lookup;
753 cth->lookup_request = NULL;
755 GNUNET_STATISTICS_update (
756 stats, "reclaim_authz_lookup_time_total",
757 GNUNET_TIME_absolute_get_duration (cth->lookup_start_time).rel_value_us,
759 GNUNET_STATISTICS_update (stats, "reclaim_authz_lookups_count", 1,
762 for (int i = 0; i < rd_count; i++) {
763 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
765 lbl = GNUNET_STRINGS_data_to_string_alloc (rd[i].data, rd[i].data_size);
766 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute ref found %s\n", lbl);
767 parallel_lookup = GNUNET_new (struct ParallelLookup);
768 parallel_lookup->handle = cth;
769 parallel_lookup->label = lbl;
770 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get ();
771 parallel_lookup->lookup_request = GNUNET_GNS_lookup (
772 gns, lbl, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
773 GNUNET_GNS_LO_DEFAULT, &process_parallel_lookup_result,
775 GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head,
776 cth->parallel_lookups_tail, parallel_lookup);
778 if (NULL != cth->parallel_lookups_head) {
779 cth->kill_task = GNUNET_SCHEDULER_add_delayed (
780 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3),
781 &abort_parallel_lookups, cth);
784 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
789 struct RECLAIM_TICKETS_ConsumeHandle *
790 RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id,
791 const struct GNUNET_RECLAIM_Ticket *ticket,
792 RECLAIM_TICKETS_ConsumeCallback cb, void *cb_cls)
794 struct RECLAIM_TICKETS_ConsumeHandle *cth;
796 cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle);
799 GNUNET_CRYPTO_ecdsa_key_get_public (&cth->identity, &cth->identity_pub);
800 cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
801 cth->ticket = *ticket;
803 cth->cb_cls = cb_cls;
805 GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof (uint64_t));
806 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for AuthZ info under %s\n",
808 cth->lookup_start_time = GNUNET_TIME_absolute_get ();
809 cth->lookup_request = GNUNET_GNS_lookup (
810 gns, label, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF,
811 GNUNET_GNS_LO_DEFAULT, &lookup_authz_cb, cth);
817 RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth)
824 /*******************************
826 *******************************/
829 * Cleanup ticket consume handle
830 * @param handle the handle to clean up
833 cleanup_issue_handle (struct TicketIssueHandle *handle)
835 if (NULL != handle->ns_qe)
836 GNUNET_NAMESTORE_cancel (handle->ns_qe);
837 GNUNET_free (handle);
842 store_ticket_issue_cont (void *cls, int32_t success, const char *emsg)
844 struct TicketIssueHandle *handle = cls;
846 handle->ns_qe = NULL;
847 if (GNUNET_SYSERR == success) {
848 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_SYSERR,
849 "Error storing AuthZ ticket in GNS");
852 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_OK, NULL);
853 cleanup_issue_handle (handle);
858 issue_ticket (struct TicketIssueHandle *ih)
860 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
861 struct GNUNET_GNSRECORD_Data *attrs_record;
866 for (le = ih->attrs->list_head; NULL != le; le = le->next)
870 GNUNET_malloc (list_len * sizeof (struct GNUNET_GNSRECORD_Data));
872 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
873 attrs_record[i].data = &le->claim->id;
874 attrs_record[i].data_size = sizeof (le->claim->id);
875 attrs_record[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
876 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF;
877 attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
880 attrs_record[i].data = &ih->ticket;
881 attrs_record[i].data_size = sizeof (struct GNUNET_RECLAIM_Ticket);
882 attrs_record[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
883 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET;
884 attrs_record[i].flags =
885 GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
888 GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof (uint64_t));
890 ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &ih->identity, label,
891 list_len, attrs_record,
892 &store_ticket_issue_cont, ih);
893 GNUNET_free (attrs_record);
899 RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
900 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
901 const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
902 RECLAIM_TICKETS_TicketResult cb, void *cb_cls)
904 struct TicketIssueHandle *tih;
905 tih = GNUNET_new (struct TicketIssueHandle);
907 tih->cb_cls = cb_cls;
908 tih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
909 tih->identity = *identity;
910 GNUNET_CRYPTO_ecdsa_key_get_public (identity, &tih->ticket.identity);
912 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
913 tih->ticket.audience = *audience;
917 /************************************
919 ************************************/
922 cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter)
924 if (NULL != iter->ns_it)
925 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
931 collect_tickets_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
932 const char *label, unsigned int rd_count,
933 const struct GNUNET_GNSRECORD_Data *rd)
935 struct RECLAIM_TICKETS_Iterator *iter = cls;
937 for (int i = 0; i < rd_count; i++) {
938 if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET != rd[i].record_type)
940 iter->cb (iter->cb_cls, (struct GNUNET_RECLAIM_Ticket *)rd[i].data);
943 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
948 collect_tickets_finished_cb (void *cls)
950 struct RECLAIM_TICKETS_Iterator *iter = cls;
952 iter->cb (iter->cb_cls, NULL);
958 collect_tickets_error_cb (void *cls)
960 struct RECLAIM_TICKETS_Iterator *iter = cls;
962 iter->cb (iter->cb_cls, NULL);
968 RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter)
970 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
975 RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter)
977 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
982 struct RECLAIM_TICKETS_Iterator *
983 RECLAIM_TICKETS_iteration_start (
984 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
985 RECLAIM_TICKETS_TicketIter cb, void *cb_cls)
987 struct RECLAIM_TICKETS_Iterator *iter;
989 iter = GNUNET_new (struct RECLAIM_TICKETS_Iterator);
991 iter->cb_cls = cb_cls;
992 iter->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
993 nsh, identity, &collect_tickets_error_cb, iter, &collect_tickets_cb, iter,
994 &collect_tickets_finished_cb, iter);
1000 RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
1002 // Connect to identity and namestore services
1003 nsh = GNUNET_NAMESTORE_connect (c);
1005 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1006 "error connecting to namestore");
1007 return GNUNET_SYSERR;
1009 gns = GNUNET_GNS_connect (c);
1011 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1012 return GNUNET_SYSERR;
1014 stats = GNUNET_STATISTICS_create ("reclaim", c);
1019 RECLAIM_TICKETS_deinit (void)
1022 GNUNET_NAMESTORE_disconnect (nsh);
1025 GNUNET_GNS_disconnect (gns);
1027 if (NULL != stats) {
1028 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);