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)) {
333 GNUNET_CONTAINER_DLL_remove (rh->attrs_head, rh->attrs_tail, ae);
336 while (NULL != (le = rh->tickets_to_update_head)) {
337 GNUNET_CONTAINER_DLL_remove (rh->tickets_to_update_head,
338 rh->tickets_to_update_head, le);
339 if (NULL != le->data)
340 GNUNET_free (le->data);
341 if (NULL != le->label)
342 GNUNET_free (le->label);
349 del_attr_finished (void *cls, int32_t success, const char *emsg)
351 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
353 if (GNUNET_SYSERR == success) {
354 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error removing attribute: %s\n",
356 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
360 rvk->move_attr = rvk->move_attr->next;
361 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
365 move_attr_finished (void *cls, int32_t success, const char *emsg)
367 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
370 if (GNUNET_SYSERR == success) {
371 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error moving attribute: %s\n", emsg);
372 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
376 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
378 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing attribute %s\n", label);
379 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, label, 0,
380 NULL, &del_attr_finished, rvk);
385 rvk_move_attr_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
386 const char *label, unsigned int rd_count,
387 const struct GNUNET_GNSRECORD_Data *rd)
389 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
390 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
391 struct GNUNET_GNSRECORD_Data new_rd;
392 struct RevokedAttributeEntry *le;
397 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
398 "The attribute %s no longer exists!\n", label);
400 rvk->move_attr = le->next;
401 GNUNET_CONTAINER_DLL_remove (rvk->attrs_head, rvk->attrs_tail, le);
403 GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
406 /** find a new place for this attribute **/
407 rvk->move_attr->new_id =
408 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
410 claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
412 "Attribute to update: Name=%s, ID=%" PRIu64 "\n", claim->name,
414 claim->id = rvk->move_attr->new_id;
415 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
416 attr_data = GNUNET_malloc (rd->data_size);
417 new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
418 new_rd.data = attr_data;
419 new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
422 rvk->ns_qe = GNUNET_NAMESTORE_records_store (
423 nsh, &rvk->identity, new_label, 1, &new_rd, &move_attr_finished, rvk);
424 GNUNET_free (new_label);
426 GNUNET_free (attr_data);
431 rvk_ticket_update (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
432 const char *label, unsigned int rd_count,
433 const struct GNUNET_GNSRECORD_Data *rd)
435 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
436 struct TicketRecordsEntry *le;
437 struct RevokedAttributeEntry *ae;
438 int has_changed = GNUNET_NO;
440 /** Let everything point to the old record **/
441 for (int i = 0; i < rd_count; i++) {
442 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
444 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next) {
445 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
447 has_changed = GNUNET_YES;
450 if (GNUNET_YES == has_changed)
453 if (GNUNET_YES == has_changed) {
454 le = GNUNET_new (struct TicketRecordsEntry);
455 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
456 le->data = GNUNET_malloc (le->data_size);
457 le->rd_count = rd_count;
458 le->label = GNUNET_strdup (label);
459 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
460 GNUNET_CONTAINER_DLL_insert (rvk->tickets_to_update_head,
461 rvk->tickets_to_update_tail, le);
463 GNUNET_NAMESTORE_zone_iterator_next (rvk->ns_it, 1);
468 process_tickets (void *cls);
472 ticket_processed (void *cls, int32_t success, const char *emsg)
474 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
476 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
480 process_tickets (void *cls)
482 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
483 struct TicketRecordsEntry *le;
484 struct RevokedAttributeEntry *ae;
485 if (NULL == rvk->tickets_to_update_head) {
486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
487 "Finished updatding tickets, success\n");
488 rvk->cb (rvk->cb_cls, GNUNET_OK);
492 le = rvk->tickets_to_update_head;
493 GNUNET_CONTAINER_DLL_remove (rvk->tickets_to_update_head,
494 rvk->tickets_to_update_tail, le);
495 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
496 GNUNET_GNSRECORD_records_deserialize (le->data_size, le->data, le->rd_count,
498 for (int i = 0; i < le->rd_count; i++) {
499 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
501 for (ae = rvk->attrs_head; NULL != ae; ae = ae->next) {
502 if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
504 rd[i].data = &ae->new_id;
507 rvk->ns_qe = GNUNET_NAMESTORE_records_store (
508 nsh, &rvk->identity, le->label, le->rd_count, rd, &ticket_processed, rvk);
509 GNUNET_free (le->label);
510 GNUNET_free (le->data);
515 rvk_ticket_update_finished (void *cls)
517 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
519 GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
524 rvk_ns_iter_err (void *cls)
526 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
528 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
529 "Namestore error on revocation (id=%" PRIu64 "\n",
530 rvk->move_attr->old_id);
531 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
537 rvk_ns_err (void *cls)
539 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
541 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
542 "Namestore error on revocation (id=%" PRIu64 "\n",
543 rvk->move_attr->old_id);
544 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
550 move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
554 if (NULL == rvk->move_attr) {
555 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished moving attributes\n");
556 rvk->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
557 nsh, &rvk->identity, &rvk_ns_iter_err, rvk, &rvk_ticket_update, rvk,
558 &rvk_ticket_update_finished, rvk);
561 label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
563 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label);
565 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (
566 nsh, &rvk->identity, label, &rvk_ns_err, rvk, &rvk_move_attr_cb, rvk);
572 remove_ticket_cont (void *cls, int32_t success, const char *emsg)
574 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
576 if (GNUNET_SYSERR == success) {
577 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
578 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
582 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleted ticket\n");
583 if (0 == rvk->ticket_attrs) {
584 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
585 "No attributes to move... strange\n");
586 rvk->cb (rvk->cb_cls, GNUNET_OK);
590 rvk->move_attr = rvk->attrs_head;
596 revoke_attrs_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
597 const char *label, unsigned int rd_count,
598 const struct GNUNET_GNSRECORD_Data *rd)
601 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
602 struct RevokedAttributeEntry *le;
604 for (int i = 0; i < rd_count; i++) {
605 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
607 le = GNUNET_new (struct RevokedAttributeEntry);
608 le->old_id = *((uint64_t *)rd[i].data);
609 GNUNET_CONTAINER_DLL_insert (rvk->attrs_head, rvk->attrs_tail, le);
613 /** Now, remove ticket **/
614 rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &rvk->identity, label, 0,
615 NULL, &remove_ticket_cont, rvk);
620 rvk_attrs_err_cb (void *cls)
622 struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
623 rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
628 struct RECLAIM_TICKETS_RevokeHandle *
629 RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket,
630 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
631 RECLAIM_TICKETS_RevokeCallback cb, void *cb_cls)
633 struct RECLAIM_TICKETS_RevokeHandle *rvk;
636 rvk = GNUNET_new (struct RECLAIM_TICKETS_RevokeHandle);
638 rvk->cb_cls = cb_cls;
639 rvk->identity = *identity;
640 rvk->ticket = *ticket;
641 GNUNET_CRYPTO_ecdsa_key_get_public (&rvk->identity, &rvk->ticket.identity);
642 /** Get shared attributes **/
643 label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof (uint64_t));
645 rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (
646 nsh, identity, label, &rvk_attrs_err_cb, rvk, &revoke_attrs_cb, rvk);
652 RECLAIM_TICKETS_revoke_cancel (struct RECLAIM_TICKETS_RevokeHandle *rh)
656 /*******************************
658 *******************************/
661 * Cleanup ticket consume handle
662 * @param cth the handle to clean up
665 cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth)
667 struct ParallelLookup *lu;
668 if (NULL != cth->lookup_request)
669 GNUNET_GNS_lookup_cancel (cth->lookup_request);
670 if (NULL != cth->kill_task)
671 GNUNET_SCHEDULER_cancel (cth->kill_task);
672 while (NULL != (lu = cth->parallel_lookups_head)) {
673 if (NULL != lu->lookup_request)
674 GNUNET_GNS_lookup_cancel (lu->lookup_request);
675 GNUNET_free_non_null (lu->label);
676 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
677 cth->parallel_lookups_tail, lu);
681 if (NULL != cth->attrs)
682 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (cth->attrs);
688 process_parallel_lookup_result (void *cls, uint32_t rd_count,
689 const struct GNUNET_GNSRECORD_Data *rd)
691 struct ParallelLookup *parallel_lookup = cls;
692 struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle;
693 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
694 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Parallel lookup finished (count=%u)\n",
697 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
698 cth->parallel_lookups_tail, parallel_lookup);
699 GNUNET_free (parallel_lookup->label);
701 GNUNET_STATISTICS_update (
702 stats, "attribute_lookup_time_total",
703 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time)
706 GNUNET_STATISTICS_update (stats, "attribute_lookups_count", 1, GNUNET_YES);
709 GNUNET_free (parallel_lookup);
711 GNUNET_break (0); // TODO
712 if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR) {
713 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
715 GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
716 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head, cth->attrs->list_tail,
719 if (NULL != cth->parallel_lookups_head)
720 return; // Wait for more
721 /* Else we are done */
723 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
729 abort_parallel_lookups (void *cls)
731 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
732 struct ParallelLookup *lu;
733 struct ParallelLookup *tmp;
735 cth->kill_task = NULL;
736 for (lu = cth->parallel_lookups_head; NULL != lu;) {
737 GNUNET_GNS_lookup_cancel (lu->lookup_request);
738 GNUNET_free (lu->label);
740 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
741 cth->parallel_lookups_tail, lu);
745 cth->cb (cth->cb_cls, NULL, NULL, GNUNET_SYSERR, "Aborted");
750 lookup_authz_cb (void *cls, uint32_t rd_count,
751 const struct GNUNET_GNSRECORD_Data *rd)
753 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
754 struct ParallelLookup *parallel_lookup;
757 cth->lookup_request = NULL;
759 GNUNET_STATISTICS_update (
760 stats, "reclaim_authz_lookup_time_total",
761 GNUNET_TIME_absolute_get_duration (cth->lookup_start_time).rel_value_us,
763 GNUNET_STATISTICS_update (stats, "reclaim_authz_lookups_count", 1,
766 for (int i = 0; i < rd_count; i++) {
767 if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
769 lbl = GNUNET_STRINGS_data_to_string_alloc (rd[i].data, rd[i].data_size);
770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Attribute ref found %s\n", lbl);
771 parallel_lookup = GNUNET_new (struct ParallelLookup);
772 parallel_lookup->handle = cth;
773 parallel_lookup->label = lbl;
774 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get ();
775 parallel_lookup->lookup_request = GNUNET_GNS_lookup (
776 gns, lbl, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
777 GNUNET_GNS_LO_DEFAULT, &process_parallel_lookup_result,
779 GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head,
780 cth->parallel_lookups_tail, parallel_lookup);
782 if (NULL != cth->parallel_lookups_head) {
783 cth->kill_task = GNUNET_SCHEDULER_add_delayed (
784 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3),
785 &abort_parallel_lookups, cth);
788 cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
793 struct RECLAIM_TICKETS_ConsumeHandle *
794 RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id,
795 const struct GNUNET_RECLAIM_Ticket *ticket,
796 RECLAIM_TICKETS_ConsumeCallback cb, void *cb_cls)
798 struct RECLAIM_TICKETS_ConsumeHandle *cth;
800 cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle);
803 GNUNET_CRYPTO_ecdsa_key_get_public (&cth->identity, &cth->identity_pub);
804 cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
805 cth->ticket = *ticket;
807 cth->cb_cls = cb_cls;
809 GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof (uint64_t));
810 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for AuthZ info under %s\n",
812 cth->lookup_start_time = GNUNET_TIME_absolute_get ();
813 cth->lookup_request = GNUNET_GNS_lookup (
814 gns, label, &cth->ticket.identity, GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF,
815 GNUNET_GNS_LO_DEFAULT, &lookup_authz_cb, cth);
821 RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth)
828 /*******************************
830 *******************************/
833 * Cleanup ticket consume handle
834 * @param handle the handle to clean up
837 cleanup_issue_handle (struct TicketIssueHandle *handle)
839 if (NULL != handle->ns_qe)
840 GNUNET_NAMESTORE_cancel (handle->ns_qe);
841 GNUNET_free (handle);
846 store_ticket_issue_cont (void *cls, int32_t success, const char *emsg)
848 struct TicketIssueHandle *handle = cls;
850 handle->ns_qe = NULL;
851 if (GNUNET_SYSERR == success) {
852 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_SYSERR,
853 "Error storing AuthZ ticket in GNS");
856 handle->cb (handle->cb_cls, &handle->ticket, GNUNET_OK, NULL);
857 cleanup_issue_handle (handle);
862 issue_ticket (struct TicketIssueHandle *ih)
864 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
865 struct GNUNET_GNSRECORD_Data *attrs_record;
870 for (le = ih->attrs->list_head; NULL != le; le = le->next)
874 GNUNET_malloc (list_len * sizeof (struct GNUNET_GNSRECORD_Data));
876 for (le = ih->attrs->list_head; NULL != le; le = le->next) {
877 attrs_record[i].data = &le->claim->id;
878 attrs_record[i].data_size = sizeof (le->claim->id);
879 //FIXME: Should this be the attribute expiration time or ticket refresh intv
880 attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us;
881 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF;
882 attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
885 attrs_record[i].data = &ih->ticket;
886 attrs_record[i].data_size = sizeof (struct GNUNET_RECLAIM_Ticket);
887 attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us;
888 attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET;
889 attrs_record[i].flags =
890 GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
893 GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof (uint64_t));
895 ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh, &ih->identity, label,
896 list_len, attrs_record,
897 &store_ticket_issue_cont, ih);
898 GNUNET_free (attrs_record);
904 RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
905 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
906 const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
907 RECLAIM_TICKETS_TicketResult cb, void *cb_cls)
909 struct TicketIssueHandle *tih;
910 tih = GNUNET_new (struct TicketIssueHandle);
912 tih->cb_cls = cb_cls;
913 tih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
914 tih->identity = *identity;
915 GNUNET_CRYPTO_ecdsa_key_get_public (identity, &tih->ticket.identity);
917 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
918 tih->ticket.audience = *audience;
922 /************************************
924 ************************************/
927 cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter)
929 if (NULL != iter->ns_it)
930 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
936 collect_tickets_cb (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
937 const char *label, unsigned int rd_count,
938 const struct GNUNET_GNSRECORD_Data *rd)
940 struct RECLAIM_TICKETS_Iterator *iter = cls;
942 for (int i = 0; i < rd_count; i++) {
943 if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET != rd[i].record_type)
945 iter->cb (iter->cb_cls, (struct GNUNET_RECLAIM_Ticket *)rd[i].data);
948 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
953 collect_tickets_finished_cb (void *cls)
955 struct RECLAIM_TICKETS_Iterator *iter = cls;
957 iter->cb (iter->cb_cls, NULL);
963 collect_tickets_error_cb (void *cls)
965 struct RECLAIM_TICKETS_Iterator *iter = cls;
967 iter->cb (iter->cb_cls, NULL);
973 RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter)
975 GNUNET_NAMESTORE_zone_iterator_next (iter->ns_it, 1);
980 RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter)
982 GNUNET_NAMESTORE_zone_iteration_stop (iter->ns_it);
987 struct RECLAIM_TICKETS_Iterator *
988 RECLAIM_TICKETS_iteration_start (
989 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
990 RECLAIM_TICKETS_TicketIter cb, void *cb_cls)
992 struct RECLAIM_TICKETS_Iterator *iter;
994 iter = GNUNET_new (struct RECLAIM_TICKETS_Iterator);
996 iter->cb_cls = cb_cls;
997 iter->ns_it = GNUNET_NAMESTORE_zone_iteration_start (
998 nsh, identity, &collect_tickets_error_cb, iter, &collect_tickets_cb, iter,
999 &collect_tickets_finished_cb, iter);
1005 RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
1007 // Get ticket expiration time (relative) from config
1009 == GNUNET_CONFIGURATION_get_value_time (c,
1011 "TICKET_REFRESH_INTERVAL",
1012 &ticket_refresh_interval)) {
1014 GNUNET_ERROR_TYPE_DEBUG,
1015 "Configured refresh interval for tickets: %s\n",
1016 GNUNET_STRINGS_relative_time_to_string (ticket_refresh_interval,
1019 ticket_refresh_interval = DEFAULT_TICKET_REFRESH_INTERVAL;
1021 // Connect to identity and namestore services
1022 nsh = GNUNET_NAMESTORE_connect (c);
1024 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
1025 "error connecting to namestore");
1026 return GNUNET_SYSERR;
1028 gns = GNUNET_GNS_connect (c);
1030 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to gns");
1031 return GNUNET_SYSERR;
1033 stats = GNUNET_STATISTICS_create ("reclaim", c);
1038 RECLAIM_TICKETS_deinit (void)
1041 GNUNET_NAMESTORE_disconnect (nsh);
1044 GNUNET_GNS_disconnect (gns);
1046 if (NULL != stats) {
1047 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);