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
27 #include "gnunet-service-reclaim_tickets.h"
29 struct ParallelLookup;
31 struct RECLAIM_TICKETS_ConsumeHandle
36 struct GNUNET_RECLAIM_Ticket ticket;
41 struct GNUNET_GNS_LookupRequest *lookup_request;
46 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
51 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
56 struct ParallelLookup *parallel_lookups_head;
61 struct ParallelLookup *parallel_lookups_tail;
66 struct GNUNET_SCHEDULER_Task *kill_task;
71 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
76 struct GNUNET_TIME_Absolute lookup_start_time;
81 RECLAIM_TICKETS_ConsumeCallback cb;
91 * Handle for a parallel GNS lookup job
96 struct ParallelLookup *next;
99 struct ParallelLookup *prev;
101 /* The GNS request */
102 struct GNUNET_GNS_LookupRequest *lookup_request;
104 /* The handle the return to */
105 struct RECLAIM_TICKETS_ConsumeHandle *handle;
110 struct GNUNET_TIME_Absolute lookup_start_time;
112 /* The label to look up */
118 * A reference to a ticket stored in GNS
120 struct TicketReference
125 struct TicketReference *next;
130 struct TicketReference *prev;
135 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
140 struct GNUNET_RECLAIM_Ticket ticket;
145 * Ticket issue request handle
147 struct TicketIssueHandle
150 * Attributes to issue
152 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
157 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
162 struct GNUNET_RECLAIM_Ticket ticket;
167 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
170 * Ticket reference list
172 struct TicketReference *ticket_refs_head;
175 * Ticket reference list
177 struct TicketReference *ticket_refs_tail;
180 * Number of references
182 uint32_t ticket_ref_num;
187 RECLAIM_TICKETS_TicketResult cb;
199 struct RECLAIM_TICKETS_Iterator
204 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
209 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
212 * Namestore queue entry
214 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
219 RECLAIM_TICKETS_TicketIter cb;
227 * Ticket reference list
229 struct TicketReference *tickets_head;
232 * Ticket reference list
234 struct TicketReference *tickets_tail;
237 /* Namestore handle */
238 static struct GNUNET_NAMESTORE_Handle *nsh;
241 static struct GNUNET_GNS_Handle *gns;
243 /* Handle to the statistics service */
244 static struct GNUNET_STATISTICS_Handle *stats;
247 create_sym_key_from_ecdh (const struct GNUNET_HashCode *new_key_hash,
248 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
249 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
251 struct GNUNET_CRYPTO_HashAsciiEncoded new_key_hash_str;
253 GNUNET_CRYPTO_hash_to_enc (new_key_hash,
255 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating symmetric rsa key from %s\n", (char*)&new_key_hash_str);
256 static const char ctx_key[] = "gnuid-aes-ctx-key";
257 GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_SymmetricSessionKey),
258 new_key_hash, sizeof (struct GNUNET_HashCode),
259 ctx_key, strlen (ctx_key),
261 static const char ctx_iv[] = "gnuid-aes-ctx-iv";
262 GNUNET_CRYPTO_kdf (iv, sizeof (struct GNUNET_CRYPTO_SymmetricInitializationVector),
263 new_key_hash, sizeof (struct GNUNET_HashCode),
264 ctx_iv, strlen (ctx_iv),
271 * Cleanup ticket consume handle
272 * @param cth the handle to clean up
275 cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth)
277 struct ParallelLookup *lu;
278 struct ParallelLookup *tmp;
279 if (NULL != cth->lookup_request)
280 GNUNET_GNS_lookup_cancel (cth->lookup_request);
281 for (lu = cth->parallel_lookups_head;
283 GNUNET_GNS_lookup_cancel (lu->lookup_request);
284 GNUNET_free (lu->label);
286 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
287 cth->parallel_lookups_tail,
293 if (NULL != cth->attrs)
294 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (cth->attrs);
300 process_parallel_lookup_result (void *cls,
302 const struct GNUNET_GNSRECORD_Data *rd)
304 struct ParallelLookup *parallel_lookup = cls;
305 struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle;
306 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
307 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
308 "Parallel lookup finished (count=%u)\n", rd_count);
310 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
311 cth->parallel_lookups_tail,
313 GNUNET_free (parallel_lookup->label);
315 GNUNET_STATISTICS_update (stats,
316 "attribute_lookup_time_total",
317 GNUNET_TIME_absolute_get_duration (parallel_lookup->lookup_start_time).rel_value_us,
319 GNUNET_STATISTICS_update (stats,
320 "attribute_lookups_count",
325 GNUNET_free (parallel_lookup);
327 GNUNET_break(0);//TODO
328 if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR)
330 attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
331 attr_le->claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data,
333 GNUNET_CONTAINER_DLL_insert (cth->attrs->list_head,
334 cth->attrs->list_tail,
337 if (NULL != cth->parallel_lookups_head)
338 return; //Wait for more
339 /* Else we are done */
341 GNUNET_SCHEDULER_cancel (cth->kill_task);
342 cth->cb (cth->cb_cls,
343 &cth->ticket.identity,
352 abort_parallel_lookups (void *cls)
354 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
355 struct ParallelLookup *lu;
356 struct ParallelLookup *tmp;
358 cth->kill_task = NULL;
359 for (lu = cth->parallel_lookups_head;
361 GNUNET_GNS_lookup_cancel (lu->lookup_request);
362 GNUNET_free (lu->label);
364 GNUNET_CONTAINER_DLL_remove (cth->parallel_lookups_head,
365 cth->parallel_lookups_tail,
370 cth->cb (cth->cb_cls,
381 lookup_authz_cb (void *cls,
383 const struct GNUNET_GNSRECORD_Data *rd)
385 struct RECLAIM_TICKETS_ConsumeHandle *cth = cls;
386 struct GNUNET_HashCode new_key_hash;
387 struct GNUNET_CRYPTO_SymmetricSessionKey enc_key;
388 struct GNUNET_CRYPTO_SymmetricInitializationVector enc_iv;
389 struct GNUNET_CRYPTO_EcdhePublicKey *ecdh_key;
390 struct ParallelLookup *parallel_lookup;
396 cth->lookup_request = NULL;
399 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
400 "Number of keys %d != 1.",
402 cth->cb (cth->cb_cls,
406 "Number of keys %d != 1.");
412 ecdh_key = (struct GNUNET_CRYPTO_EcdhePublicKey *)rd->data;
414 buf = GNUNET_malloc (rd->data_size
415 - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
417 //Calculate symmetric key from ecdh parameters
418 GNUNET_assert (GNUNET_OK ==
419 GNUNET_CRYPTO_ecdsa_ecdh (&cth->identity,
422 create_sym_key_from_ecdh (&new_key_hash,
425 size = GNUNET_CRYPTO_symmetric_decrypt (rd->data
426 + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
428 - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
433 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
434 "Decrypted bytes: %zd Expected bytes: %zd\n",
436 rd->data_size - sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
437 GNUNET_STATISTICS_update (stats,
438 "reclaim_authz_lookup_time_total",
439 GNUNET_TIME_absolute_get_duration (cth->lookup_start_time).rel_value_us,
441 GNUNET_STATISTICS_update (stats,
442 "reclaim_authz_lookups_count",
445 lbls = GNUNET_strdup (buf);
446 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
447 "Attributes found %s\n", lbls);
449 for (attr_lbl = strtok (lbls, ",");
451 attr_lbl = strtok (NULL, ","))
453 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
454 "Looking up %s\n", attr_lbl);
455 parallel_lookup = GNUNET_new (struct ParallelLookup);
456 parallel_lookup->handle = cth;
457 parallel_lookup->label = GNUNET_strdup (attr_lbl);
458 parallel_lookup->lookup_start_time = GNUNET_TIME_absolute_get();
459 parallel_lookup->lookup_request
460 = GNUNET_GNS_lookup (gns,
462 &cth->ticket.identity,
463 GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR,
464 GNUNET_GNS_LO_DEFAULT,
465 &process_parallel_lookup_result,
467 GNUNET_CONTAINER_DLL_insert (cth->parallel_lookups_head,
468 cth->parallel_lookups_tail,
473 cth->kill_task = GNUNET_SCHEDULER_add_delayed (
474 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES,3),
475 &abort_parallel_lookups,
481 struct RECLAIM_TICKETS_ConsumeHandle*
482 RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id,
483 const struct GNUNET_RECLAIM_Ticket *ticket,
484 RECLAIM_TICKETS_ConsumeCallback cb,
487 struct RECLAIM_TICKETS_ConsumeHandle *cth;
489 cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle);
492 GNUNET_CRYPTO_ecdsa_key_get_public (&cth->identity,
494 cth->attrs = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
495 cth->ticket = *ticket;
497 cth->cb_cls = cb_cls;
498 label = GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd,
500 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
501 "Looking for AuthZ info under %s\n", label);
502 cth->lookup_start_time = GNUNET_TIME_absolute_get ();
503 cth->lookup_request = GNUNET_GNS_lookup (gns,
505 &cth->ticket.identity,
506 GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ,
507 GNUNET_GNS_LO_DEFAULT,
515 RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth)
522 /*******************************
524 *******************************/
527 * Cleanup ticket consume handle
528 * @param handle the handle to clean up
531 cleanup_issue_handle (struct TicketIssueHandle *handle)
533 struct TicketReference *tr;
534 struct TicketReference *tr_tmp;
535 if (NULL != handle->attrs)
536 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (handle->attrs);
537 if (NULL != handle->ns_qe)
538 GNUNET_NAMESTORE_cancel (handle->ns_qe);
539 for (tr = handle->ticket_refs_head; NULL != tr;)
541 if (NULL != tr->attrs)
542 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (tr->attrs);
545 GNUNET_free (tr_tmp);
547 GNUNET_free (handle);
553 store_ticket_refs_cont (void *cls,
557 struct TicketIssueHandle *handle = cls;
558 handle->ns_qe = NULL;
559 if (GNUNET_OK != success)
561 handle->cb (handle->cb_cls,
564 "Error storing updated ticket refs in GNS");
565 cleanup_issue_handle (handle);
568 handle->cb (handle->cb_cls,
572 cleanup_issue_handle (handle);
578 update_ticket_refs (void* cls)
580 struct TicketIssueHandle *handle = cls;
581 struct GNUNET_GNSRECORD_Data refs_rd[handle->ticket_ref_num];
582 struct TicketReference *tr;
586 tr = handle->ticket_refs_head;
587 for (int i = 0; i < handle->ticket_ref_num; i++)
589 buf_size = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (tr->attrs);
590 buf_size += sizeof (struct GNUNET_RECLAIM_Ticket);
591 buf = GNUNET_malloc (buf_size);
592 memcpy (buf, &tr->ticket, sizeof (struct GNUNET_RECLAIM_Ticket));
593 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (tr->attrs,
594 buf + sizeof (struct GNUNET_RECLAIM_Ticket));
595 refs_rd[i].data = buf;
596 refs_rd[i].data_size = buf_size;
597 refs_rd[i].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
598 refs_rd[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF;
599 refs_rd[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION |
600 GNUNET_GNSRECORD_RF_PRIVATE;
604 handle->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
606 GNUNET_GNS_EMPTY_LABEL_AT,
607 handle->ticket_ref_num,
609 &store_ticket_refs_cont,
611 for (int i = 0; i < handle->ticket_ref_num; i++)
612 GNUNET_free ((char*)refs_rd[i].data);
618 ticket_lookup_cb (void *cls,
619 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
621 unsigned int rd_count,
622 const struct GNUNET_GNSRECORD_Data *rd)
624 struct TicketIssueHandle *handle = cls;
625 struct TicketReference *tr;
626 const char* attr_data;
627 size_t attr_data_len;
628 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
629 "Received tickets from local namestore.\n");
630 handle->ns_qe = NULL;
631 for (int i = 0; i < rd_count; i++)
633 if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF != rd[i].record_type)
635 tr = GNUNET_new (struct TicketReference);
636 memcpy (&tr->ticket, rd[i].data,
637 sizeof (struct GNUNET_RECLAIM_Ticket));
638 if (0 != memcmp (&tr->ticket.identity,
639 &handle->ticket.identity,
640 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
646 attr_data = rd[i].data + sizeof (struct GNUNET_RECLAIM_Ticket);
647 attr_data_len = rd[i].data_size - sizeof (struct GNUNET_RECLAIM_Ticket);
648 tr->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attr_data,
650 GNUNET_CONTAINER_DLL_insert (handle->ticket_refs_head,
651 handle->ticket_refs_tail,
653 handle->ticket_ref_num++;
655 tr = GNUNET_new (struct TicketReference);
656 tr->ticket = handle->ticket;
657 tr->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (handle->attrs);
658 GNUNET_CONTAINER_DLL_insert (handle->ticket_refs_head,
659 handle->ticket_refs_tail,
661 handle->ticket_ref_num++;
662 GNUNET_SCHEDULER_add_now (&update_ticket_refs, handle);
666 ticket_lookup_error_cb (void *cls)
668 struct TicketIssueHandle *handle = cls;
669 handle->ns_qe = NULL;
670 handle->cb (handle->cb_cls,
673 "Error checking for ticketsin GNS\n");
674 cleanup_issue_handle (handle);
678 store_ticket_issue_cont (void *cls,
682 struct TicketIssueHandle *handle = cls;
684 handle->ns_qe = NULL;
685 if (GNUNET_SYSERR == success)
687 handle->cb (handle->cb_cls,
690 "Error storing AuthZ ticket in GNS");
693 /* First, local references to tickets */
694 handle->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
696 GNUNET_GNS_EMPTY_LABEL_AT,
697 &ticket_lookup_error_cb,
705 serialize_authz_record (const struct GNUNET_RECLAIM_Ticket *ticket,
706 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
707 struct GNUNET_CRYPTO_EcdhePrivateKey **ecdh_privkey,
710 struct GNUNET_CRYPTO_EcdhePublicKey ecdh_pubkey;
711 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
712 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
713 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
714 struct GNUNET_HashCode new_key_hash;
722 GNUNET_assert (NULL != attrs->list_head);
724 for (le = attrs->list_head; NULL != le; le = le->next) {
725 attrs_str_len += 15 + 1; //TODO propery calculate
727 buf = GNUNET_malloc (attrs_str_len);
729 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
730 "Writing attributes\n");
731 for (le = attrs->list_head; NULL != le; le = le->next) {
732 label = GNUNET_STRINGS_data_to_string_alloc (&le->claim->id,
734 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
735 "Adding attribute to record: %s\n", label);
737 GNUNET_memcpy (write_ptr,
740 write_ptr[strlen (label)] = ',';
741 write_ptr += strlen (label) + 1;
745 write_ptr[0] = '\0'; //replace last , with a 0-terminator
746 // ECDH keypair E = eG
747 *ecdh_privkey = GNUNET_CRYPTO_ecdhe_key_create();
748 GNUNET_CRYPTO_ecdhe_key_get_public (*ecdh_privkey,
750 enc_keyinfo = GNUNET_malloc (attrs_str_len);
751 // Derived key K = H(eB)
752 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdh_ecdsa (*ecdh_privkey,
755 create_sym_key_from_ecdh (&new_key_hash, &skey, &iv);
756 enc_size = GNUNET_CRYPTO_symmetric_encrypt (buf,
760 *result = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+
762 GNUNET_memcpy (*result,
764 sizeof (struct GNUNET_CRYPTO_EcdhePublicKey));
765 GNUNET_memcpy (*result + sizeof (struct GNUNET_CRYPTO_EcdhePublicKey),
768 GNUNET_free (enc_keyinfo);
770 return sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)+enc_size;
776 issue_ticket (struct TicketIssueHandle *ih)
778 struct GNUNET_CRYPTO_EcdhePrivateKey *ecdhe_privkey;
779 struct GNUNET_GNSRECORD_Data code_record[1];
780 char *authz_record_data;
781 size_t authz_record_len;
784 //TODO rename function
785 authz_record_len = serialize_authz_record (&ih->ticket,
789 code_record[0].data = authz_record_data;
790 code_record[0].data_size = authz_record_len;
791 code_record[0].expiration_time = GNUNET_TIME_UNIT_DAYS.rel_value_us;
792 code_record[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_AUTHZ;
793 code_record[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
795 label = GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd,
798 ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
803 &store_ticket_issue_cont,
805 GNUNET_free (ecdhe_privkey);
807 GNUNET_free (authz_record_data);
814 RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
815 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
816 const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
817 RECLAIM_TICKETS_TicketResult cb,
820 struct TicketIssueHandle *tih;
821 tih = GNUNET_new (struct TicketIssueHandle);
823 tih->cb_cls = cb_cls;
824 tih->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_dup (attrs);
825 tih->identity = *identity;
826 GNUNET_CRYPTO_ecdsa_key_get_public (identity,
827 &tih->ticket.identity);
829 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
831 tih->ticket.audience = *audience;
835 /************************************
837 ************************************/
840 cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter)
842 struct TicketReference *tr;
843 struct TicketReference *tr_tmp;
844 if (NULL != iter->ns_qe)
845 GNUNET_NAMESTORE_cancel (iter->ns_qe);
846 for (tr = iter->tickets_head; NULL != tr;)
848 if (NULL != tr->attrs)
849 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (tr->attrs);
852 GNUNET_free (tr_tmp);
858 do_cleanup_iter (void* cls)
860 struct RECLAIM_TICKETS_Iterator *iter = cls;
865 * Perform ticket iteration step
867 * @param ti ticket iterator to process
870 run_ticket_iteration_round (struct RECLAIM_TICKETS_Iterator *iter)
872 struct TicketReference *tr;
873 if (NULL == iter->tickets_head)
876 iter->cb (iter->cb_cls,
878 GNUNET_SCHEDULER_add_now (&do_cleanup_iter, iter);
881 tr = iter->tickets_head;
882 GNUNET_CONTAINER_DLL_remove (iter->tickets_head,
885 iter->cb (iter->cb_cls,
887 if (NULL != tr->attrs)
888 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (tr->attrs);
893 collect_tickets_cb (void *cls,
894 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
896 unsigned int rd_count,
897 const struct GNUNET_GNSRECORD_Data *rd)
899 struct RECLAIM_TICKETS_Iterator *iter = cls;
900 struct TicketReference *tr;
901 size_t attr_data_len;
902 const char* attr_data;
905 for (int i = 0; i < rd_count; i++)
907 if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF != rd[i].record_type)
909 tr = GNUNET_new (struct TicketReference);
910 memcpy (&tr->ticket, rd[i].data,
911 sizeof (struct GNUNET_RECLAIM_Ticket));
912 if (0 != memcmp (&tr->ticket.identity,
914 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
920 attr_data = rd[i].data + sizeof (struct GNUNET_RECLAIM_Ticket);
921 attr_data_len = rd[i].data_size - sizeof (struct GNUNET_RECLAIM_Ticket);
922 tr->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attr_data,
924 GNUNET_CONTAINER_DLL_insert (iter->tickets_head,
928 run_ticket_iteration_round (iter);
932 collect_tickets_error_cb (void *cls)
934 struct RECLAIM_TICKETS_Iterator *iter = cls;
936 iter->cb (iter->cb_cls,
942 RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter)
944 run_ticket_iteration_round (iter);
948 RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter)
953 struct RECLAIM_TICKETS_Iterator*
954 RECLAIM_TICKETS_iteration_start (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
955 RECLAIM_TICKETS_TicketIter cb,
958 struct RECLAIM_TICKETS_Iterator *iter;
960 iter = GNUNET_new (struct RECLAIM_TICKETS_Iterator);
961 iter->identity = *identity;
962 GNUNET_CRYPTO_ecdsa_key_get_public (identity,
963 &iter->identity_pub);
965 iter->cb_cls = cb_cls;
966 iter->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
968 GNUNET_GNS_EMPTY_LABEL_AT,
969 &collect_tickets_error_cb,
980 RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
982 //Connect to identity and namestore services
983 nsh = GNUNET_NAMESTORE_connect (c);
986 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
987 "error connecting to namestore");
988 return GNUNET_SYSERR;
990 gns = GNUNET_GNS_connect (c);
993 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
994 "error connecting to gns");
995 return GNUNET_SYSERR;
997 stats = GNUNET_STATISTICS_create ("reclaim", c);
1002 RECLAIM_TICKETS_deinit (void)
1005 GNUNET_NAMESTORE_disconnect (nsh);
1008 GNUNET_GNS_disconnect (gns);
1012 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);