aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim/gnunet-service-reclaim.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/reclaim/gnunet-service-reclaim.c')
-rw-r--r--src/reclaim/gnunet-service-reclaim.c2504
1 files changed, 0 insertions, 2504 deletions
diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c
deleted file mode 100644
index 84a98d1e4..000000000
--- a/src/reclaim/gnunet-service-reclaim.c
+++ /dev/null
@@ -1,2504 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 GNUnet e.V.
4
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.
9
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.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @author Martin Schanzenbach
22 * @file src/reclaim/gnunet-service-reclaim.c
23 * @brief reclaim Service
24 *
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet-service-reclaim_tickets.h"
29#include "gnunet_constants.h"
30#include "gnunet_gnsrecord_lib.h"
31#include "gnunet_protocols.h"
32#include "gnunet_reclaim_lib.h"
33#include "gnunet_reclaim_service.h"
34#include "gnunet_signatures.h"
35#include "reclaim.h"
36
37
38/**
39 * Namestore handle
40 */
41static struct GNUNET_NAMESTORE_Handle *nsh;
42
43/**
44 * Timeout task
45 */
46static struct GNUNET_SCHEDULER_Task *timeout_task;
47
48/**
49 * Our configuration.
50 */
51static const struct GNUNET_CONFIGURATION_Handle *cfg;
52
53/**
54 * An idp client
55 */
56struct IdpClient;
57
58/**
59 * A ticket iteration operation.
60 */
61struct TicketIteration
62{
63 /**
64 * DLL
65 */
66 struct TicketIteration *next;
67
68 /**
69 * DLL
70 */
71 struct TicketIteration *prev;
72
73 /**
74 * Client which intiated this zone iteration
75 */
76 struct IdpClient *client;
77
78 /**
79 * The operation id for the iteration in the response for the client
80 */
81 uint32_t r_id;
82
83 /**
84 * The ticket iterator
85 */
86 struct RECLAIM_TICKETS_Iterator *iter;
87};
88
89
90/**
91 * An attribute iteration operation.
92 */
93struct Iterator
94{
95 /**
96 * Next element in the DLL
97 */
98 struct Iterator *next;
99
100 /**
101 * Previous element in the DLL
102 */
103 struct Iterator *prev;
104
105 /**
106 * IDP client which intiated this zone iteration
107 */
108 struct IdpClient *client;
109
110 /**
111 * Key of the zone we are iterating over.
112 */
113 struct GNUNET_IDENTITY_PrivateKey identity;
114
115 /**
116 * Namestore iterator
117 */
118 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
119
120 /**
121 * The operation id for the zone iteration in the response for the client
122 */
123 uint32_t request_id;
124
125 /**
126 * Context
127 */
128 void *ctx;
129};
130
131
132/**
133 * An idp client
134 */
135struct IdpClient
136{
137 /**
138 * DLL
139 */
140 struct IdpClient *prev;
141
142 /**
143 * DLL
144 */
145 struct IdpClient *next;
146
147 /**
148 * The client
149 */
150 struct GNUNET_SERVICE_Client *client;
151
152 /**
153 * Message queue for transmission to @e client
154 */
155 struct GNUNET_MQ_Handle *mq;
156
157 /**
158 * Head of the DLL of
159 * Attribute iteration operations in
160 * progress initiated by this client
161 */
162 struct Iterator *attr_iter_head;
163
164 /**
165 * Tail of the DLL of
166 * Attribute iteration operations
167 * in progress initiated by this client
168 */
169 struct Iterator *attr_iter_tail;
170
171 /**
172 * Head of the DLL of
173 * Credential iteration operations in
174 * progress initiated by this client
175 */
176 struct Iterator *cred_iter_head;
177
178 /**
179 * Tail of the DLL of
180 * Credential iteration operations
181 * in progress initiated by this client
182 */
183 struct Iterator *cred_iter_tail;
184
185 /**
186 * Head of DLL of ticket iteration ops
187 */
188 struct TicketIteration *ticket_iter_head;
189
190 /**
191 * Tail of DLL of ticket iteration ops
192 */
193 struct TicketIteration *ticket_iter_tail;
194
195 /**
196 * Head of DLL of ticket revocation ops
197 */
198 struct TicketRevocationOperation *revoke_op_head;
199
200 /**
201 * Tail of DLL of ticket revocation ops
202 */
203 struct TicketRevocationOperation *revoke_op_tail;
204
205 /**
206 * Head of DLL of ticket issue ops
207 */
208 struct TicketIssueOperation *issue_op_head;
209
210 /**
211 * Tail of DLL of ticket issue ops
212 */
213 struct TicketIssueOperation *issue_op_tail;
214
215 /**
216 * Head of DLL of ticket consume ops
217 */
218 struct ConsumeTicketOperation *consume_op_head;
219
220 /**
221 * Tail of DLL of ticket consume ops
222 */
223 struct ConsumeTicketOperation *consume_op_tail;
224
225 /**
226 * Head of DLL of attribute store ops
227 */
228 struct AttributeStoreHandle *store_op_head;
229
230 /**
231 * Tail of DLL of attribute store ops
232 */
233 struct AttributeStoreHandle *store_op_tail;
234 /**
235 * Head of DLL of attribute delete ops
236 */
237 struct AttributeDeleteHandle *delete_op_head;
238
239 /**
240 * Tail of DLL of attribute delete ops
241 */
242 struct AttributeDeleteHandle *delete_op_tail;
243};
244
245
246/**
247 * Handle for attribute deletion request
248 */
249struct AttributeDeleteHandle
250{
251 /**
252 * DLL
253 */
254 struct AttributeDeleteHandle *next;
255
256 /**
257 * DLL
258 */
259 struct AttributeDeleteHandle *prev;
260
261 /**
262 * Client connection
263 */
264 struct IdpClient *client;
265
266 /**
267 * Identity
268 */
269 struct GNUNET_IDENTITY_PrivateKey identity;
270
271
272 /**
273 * QueueEntry
274 */
275 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
276
277 /**
278 * Iterator
279 */
280 struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
281
282 /**
283 * The attribute to delete
284 */
285 struct GNUNET_RECLAIM_Attribute *claim;
286
287 /**
288 * The credential to delete
289 */
290 struct GNUNET_RECLAIM_Credential *credential;
291
292 /**
293 * Tickets to update
294 */
295 struct TicketRecordsEntry *tickets_to_update_head;
296
297 /**
298 * Tickets to update
299 */
300 struct TicketRecordsEntry *tickets_to_update_tail;
301
302 /**
303 * Existing attributes
304 */
305 struct GNUNET_RECLAIM_AttributeList *existing_attributes;
306
307 /**
308 * Existing credentials
309 */
310 struct GNUNET_RECLAIM_CredentialList *existing_credentials;
311
312 /**
313 * Attribute label
314 */
315 char *label;
316
317 /**
318 * request id
319 */
320 uint32_t r_id;
321};
322
323
324/**
325 * Handle for attribute store request
326 */
327struct AttributeStoreHandle
328{
329 /**
330 * DLL
331 */
332 struct AttributeStoreHandle *next;
333
334 /**
335 * DLL
336 */
337 struct AttributeStoreHandle *prev;
338
339 /**
340 * Client connection
341 */
342 struct IdpClient *client;
343
344 /**
345 * Identity
346 */
347 struct GNUNET_IDENTITY_PrivateKey identity;
348
349 /**
350 * Identity pubkey
351 */
352 struct GNUNET_IDENTITY_PublicKey identity_pkey;
353
354 /**
355 * QueueEntry
356 */
357 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
358
359 /**
360 * The attribute to store
361 */
362 struct GNUNET_RECLAIM_Attribute *claim;
363
364 /**
365 * The credential to store
366 */
367 struct GNUNET_RECLAIM_Credential *credential;
368
369 /**
370 * The attribute expiration interval
371 */
372 struct GNUNET_TIME_Relative exp;
373
374 /**
375 * request id
376 */
377 uint32_t r_id;
378};
379
380
381/**
382 * Handle for ticket consume request
383 */
384struct ConsumeTicketOperation
385{
386 /**
387 * DLL
388 */
389 struct ConsumeTicketOperation *next;
390
391 /**
392 * DLL
393 */
394 struct ConsumeTicketOperation *prev;
395
396 /**
397 * Client connection
398 */
399 struct IdpClient *client;
400
401 /**
402 * request id
403 */
404 uint32_t r_id;
405
406 /**
407 * Ticket consume handle
408 */
409 struct RECLAIM_TICKETS_ConsumeHandle *ch;
410};
411
412
413/**
414 * Ticket revocation request handle
415 */
416struct TicketRevocationOperation
417{
418 /**
419 * DLL
420 */
421 struct TicketRevocationOperation *prev;
422
423 /**
424 * DLL
425 */
426 struct TicketRevocationOperation *next;
427
428 /**
429 * Client connection
430 */
431 struct IdpClient *client;
432
433 /**
434 * Revocation handle
435 */
436 struct RECLAIM_TICKETS_RevokeHandle *rh;
437
438 /**
439 * request id
440 */
441 uint32_t r_id;
442};
443
444
445/**
446 * Ticket issue operation handle
447 */
448struct TicketIssueOperation
449{
450 /**
451 * DLL
452 */
453 struct TicketIssueOperation *prev;
454
455 /**
456 * DLL
457 */
458 struct TicketIssueOperation *next;
459
460 /**
461 * Client connection
462 */
463 struct IdpClient *client;
464
465 /**
466 * request id
467 */
468 uint32_t r_id;
469};
470
471
472/**
473 * Client list
474 */
475static struct IdpClient *client_list_head = NULL;
476
477/**
478 * Client list
479 */
480static struct IdpClient *client_list_tail = NULL;
481
482
483/**
484 * Cleanup attribute delete handle
485 *
486 * @param adh the attribute to cleanup
487 */
488static void
489cleanup_adh (struct AttributeDeleteHandle *adh)
490{
491 struct TicketRecordsEntry *le;
492
493 if (NULL != adh->ns_it)
494 GNUNET_NAMESTORE_zone_iteration_stop (adh->ns_it);
495 if (NULL != adh->ns_qe)
496 GNUNET_NAMESTORE_cancel (adh->ns_qe);
497 if (NULL != adh->label)
498 GNUNET_free (adh->label);
499 if (NULL != adh->claim)
500 GNUNET_free (adh->claim);
501 if (NULL != adh->credential)
502 GNUNET_free (adh->credential);
503 if (NULL != adh->existing_credentials)
504 GNUNET_RECLAIM_credential_list_destroy (adh->existing_credentials);
505 if (NULL != adh->existing_attributes)
506 GNUNET_RECLAIM_attribute_list_destroy (adh->existing_attributes);
507 while (NULL != (le = adh->tickets_to_update_head))
508 {
509 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
510 adh->tickets_to_update_tail,
511 le);
512 if (NULL != le->label)
513 GNUNET_free (le->label);
514 if (NULL != le->data)
515 GNUNET_free (le->data);
516 GNUNET_free (le);
517 }
518 GNUNET_free (adh);
519}
520
521
522/**
523 * Cleanup attribute store handle
524 *
525 * @param handle handle to clean up
526 */
527static void
528cleanup_as_handle (struct AttributeStoreHandle *ash)
529{
530 if (NULL != ash->ns_qe)
531 GNUNET_NAMESTORE_cancel (ash->ns_qe);
532 if (NULL != ash->claim)
533 GNUNET_free (ash->claim);
534 if (NULL != ash->credential)
535 GNUNET_free (ash->credential);
536 GNUNET_free (ash);
537}
538
539
540/**
541 * Cleanup client
542 *
543 * @param idp the client to clean up
544 */
545static void
546cleanup_client (struct IdpClient *idp)
547{
548 struct Iterator *ai;
549 struct TicketIteration *ti;
550 struct TicketRevocationOperation *rop;
551 struct TicketIssueOperation *iss;
552 struct ConsumeTicketOperation *ct;
553 struct AttributeStoreHandle *as;
554 struct AttributeDeleteHandle *adh;
555
556 while (NULL != (iss = idp->issue_op_head))
557 {
558 GNUNET_CONTAINER_DLL_remove (idp->issue_op_head, idp->issue_op_tail, iss);
559 GNUNET_free (iss);
560 }
561 while (NULL != (ct = idp->consume_op_head))
562 {
563 GNUNET_CONTAINER_DLL_remove (idp->consume_op_head,
564 idp->consume_op_tail,
565 ct);
566 if (NULL != ct->ch)
567 RECLAIM_TICKETS_consume_cancel (ct->ch);
568 GNUNET_free (ct);
569 }
570 while (NULL != (as = idp->store_op_head))
571 {
572 GNUNET_CONTAINER_DLL_remove (idp->store_op_head, idp->store_op_tail, as);
573 cleanup_as_handle (as);
574 }
575 while (NULL != (adh = idp->delete_op_head))
576 {
577 GNUNET_CONTAINER_DLL_remove (idp->delete_op_head, idp->delete_op_tail, adh);
578 cleanup_adh (adh);
579 }
580
581 while (NULL != (ai = idp->attr_iter_head))
582 {
583 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
584 GNUNET_free (ai);
585 }
586 while (NULL != (ai = idp->cred_iter_head))
587 {
588 GNUNET_CONTAINER_DLL_remove (idp->cred_iter_head, idp->cred_iter_tail,
589 ai);
590 GNUNET_free (ai);
591 }
592
593 while (NULL != (rop = idp->revoke_op_head))
594 {
595 GNUNET_CONTAINER_DLL_remove (idp->revoke_op_head, idp->revoke_op_tail, rop);
596 if (NULL != rop->rh)
597 RECLAIM_TICKETS_revoke_cancel (rop->rh);
598 GNUNET_free (rop);
599 }
600 while (NULL != (ti = idp->ticket_iter_head))
601 {
602 GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head,
603 idp->ticket_iter_tail,
604 ti);
605 if (NULL != ti->iter)
606 RECLAIM_TICKETS_iteration_stop (ti->iter);
607 GNUNET_free (ti);
608 }
609 GNUNET_free (idp);
610}
611
612
613/**
614 * Cleanup task
615 */
616static void
617cleanup ()
618{
619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
620
621 RECLAIM_TICKETS_deinit ();
622 if (NULL != timeout_task)
623 GNUNET_SCHEDULER_cancel (timeout_task);
624 if (NULL != nsh)
625 GNUNET_NAMESTORE_disconnect (nsh);
626}
627
628
629/**
630 * Shutdown task
631 *
632 * @param cls NULL
633 */
634static void
635do_shutdown (void *cls)
636{
637 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
638 cleanup ();
639}
640
641
642/**
643 * Sends a ticket result message to the client
644 *
645 * @param client the client to send to
646 * @param r_id the request message ID to reply to
647 * @param ticket the ticket to include (may be NULL)
648 * @param success the success status of the request
649 */
650static void
651send_ticket_result (const struct IdpClient *client,
652 uint32_t r_id,
653 const struct GNUNET_RECLAIM_Ticket *ticket,
654 const struct GNUNET_RECLAIM_PresentationList *presentations,
655 uint32_t success)
656{
657 struct TicketResultMessage *irm;
658 struct GNUNET_MQ_Envelope *env;
659 size_t pres_len = 0;
660
661 if (NULL != presentations)
662 {
663 pres_len =
664 GNUNET_RECLAIM_presentation_list_serialize_get_size (presentations);
665 }
666 env = GNUNET_MQ_msg_extra (irm,
667 pres_len,
668 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
669 if (NULL != ticket)
670 {
671 irm->ticket = *ticket;
672 }
673 // TODO add success member
674 irm->id = htonl (r_id);
675 irm->presentations_len = htons (pres_len);
676 if (NULL != presentations)
677 {
678 GNUNET_RECLAIM_presentation_list_serialize (presentations,
679 (char*) &irm[1]);
680 }
681 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
682 GNUNET_MQ_send (client->mq, env);
683}
684
685
686/**
687 * Issue ticket result
688 *
689 * @param cls out ticket issue operation handle
690 * @param ticket the issued ticket
691 * @param presentations newly created credential presentations (NULL on error)
692 * @param success issue success status (GNUNET_OK if successful)
693 * @param emsg error message (NULL of success is GNUNET_OK)
694 */
695static void
696issue_ticket_result_cb (void *cls,
697 struct GNUNET_RECLAIM_Ticket *ticket,
698 struct GNUNET_RECLAIM_PresentationList *presentations,
699 int32_t success,
700 const char *emsg)
701{
702 struct TicketIssueOperation *tio = cls;
703
704 if (GNUNET_OK != success)
705 {
706 send_ticket_result (tio->client, tio->r_id, NULL, NULL, GNUNET_SYSERR);
707 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
708 tio->client->issue_op_tail,
709 tio);
710 GNUNET_free (tio);
711 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error issuing ticket: %s\n", emsg);
712 return;
713 }
714 send_ticket_result (tio->client, tio->r_id,
715 ticket, presentations, GNUNET_SYSERR);
716 GNUNET_CONTAINER_DLL_remove (tio->client->issue_op_head,
717 tio->client->issue_op_tail,
718 tio);
719 GNUNET_free (tio);
720}
721
722
723/**
724 * Check issue ticket message
725 *
726 * @cls unused
727 * @im message to check
728 * @return GNUNET_OK if message is ok
729 */
730static int
731check_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
732{
733 uint16_t size;
734 size_t attrs_len;
735
736 size = ntohs (im->header.size);
737 attrs_len = ntohs (im->attr_len);
738
739 if (attrs_len > size - sizeof(struct IssueTicketMessage))
740 {
741 GNUNET_break (0);
742 return GNUNET_SYSERR;
743 }
744 return GNUNET_OK;
745}
746
747
748/**
749 * Handle ticket issue message
750 *
751 * @param cls our client
752 * @param im the message
753 */
754static void
755handle_issue_ticket_message (void *cls, const struct IssueTicketMessage *im)
756{
757 struct TicketIssueOperation *tio;
758 struct IdpClient *idp = cls;
759 struct GNUNET_RECLAIM_AttributeList *attrs;
760 struct GNUNET_RECLAIM_AttributeListEntry *le;
761 size_t attrs_len;
762
763 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ISSUE_TICKET message\n");
764 tio = GNUNET_new (struct TicketIssueOperation);
765 attrs_len = ntohs (im->attr_len);
766 attrs = GNUNET_RECLAIM_attribute_list_deserialize ((char *) &im[1],
767 attrs_len);
768 for (le = attrs->list_head; NULL != le; le = le->next)
769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
770 "List entry: %s\n", le->attribute->name);
771
772 tio->r_id = ntohl (im->id);
773 tio->client = idp;
774 GNUNET_CONTAINER_DLL_insert (idp->issue_op_head, idp->issue_op_tail, tio);
775 RECLAIM_TICKETS_issue (&im->identity,
776 attrs,
777 &im->rp,
778 &issue_ticket_result_cb,
779 tio);
780 GNUNET_SERVICE_client_continue (idp->client);
781 GNUNET_RECLAIM_attribute_list_destroy (attrs);
782}
783
784
785/**********************************************************
786* Revocation
787**********************************************************/
788
789/**
790 * Handles revocation result
791 *
792 * @param cls our revocation operation handle
793 * @param success revocation result (GNUNET_OK if successful)
794 */
795static void
796revoke_result_cb (void *cls, int32_t success)
797{
798 struct TicketRevocationOperation *rop = cls;
799 struct GNUNET_MQ_Envelope *env;
800 struct RevokeTicketResultMessage *trm;
801
802 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
803 "Sending REVOKE_TICKET_RESULT message\n");
804 rop->rh = NULL;
805 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT);
806 trm->id = htonl (rop->r_id);
807 trm->success = htonl (success);
808 GNUNET_MQ_send (rop->client->mq, env);
809 GNUNET_CONTAINER_DLL_remove (rop->client->revoke_op_head,
810 rop->client->revoke_op_tail,
811 rop);
812 GNUNET_free (rop);
813}
814
815
816/**
817 * Check revocation message format
818 *
819 * @param cls unused
820 * @param im the message to check
821 * @return GNUNET_OK if message is ok
822 */
823static int
824check_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *im)
825{
826 uint16_t size;
827
828 size = ntohs (im->header.size);
829 if (size != sizeof(struct RevokeTicketMessage))
830 {
831 GNUNET_break (0);
832 return GNUNET_SYSERR;
833 }
834 return GNUNET_OK;
835}
836
837
838/**
839 * Handle a revocation message to a ticket.
840 *
841 * @param cls our client
842 * @param rm the message to handle
843 */
844static void
845handle_revoke_ticket_message (void *cls, const struct RevokeTicketMessage *rm)
846{
847 struct TicketRevocationOperation *rop;
848 struct IdpClient *idp = cls;
849
850 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REVOKE_TICKET message\n");
851 rop = GNUNET_new (struct TicketRevocationOperation);
852 rop->r_id = ntohl (rm->id);
853 rop->client = idp;
854 GNUNET_CONTAINER_DLL_insert (idp->revoke_op_head, idp->revoke_op_tail, rop);
855 rop->rh
856 = RECLAIM_TICKETS_revoke (&rm->ticket, &rm->identity, &revoke_result_cb,
857 rop);
858 GNUNET_SERVICE_client_continue (idp->client);
859}
860
861
862/**
863 * Handle a ticket consume result
864 *
865 * @param cls our consume ticket operation handle
866 * @param identity the attribute authority
867 * @param attrs the attribute/claim list
868 * @param success GNUNET_OK if successful
869 * @param emsg error message (NULL if success=GNUNET_OK)
870 */
871static void
872consume_result_cb (void *cls,
873 const struct GNUNET_IDENTITY_PublicKey *identity,
874 const struct GNUNET_RECLAIM_AttributeList *attrs,
875 const struct GNUNET_RECLAIM_PresentationList *presentations,
876 int32_t success,
877 const char *emsg)
878{
879 struct ConsumeTicketOperation *cop = cls;
880 struct ConsumeTicketResultMessage *crm;
881 struct GNUNET_MQ_Envelope *env;
882 char *data_tmp;
883 size_t attrs_len = 0;
884 size_t pres_len = 0;
885
886 if (GNUNET_OK != success)
887 {
888 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error consuming ticket: %s\n", emsg);
889 }
890 attrs_len = GNUNET_RECLAIM_attribute_list_serialize_get_size (attrs);
891 pres_len = GNUNET_RECLAIM_presentation_list_serialize_get_size (
892 presentations);
893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
894 "Sending CONSUME_TICKET_RESULT message\n");
895 env = GNUNET_MQ_msg_extra (crm,
896 attrs_len + pres_len,
897 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT);
898 crm->id = htonl (cop->r_id);
899 crm->attrs_len = htons (attrs_len);
900 crm->presentations_len = htons (pres_len);
901 crm->identity = *identity;
902 crm->result = htonl (success);
903 data_tmp = (char *) &crm[1];
904 GNUNET_RECLAIM_attribute_list_serialize (attrs, data_tmp);
905 data_tmp += attrs_len;
906 GNUNET_RECLAIM_presentation_list_serialize (presentations, data_tmp);
907 GNUNET_MQ_send (cop->client->mq, env);
908 GNUNET_CONTAINER_DLL_remove (cop->client->consume_op_head,
909 cop->client->consume_op_tail,
910 cop);
911 GNUNET_free (cop);
912}
913
914
915/**
916 * Check a consume ticket message
917 *
918 * @param cls unused
919 * @param cm the message to handle
920 */
921static int
922check_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
923{
924 uint16_t size;
925
926 size = ntohs (cm->header.size);
927 if (size != sizeof(struct ConsumeTicketMessage))
928 {
929 GNUNET_break (0);
930 return GNUNET_SYSERR;
931 }
932 return GNUNET_OK;
933}
934
935
936/**
937 * Handle a consume ticket message
938 *
939 * @param cls our client handle
940 * @cm the message to handle
941 */
942static void
943handle_consume_ticket_message (void *cls, const struct ConsumeTicketMessage *cm)
944{
945 struct ConsumeTicketOperation *cop;
946 struct IdpClient *idp = cls;
947
948 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CONSUME_TICKET message\n");
949 cop = GNUNET_new (struct ConsumeTicketOperation);
950 cop->r_id = ntohl (cm->id);
951 cop->client = idp;
952 cop->ch
953 = RECLAIM_TICKETS_consume (&cm->identity, &cm->ticket, &consume_result_cb,
954 cop);
955 GNUNET_CONTAINER_DLL_insert (idp->consume_op_head, idp->consume_op_tail, cop);
956 GNUNET_SERVICE_client_continue (idp->client);
957}
958
959
960/*****************************************
961* Attribute store
962*****************************************/
963
964
965/**
966 * Attribute store result handler
967 *
968 * @param cls our attribute store handle
969 * @param success GNUNET_OK if successful
970 * @param emsg error message (NULL if success=GNUNET_OK)
971 */
972static void
973attr_store_cont (void *cls, int32_t success, const char *emsg)
974{
975 struct AttributeStoreHandle *ash = cls;
976 struct GNUNET_MQ_Envelope *env;
977 struct SuccessResultMessage *acr_msg;
978
979 ash->ns_qe = NULL;
980 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
981 ash->client->store_op_tail,
982 ash);
983
984 if (GNUNET_SYSERR == success)
985 {
986 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
987 "Failed to store attribute %s\n",
988 emsg);
989 cleanup_as_handle (ash);
990 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
991 return;
992 }
993
994 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
995 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
996 acr_msg->id = htonl (ash->r_id);
997 acr_msg->op_result = htonl (GNUNET_OK);
998 GNUNET_MQ_send (ash->client->mq, env);
999 cleanup_as_handle (ash);
1000}
1001
1002
1003/**
1004 * Add a new attribute
1005 *
1006 * @param cls the AttributeStoreHandle
1007 */
1008static void
1009attr_store_task (void *cls)
1010{
1011 struct AttributeStoreHandle *ash = cls;
1012 struct GNUNET_GNSRECORD_Data rd[1];
1013 char *buf;
1014 char *label;
1015 size_t buf_size;
1016
1017 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Storing attribute\n");
1018 buf_size = GNUNET_RECLAIM_attribute_serialize_get_size (ash->claim);
1019 buf = GNUNET_malloc (buf_size);
1020 // Give the ash a new id if unset
1021 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->claim->id))
1022 GNUNET_RECLAIM_id_generate (&ash->claim->id);
1023 GNUNET_RECLAIM_attribute_serialize (ash->claim, buf);
1024 label
1025 = GNUNET_STRINGS_data_to_string_alloc (&ash->claim->id,
1026 sizeof (ash->claim->id));
1027 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting with label %s\n", label);
1028
1029 rd[0].data_size = buf_size;
1030 rd[0].data = buf;
1031 rd[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE;
1032 rd[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1033 rd[0].expiration_time = ash->exp.rel_value_us;
1034 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1035 &ash->identity,
1036 label,
1037 1,
1038 rd,
1039 &attr_store_cont,
1040 ash);
1041 GNUNET_free (buf);
1042 GNUNET_free (label);
1043}
1044
1045
1046/**
1047 * Check an attribute store message
1048 *
1049 * @param cls unused
1050 * @param sam the message to check
1051 */
1052static int
1053check_attribute_store_message (void *cls,
1054 const struct AttributeStoreMessage *sam)
1055{
1056 uint16_t size;
1057
1058 size = ntohs (sam->header.size);
1059 if (size <= sizeof(struct AttributeStoreMessage))
1060 {
1061 GNUNET_break (0);
1062 return GNUNET_SYSERR;
1063 }
1064 return GNUNET_OK;
1065}
1066
1067
1068/**
1069 * Handle an attribute store message
1070 *
1071 * @param cls our client
1072 * @param sam the message to handle
1073 */
1074static void
1075handle_attribute_store_message (void *cls,
1076 const struct AttributeStoreMessage *sam)
1077{
1078 struct AttributeStoreHandle *ash;
1079 struct IdpClient *idp = cls;
1080 size_t data_len;
1081
1082 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_STORE message\n");
1083
1084 data_len = ntohs (sam->attr_len);
1085
1086 ash = GNUNET_new (struct AttributeStoreHandle);
1087 GNUNET_RECLAIM_attribute_deserialize ((char *) &sam[1],
1088 data_len,
1089 &ash->claim);
1090
1091 ash->r_id = ntohl (sam->id);
1092 ash->identity = sam->identity;
1093 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1094 GNUNET_IDENTITY_key_get_public (&sam->identity, &ash->identity_pkey);
1095
1096 GNUNET_SERVICE_client_continue (idp->client);
1097 ash->client = idp;
1098 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1099 GNUNET_SCHEDULER_add_now (&attr_store_task, ash);
1100}
1101
1102
1103/**
1104 * Credential store result handler
1105 *
1106 * @param cls our attribute store handle
1107 * @param success GNUNET_OK if successful
1108 * @param emsg error message (NULL if success=GNUNET_OK)
1109 */
1110static void
1111cred_store_cont (void *cls, int32_t success, const char *emsg)
1112{
1113 struct AttributeStoreHandle *ash = cls;
1114 struct GNUNET_MQ_Envelope *env;
1115 struct SuccessResultMessage *acr_msg;
1116
1117 ash->ns_qe = NULL;
1118 GNUNET_CONTAINER_DLL_remove (ash->client->store_op_head,
1119 ash->client->store_op_tail,
1120 ash);
1121
1122 if (GNUNET_SYSERR == success)
1123 {
1124 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1125 "Failed to store credential: %s\n",
1126 emsg);
1127 cleanup_as_handle (ash);
1128 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1129 return;
1130 }
1131
1132 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1133 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1134 acr_msg->id = htonl (ash->r_id);
1135 acr_msg->op_result = htonl (GNUNET_OK);
1136 GNUNET_MQ_send (ash->client->mq, env);
1137 cleanup_as_handle (ash);
1138}
1139
1140
1141/**
1142 * Error looking up potential credential. Abort.
1143 *
1144 * @param cls our attribute store handle
1145 */
1146static void
1147cred_error (void *cls)
1148{
1149 struct AttributeStoreHandle *ash = cls;
1150 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1151 "Failed to check for existing credential.\n");
1152 cleanup_as_handle (ash);
1153 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
1154 return;
1155}
1156
1157
1158/**
1159* Check for existing record before storing credential
1160*
1161* @param cls our attribute store handle
1162* @param zone zone we are iterating
1163* @param label label of the records
1164* @param rd_count record count
1165* @param rd records
1166*/
1167static void
1168cred_add_cb (void *cls,
1169 const struct GNUNET_IDENTITY_PrivateKey *zone,
1170 const char *label,
1171 unsigned int rd_count,
1172 const struct GNUNET_GNSRECORD_Data *rd)
1173{
1174 struct AttributeStoreHandle *ash = cls;
1175 struct GNUNET_GNSRECORD_Data rd_new[1];
1176 char *buf;
1177 size_t buf_size;
1178
1179 buf_size = GNUNET_RECLAIM_credential_serialize_get_size (ash->credential);
1180 buf = GNUNET_malloc (buf_size);
1181 GNUNET_RECLAIM_credential_serialize (ash->credential, buf);
1182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1183 "Storing new credential under `%s'.\n",
1184 label);
1185 rd_new[0].data_size = buf_size;
1186 rd_new[0].data = buf;
1187 rd_new[0].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL;
1188 rd_new[0].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1189 rd_new[0].expiration_time = ash->exp.rel_value_us;
1190 ash->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1191 &ash->identity,
1192 label,
1193 1,
1194 rd_new,
1195 &cred_store_cont,
1196 ash);
1197 GNUNET_free (buf);
1198 return;
1199}
1200
1201
1202/**
1203 * Add a new credential
1204 *
1205 * @param cls the AttributeStoreHandle
1206 */
1207static void
1208cred_store_task (void *cls)
1209{
1210 struct AttributeStoreHandle *ash = cls;
1211 char *label;
1212
1213 // Give the ash a new id if unset
1214 if (GNUNET_YES == GNUNET_RECLAIM_id_is_zero (&ash->credential->id))
1215 GNUNET_RECLAIM_id_generate (&ash->credential->id);
1216 label = GNUNET_STRINGS_data_to_string_alloc (&ash->credential->id,
1217 sizeof (ash->credential->id));
1218 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1219 "Looking up existing data under label `%s'\n", label);
1220 ash->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
1221 &ash->identity,
1222 label,
1223 &cred_error,
1224 ash,
1225 &cred_add_cb,
1226 ash);
1227 GNUNET_free (label);
1228}
1229
1230
1231/**
1232 * Check an credential store message
1233 *
1234 * @param cls unused
1235 * @param sam the message to check
1236 */
1237static int
1238check_credential_store_message (void *cls,
1239 const struct AttributeStoreMessage *sam)
1240{
1241 uint16_t size;
1242
1243 size = ntohs (sam->header.size);
1244 if (size <= sizeof(struct AttributeStoreMessage))
1245 {
1246 GNUNET_break (0);
1247 return GNUNET_SYSERR;
1248 }
1249 return GNUNET_OK;
1250}
1251
1252
1253/**
1254* Handle a credential store message
1255*
1256* @param cls our client
1257* @param sam the message to handle
1258*/
1259static void
1260handle_credential_store_message (void *cls,
1261 const struct AttributeStoreMessage *sam)
1262{
1263 struct AttributeStoreHandle *ash;
1264 struct IdpClient *idp = cls;
1265 size_t data_len;
1266
1267 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CREDENTIAL_STORE message\n");
1268
1269 data_len = ntohs (sam->attr_len);
1270
1271 ash = GNUNET_new (struct AttributeStoreHandle);
1272 ash->credential = GNUNET_RECLAIM_credential_deserialize ((char *) &sam[1],
1273 data_len);
1274
1275 ash->r_id = ntohl (sam->id);
1276 ash->identity = sam->identity;
1277 ash->exp.rel_value_us = GNUNET_ntohll (sam->exp);
1278 GNUNET_IDENTITY_key_get_public (&sam->identity, &ash->identity_pkey);
1279
1280 GNUNET_SERVICE_client_continue (idp->client);
1281 ash->client = idp;
1282 GNUNET_CONTAINER_DLL_insert (idp->store_op_head, idp->store_op_tail, ash);
1283 GNUNET_SCHEDULER_add_now (&cred_store_task, ash);
1284}
1285
1286
1287/**
1288 * Send a deletion success response
1289 *
1290 * @param adh our attribute deletion handle
1291 * @param success the success status
1292 */
1293static void
1294send_delete_response (struct AttributeDeleteHandle *adh, int32_t success)
1295{
1296 struct GNUNET_MQ_Envelope *env;
1297 struct SuccessResultMessage *acr_msg;
1298
1299 GNUNET_CONTAINER_DLL_remove (adh->client->delete_op_head,
1300 adh->client->delete_op_tail,
1301 adh);
1302
1303 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending SUCCESS_RESPONSE message\n");
1304 env = GNUNET_MQ_msg (acr_msg, GNUNET_MESSAGE_TYPE_RECLAIM_SUCCESS_RESPONSE);
1305 acr_msg->id = htonl (adh->r_id);
1306 acr_msg->op_result = htonl (success);
1307 GNUNET_MQ_send (adh->client->mq, env);
1308}
1309
1310
1311/**
1312 * Namestore iteration within attribute deletion.
1313 * We need to reissue tickets with the deleted attribute removed.
1314 *
1315 * @param cls our attribute deletion handle
1316 * @param zone the private key of the ticket issuer
1317 * @param label the label of the record
1318 * @param rd_count number of records
1319 * @param rd record data
1320 */
1321static void
1322consistency_iter (void *cls,
1323 const struct GNUNET_IDENTITY_PrivateKey *zone,
1324 const char *label,
1325 unsigned int rd_count,
1326 const struct GNUNET_GNSRECORD_Data *rd)
1327{
1328 struct AttributeDeleteHandle *adh = cls;
1329 struct TicketRecordsEntry *le;
1330 struct GNUNET_RECLAIM_AttributeListEntry *ale;
1331 struct GNUNET_RECLAIM_CredentialListEntry *cle;
1332 int is_ticket = GNUNET_NO;
1333 for (int i = 0; i < rd_count; i++)
1334 {
1335 switch (rd[i].record_type)
1336 {
1337 case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE:
1338 ale = GNUNET_new (struct GNUNET_RECLAIM_AttributeListEntry);
1339 GNUNET_RECLAIM_attribute_deserialize (rd[i].data,
1340 rd[i].data_size,
1341 &ale->attribute);
1342 GNUNET_CONTAINER_DLL_insert (adh->existing_attributes->list_head,
1343 adh->existing_attributes->list_tail,
1344 ale);
1345 break;
1346 case GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL:
1347 cle = GNUNET_new (struct GNUNET_RECLAIM_CredentialListEntry);
1348 cle->credential = GNUNET_RECLAIM_credential_deserialize (rd[i].data,
1349 rd[i].data_size);
1350 GNUNET_CONTAINER_DLL_insert (adh->existing_credentials->list_head,
1351 adh->existing_credentials->list_tail,
1352 cle);
1353 break;
1354 case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
1355 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1356 "Ticket to delete found (%s)\n",
1357 label);
1358 is_ticket = GNUNET_YES;
1359 break;
1360 default:
1361 break;
1362 }
1363 if (GNUNET_YES == is_ticket)
1364 break;
1365 }
1366 if (GNUNET_YES == is_ticket)
1367 {
1368 le = GNUNET_new (struct TicketRecordsEntry);
1369 le->data_size = GNUNET_GNSRECORD_records_get_size (rd_count, rd);
1370 le->data = GNUNET_malloc (le->data_size);
1371 le->rd_count = rd_count;
1372 le->label = GNUNET_strdup (label);
1373 GNUNET_GNSRECORD_records_serialize (rd_count, rd, le->data_size, le->data);
1374 GNUNET_CONTAINER_DLL_insert (adh->tickets_to_update_head,
1375 adh->tickets_to_update_tail,
1376 le);
1377 }
1378 GNUNET_NAMESTORE_zone_iterator_next (adh->ns_it, 1);
1379}
1380
1381
1382/**
1383 * Recursion prototype for function
1384 * @param cls our deletion handle
1385 */
1386static void
1387update_tickets (void *cls);
1388
1389
1390/**
1391 * Callback called when a ticket was updated
1392 *
1393 * @param cls our attribute deletion handle
1394 * @param success GNUNET_OK if successful
1395 * @param emsg error message (NULL if success=GNUNET_OK)
1396 */
1397static void
1398ticket_updated (void *cls, int32_t success, const char *emsg)
1399{
1400 struct AttributeDeleteHandle *adh = cls;
1401
1402 adh->ns_qe = NULL;
1403 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1404}
1405
1406
1407/**
1408 * Update tickets: Remove shared attribute which has just been deleted.
1409 * This method is called recursively until all tickets are processed.
1410 * Eventually, the updated tickets are stored using ``update_tickets''.
1411 *
1412 * @param cls our attribute deletion handle
1413 */
1414static void
1415update_tickets (void *cls)
1416{
1417 struct AttributeDeleteHandle *adh = cls;
1418 struct TicketRecordsEntry *le;
1419
1420 if (NULL == adh->tickets_to_update_head)
1421 {
1422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1423 "Finished updating tickets, success\n");
1424 send_delete_response (adh, GNUNET_OK);
1425 cleanup_adh (adh);
1426 return;
1427 }
1428 le = adh->tickets_to_update_head;
1429 GNUNET_CONTAINER_DLL_remove (adh->tickets_to_update_head,
1430 adh->tickets_to_update_tail,
1431 le);
1432 struct GNUNET_GNSRECORD_Data rd[le->rd_count];
1433 struct GNUNET_GNSRECORD_Data rd_new[le->rd_count - 1];
1434 if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
1435 le->data,
1436 le->rd_count,
1437 rd))
1438 {
1439 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1440 "Unable to deserialize record data!\n");
1441 send_delete_response (adh, GNUNET_SYSERR);
1442 cleanup_adh (adh);
1443 return;
1444 }
1445 int j = 0;
1446 int i = 0;
1447 struct GNUNET_RECLAIM_AttributeListEntry *ale;
1448 struct GNUNET_RECLAIM_CredentialListEntry *cle;
1449 struct GNUNET_RECLAIM_Presentation *presentation;
1450 for (i = 0; i < le->rd_count; i++)
1451 {
1452 switch (rd[i].record_type)
1453 {
1454 case GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE_REF:
1455 for (ale = adh->existing_attributes->list_head; NULL != ale; ale =
1456 ale->next)
1457 {
1458 if (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (rd[i].data,
1459 &ale->attribute->id))
1460 {
1461 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1462 "Found attribute %s, readding...\n",
1463 ale->attribute->name);
1464 rd_new[j] = rd[i];
1465 j++;
1466 break; // Found and added
1467 }
1468 }
1469 break;
1470 case GNUNET_GNSRECORD_TYPE_RECLAIM_PRESENTATION:
1471 presentation = GNUNET_RECLAIM_presentation_deserialize (rd[i].data,
1472 rd[i].data_size);
1473 for (cle = adh->existing_credentials->list_head; NULL != cle; cle =
1474 cle->next)
1475 {
1476 if (GNUNET_YES == GNUNET_RECLAIM_id_is_equal (
1477 &presentation->credential_id,
1478 &cle->credential->id))
1479 {
1480 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1481 "Found presentation for credential %s, readding...\n",
1482 cle->credential->name);
1483 rd_new[j] = rd[i];
1484 j++;
1485 break; // Found and added
1486 }
1487 }
1488 GNUNET_free (presentation);
1489 break;
1490 case GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET:
1491 rd_new[j] = rd[i];
1492 j++;
1493 break; // Found and added
1494 default:
1495 GNUNET_break (0);
1496 }
1497 }
1498 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1499 "Updating ticket with %d entries (%d before)...\n",
1500 j, i);
1501 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1502 &adh->identity,
1503 le->label,
1504 j,
1505 rd_new,
1506 &ticket_updated,
1507 adh);
1508 GNUNET_free (le->label);
1509 GNUNET_free (le->data);
1510 GNUNET_free (le);
1511}
1512
1513
1514/**
1515 * Delete all attributes which reference credentials
1516 * that no longer exist
1517 */
1518static void
1519purge_attributes (void *cls);;
1520
1521static void
1522offending_attr_delete_cont (void *cls, int32_t success, const char *emsg)
1523{
1524 struct AttributeDeleteHandle *adh = cls;
1525
1526 adh->ns_qe = NULL;
1527 if (GNUNET_SYSERR == success)
1528 {
1529 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1530 "Error deleting attribute %s\n",
1531 adh->label);
1532 send_delete_response (adh, GNUNET_SYSERR);
1533 cleanup_adh (adh);
1534 return;
1535 }
1536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Continuing consistency check...\n");
1537 GNUNET_SCHEDULER_add_now (&purge_attributes, adh);
1538}
1539
1540
1541/**
1542 * Delete all attributes which reference credentials
1543 * that no longer exist
1544 */
1545static void
1546purge_attributes (void *cls)
1547{
1548 struct AttributeDeleteHandle *adh = cls;
1549 struct GNUNET_RECLAIM_AttributeListEntry *ale;
1550 struct GNUNET_RECLAIM_CredentialListEntry *cle;
1551
1552 for (ale = adh->existing_attributes->list_head; NULL != ale; ale = ale->next)
1553 {
1554 if (GNUNET_YES ==
1555 GNUNET_RECLAIM_id_is_zero (&ale->attribute->credential))
1556 continue;
1557
1558 for (cle = adh->existing_credentials->list_head;
1559 NULL != cle; cle = cle->next)
1560 {
1561 if (GNUNET_YES !=
1562 GNUNET_RECLAIM_id_is_equal (&cle->credential->id,
1563 &ale->attribute->credential))
1564 continue;
1565 break;
1566 }
1567 if (NULL == cle)
1568 {
1569 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1570 "Found attribute with missing credential\n");
1571 break;
1572 }
1573 }
1574 if (NULL == ale)
1575 {
1576 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1577 "Attributes consistent, updating tickets.\n");
1578 GNUNET_SCHEDULER_add_now (&update_tickets, adh);
1579 return;
1580 }
1581 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1582 "Attributes inconsistent, deleting offending attribute.\n");
1583 char *label
1584 = GNUNET_STRINGS_data_to_string_alloc (&ale->attribute->id,
1585 sizeof(ale->attribute->id));
1586
1587 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1588 &adh->identity,
1589 label,
1590 0,
1591 NULL,
1592 &offending_attr_delete_cont,
1593 adh);
1594 GNUNET_CONTAINER_DLL_remove (adh->existing_attributes->list_head,
1595 adh->existing_attributes->list_tail,
1596 ale);
1597 GNUNET_free (ale);
1598 GNUNET_free (label);
1599}
1600
1601
1602/**
1603 * Done collecting affected tickets, start updating.
1604 *
1605 * @param cls our attribute deletion handle
1606 */
1607static void
1608consistency_iter_fin (void *cls)
1609{
1610 struct AttributeDeleteHandle *adh = cls;
1611 adh->ns_it = NULL;
1612 GNUNET_SCHEDULER_add_now (&purge_attributes, adh);
1613}
1614
1615
1616/**
1617 * Error collecting affected tickets. Abort.
1618 *
1619 * @param cls our attribute deletion handle
1620 */
1621static void
1622consistency_iter_err (void *cls)
1623{
1624 struct AttributeDeleteHandle *adh = cls;
1625
1626 adh->ns_it = NULL;
1627 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1628 "Namestore error on consistency check\n");
1629 send_delete_response (adh, GNUNET_SYSERR);
1630 cleanup_adh (adh);
1631}
1632
1633
1634/**
1635 * Start processing tickets which may still contain reference to deleted
1636 * attribute.
1637 *
1638 * @param cls attribute deletion handle
1639 */
1640static void
1641start_consistency_update (void *cls)
1642{
1643 struct AttributeDeleteHandle *adh = cls;
1644
1645 adh->existing_attributes = GNUNET_new (struct GNUNET_RECLAIM_AttributeList);
1646 adh->existing_credentials = GNUNET_new (struct GNUNET_RECLAIM_CredentialList);
1647
1648 adh->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1649 &adh->identity,
1650 &consistency_iter_err,
1651 adh,
1652 &consistency_iter,
1653 adh,
1654 &consistency_iter_fin,
1655 adh);
1656}
1657
1658
1659/**
1660 * Attribute deleted callback
1661 *
1662 * @param cls our handle
1663 * @param success success status
1664 * @param emsg error message (NULL if success=GNUNET_OK)
1665 */
1666static void
1667attr_delete_cont (void *cls, int32_t success, const char *emsg)
1668{
1669 struct AttributeDeleteHandle *adh = cls;
1670
1671 adh->ns_qe = NULL;
1672 if (GNUNET_SYSERR == success)
1673 {
1674 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1675 "Error deleting attribute %s\n",
1676 adh->label);
1677 send_delete_response (adh, GNUNET_SYSERR);
1678 cleanup_adh (adh);
1679 return;
1680 }
1681 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1682 GNUNET_SCHEDULER_add_now (&start_consistency_update, adh);
1683}
1684
1685
1686/**
1687 * Check attribute delete message format
1688 *
1689 * @cls unused
1690 * @dam message to check
1691 */
1692static int
1693check_attribute_delete_message (void *cls,
1694 const struct AttributeDeleteMessage *dam)
1695{
1696 uint16_t size;
1697
1698 size = ntohs (dam->header.size);
1699 if (size <= sizeof(struct AttributeDeleteMessage))
1700 {
1701 GNUNET_break (0);
1702 return GNUNET_SYSERR;
1703 }
1704 return GNUNET_OK;
1705}
1706
1707
1708/**
1709 * Handle attribute deletion
1710 *
1711 * @param cls our client
1712 * @param dam deletion message
1713 */
1714static void
1715handle_attribute_delete_message (void *cls,
1716 const struct AttributeDeleteMessage *dam)
1717{
1718 struct AttributeDeleteHandle *adh;
1719 struct IdpClient *idp = cls;
1720 size_t data_len;
1721
1722 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ATTRIBUTE_DELETE message\n");
1723
1724 data_len = ntohs (dam->attr_len);
1725
1726 adh = GNUNET_new (struct AttributeDeleteHandle);
1727 GNUNET_RECLAIM_attribute_deserialize ((char *) &dam[1],
1728 data_len,
1729 &adh->claim);
1730 adh->credential = NULL;
1731
1732 adh->r_id = ntohl (dam->id);
1733 adh->identity = dam->identity;
1734 adh->label
1735 = GNUNET_STRINGS_data_to_string_alloc (&adh->claim->id,
1736 sizeof(adh->claim->id));
1737 GNUNET_SERVICE_client_continue (idp->client);
1738 adh->client = idp;
1739 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1740 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1741 &adh->identity,
1742 adh->label,
1743 0,
1744 NULL,
1745 &attr_delete_cont,
1746 adh);
1747}
1748
1749
1750/**
1751 * Credential deleted callback
1752 *
1753 * @param cls our handle
1754 * @param success success status
1755 * @param emsg error message (NULL if success=GNUNET_OK)
1756 */
1757static void
1758cred_delete_cont (void *cls, int32_t success, const char *emsg)
1759{
1760 struct AttributeDeleteHandle *adh = cls;
1761
1762 adh->ns_qe = NULL;
1763 if (GNUNET_SYSERR == success)
1764 {
1765 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1766 "Error deleting credential `%s'\n",
1767 adh->label);
1768 send_delete_response (adh, GNUNET_SYSERR);
1769 cleanup_adh (adh);
1770 return;
1771 }
1772 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating tickets...\n");
1773 GNUNET_SCHEDULER_add_now (&start_consistency_update, adh);
1774}
1775
1776
1777/**
1778 * Check credential delete message format
1779 *
1780 * @cls unused
1781 * @dam message to check
1782 */
1783static int
1784check_credential_delete_message (void *cls,
1785 const struct AttributeDeleteMessage *dam)
1786{
1787 uint16_t size;
1788
1789 size = ntohs (dam->header.size);
1790 if (size <= sizeof(struct AttributeDeleteMessage))
1791 {
1792 GNUNET_break (0);
1793 return GNUNET_SYSERR;
1794 }
1795 return GNUNET_OK;
1796}
1797
1798
1799/**
1800 * Handle credential deletion
1801 *
1802 * @param cls our client
1803 * @param dam deletion message
1804 */
1805static void
1806handle_credential_delete_message (void *cls,
1807 const struct AttributeDeleteMessage *dam)
1808{
1809 struct AttributeDeleteHandle *adh;
1810 struct IdpClient *idp = cls;
1811 size_t data_len;
1812
1813 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CREDENTIAL_DELETE message\n");
1814
1815 data_len = ntohs (dam->attr_len);
1816
1817 adh = GNUNET_new (struct AttributeDeleteHandle);
1818 adh->credential = GNUNET_RECLAIM_credential_deserialize ((char *) &dam[1],
1819 data_len);
1820 adh->claim = NULL;
1821
1822 adh->r_id = ntohl (dam->id);
1823 adh->identity = dam->identity;
1824 adh->label
1825 = GNUNET_STRINGS_data_to_string_alloc (&adh->credential->id,
1826 sizeof(adh->credential->id));
1827 GNUNET_SERVICE_client_continue (idp->client);
1828 adh->client = idp;
1829 GNUNET_CONTAINER_DLL_insert (idp->delete_op_head, idp->delete_op_tail, adh);
1830 adh->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
1831 &adh->identity,
1832 adh->label,
1833 0,
1834 NULL,
1835 &cred_delete_cont,
1836 adh);
1837}
1838
1839
1840/*************************************************
1841 * Attribute iteration
1842 *************************************************/
1843
1844
1845/**
1846 * Done iterating over attributes
1847 *
1848 * @param cls our iterator handle
1849 */
1850static void
1851attr_iter_finished (void *cls)
1852{
1853 struct Iterator *ai = cls;
1854 struct GNUNET_MQ_Envelope *env;
1855 struct AttributeResultMessage *arm;
1856
1857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending ATTRIBUTE_RESULT message\n");
1858 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1859 arm->id = htonl (ai->request_id);
1860 arm->attr_len = htons (0);
1861 GNUNET_MQ_send (ai->client->mq, env);
1862 GNUNET_CONTAINER_DLL_remove (ai->client->attr_iter_head,
1863 ai->client->attr_iter_tail,
1864 ai);
1865 GNUNET_free (ai);
1866}
1867
1868
1869/**
1870 * Error iterating over attributes. Abort.
1871 *
1872 * @param cls our attribute iteration handle
1873 */
1874static void
1875attr_iter_error (void *cls)
1876{
1877 struct Iterator *ai = cls;
1878
1879 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over attributes\n");
1880 attr_iter_finished (ai);
1881}
1882
1883
1884/**
1885 * Got record. Return if it is an attribute.
1886 *
1887 * @param cls our attribute iterator
1888 * @param zone zone we are iterating
1889 * @param label label of the records
1890 * @param rd_count record count
1891 * @param rd records
1892 */
1893static void
1894attr_iter_cb (void *cls,
1895 const struct GNUNET_IDENTITY_PrivateKey *zone,
1896 const char *label,
1897 unsigned int rd_count,
1898 const struct GNUNET_GNSRECORD_Data *rd)
1899{
1900 struct Iterator *ai = cls;
1901 struct GNUNET_MQ_Envelope *env;
1902 char *data_tmp;
1903
1904 if ((rd_count != 1) ||
1905 (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTRIBUTE != rd->record_type))
1906 {
1907 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
1908 return;
1909 }
1910 struct AttributeResultMessage *arm;
1911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found attribute under: %s\n",
1912 label);
1913 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1914 "Sending ATTRIBUTE_RESULT message\n");
1915 env = GNUNET_MQ_msg_extra (arm,
1916 rd->data_size,
1917 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT);
1918 arm->id = htonl (ai->request_id);
1919 arm->attr_len = htons (rd->data_size);
1920 GNUNET_IDENTITY_key_get_public (zone, &arm->identity);
1921 data_tmp = (char *) &arm[1];
1922 GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
1923 GNUNET_MQ_send (ai->client->mq, env);
1924}
1925
1926
1927/**
1928 * Iterate over zone to get attributes
1929 *
1930 * @param cls our client
1931 * @param ais_msg the iteration message to start
1932 */
1933static void
1934handle_iteration_start (void *cls,
1935 const struct AttributeIterationStartMessage *ais_msg)
1936{
1937 struct IdpClient *idp = cls;
1938 struct Iterator *ai;
1939
1940 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1941 "Received ATTRIBUTE_ITERATION_START message\n");
1942 ai = GNUNET_new (struct Iterator);
1943 ai->request_id = ntohl (ais_msg->id);
1944 ai->client = idp;
1945 ai->identity = ais_msg->identity;
1946
1947 GNUNET_CONTAINER_DLL_insert (idp->attr_iter_head, idp->attr_iter_tail, ai);
1948 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
1949 &ai->identity,
1950 &attr_iter_error,
1951 ai,
1952 &attr_iter_cb,
1953 ai,
1954 &attr_iter_finished,
1955 ai);
1956 GNUNET_SERVICE_client_continue (idp->client);
1957}
1958
1959
1960/**
1961 * Handle iteration stop message from client
1962 *
1963 * @param cls the client
1964 * @param ais_msg the stop message
1965 */
1966static void
1967handle_iteration_stop (void *cls,
1968 const struct AttributeIterationStopMessage *ais_msg)
1969{
1970 struct IdpClient *idp = cls;
1971 struct Iterator *ai;
1972 uint32_t rid;
1973
1974 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1975 "Received `%s' message\n",
1976 "ATTRIBUTE_ITERATION_STOP");
1977 rid = ntohl (ais_msg->id);
1978 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
1979 if (ai->request_id == rid)
1980 break;
1981 if (NULL == ai)
1982 {
1983 GNUNET_break (0);
1984 GNUNET_SERVICE_client_drop (idp->client);
1985 return;
1986 }
1987 GNUNET_CONTAINER_DLL_remove (idp->attr_iter_head, idp->attr_iter_tail, ai);
1988 GNUNET_free (ai);
1989 GNUNET_SERVICE_client_continue (idp->client);
1990}
1991
1992
1993/**
1994 * Client requests next attribute from iterator
1995 *
1996 * @param cls the client
1997 * @param ais_msg the message
1998 */
1999static void
2000handle_iteration_next (void *cls,
2001 const struct AttributeIterationNextMessage *ais_msg)
2002{
2003 struct IdpClient *idp = cls;
2004 struct Iterator *ai;
2005 uint32_t rid;
2006
2007 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2008 "Received ATTRIBUTE_ITERATION_NEXT message\n");
2009 rid = ntohl (ais_msg->id);
2010 for (ai = idp->attr_iter_head; NULL != ai; ai = ai->next)
2011 if (ai->request_id == rid)
2012 break;
2013 if (NULL == ai)
2014 {
2015 GNUNET_break (0);
2016 GNUNET_SERVICE_client_drop (idp->client);
2017 return;
2018 }
2019 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2020 GNUNET_SERVICE_client_continue (idp->client);
2021}
2022
2023
2024/*************************************************
2025 * Credential iteration
2026 *************************************************/
2027
2028
2029/**
2030 * Done iterating over credentials
2031 *
2032 * @param cls our iterator handle
2033 */
2034static void
2035cred_iter_finished (void *cls)
2036{
2037 struct Iterator *ai = cls;
2038 struct GNUNET_MQ_Envelope *env;
2039 struct CredentialResultMessage *arm;
2040
2041 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending CREDENTIAL_RESULT message\n");
2042 env = GNUNET_MQ_msg (arm, GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_RESULT);
2043 arm->id = htonl (ai->request_id);
2044 arm->credential_len = htons (0);
2045 GNUNET_MQ_send (ai->client->mq, env);
2046 GNUNET_CONTAINER_DLL_remove (ai->client->cred_iter_head,
2047 ai->client->cred_iter_tail,
2048 ai);
2049 GNUNET_free (ai);
2050}
2051
2052
2053/**
2054 * Error iterating over credentials. Abort.
2055 *
2056 * @param cls our attribute iteration handle
2057 */
2058static void
2059cred_iter_error (void *cls)
2060{
2061 struct Iterator *ai = cls;
2062
2063 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to iterate over credentials\n");
2064 cred_iter_finished (ai);
2065}
2066
2067
2068/**
2069 * Got record. Return credential.
2070 *
2071 * @param cls our attribute iterator
2072 * @param zone zone we are iterating
2073 * @param label label of the records
2074 * @param rd_count record count
2075 * @param rd records
2076 */
2077static void
2078cred_iter_cb (void *cls,
2079 const struct GNUNET_IDENTITY_PrivateKey *zone,
2080 const char *label,
2081 unsigned int rd_count,
2082 const struct GNUNET_GNSRECORD_Data *rd)
2083{
2084 struct Iterator *ai = cls;
2085 struct GNUNET_MQ_Envelope *env;
2086 struct CredentialResultMessage *arm;
2087 char *data_tmp;
2088
2089 if ((rd_count != 1) ||
2090 (GNUNET_GNSRECORD_TYPE_RECLAIM_CREDENTIAL != rd->record_type))
2091 {
2092 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2093 return;
2094 }
2095 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found credential under: %s\n",
2096 label);
2097 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2098 "Sending CREDENTIAL_RESULT message\n");
2099 env = GNUNET_MQ_msg_extra (arm,
2100 rd->data_size,
2101 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_RESULT);
2102 arm->id = htonl (ai->request_id);
2103 arm->credential_len = htons (rd->data_size);
2104 GNUNET_IDENTITY_key_get_public (zone, &arm->identity);
2105 data_tmp = (char *) &arm[1];
2106 GNUNET_memcpy (data_tmp, rd->data, rd->data_size);
2107
2108 GNUNET_MQ_send (ai->client->mq, env);
2109}
2110
2111
2112/**
2113 * Iterate over zone to get attributes
2114 *
2115 * @param cls our client
2116 * @param ais_msg the iteration message to start
2117 */
2118static void
2119handle_credential_iteration_start (void *cls,
2120 const struct
2121 CredentialIterationStartMessage *ais_msg)
2122{
2123 struct IdpClient *idp = cls;
2124 struct Iterator *ai;
2125
2126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2127 "Received CREDENTIAL_ITERATION_START message\n");
2128 ai = GNUNET_new (struct Iterator);
2129 ai->request_id = ntohl (ais_msg->id);
2130 ai->client = idp;
2131 ai->identity = ais_msg->identity;
2132
2133 GNUNET_CONTAINER_DLL_insert (idp->cred_iter_head, idp->cred_iter_tail,
2134 ai);
2135 ai->ns_it = GNUNET_NAMESTORE_zone_iteration_start (nsh,
2136 &ai->identity,
2137 &cred_iter_error,
2138 ai,
2139 &cred_iter_cb,
2140 ai,
2141 &cred_iter_finished,
2142 ai);
2143 GNUNET_SERVICE_client_continue (idp->client);
2144}
2145
2146
2147/**
2148 * Handle iteration stop message from client
2149 *
2150 * @param cls the client
2151 * @param ais_msg the stop message
2152 */
2153static void
2154handle_credential_iteration_stop (void *cls,
2155 const struct
2156 CredentialIterationStopMessage *ais_msg)
2157{
2158 struct IdpClient *idp = cls;
2159 struct Iterator *ai;
2160 uint32_t rid;
2161
2162 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2163 "Received `%s' message\n",
2164 "CREDENTIAL_ITERATION_STOP");
2165 rid = ntohl (ais_msg->id);
2166 for (ai = idp->cred_iter_head; NULL != ai; ai = ai->next)
2167 if (ai->request_id == rid)
2168 break;
2169 if (NULL == ai)
2170 {
2171 GNUNET_break (0);
2172 GNUNET_SERVICE_client_drop (idp->client);
2173 return;
2174 }
2175 GNUNET_CONTAINER_DLL_remove (idp->cred_iter_head, idp->cred_iter_tail,
2176 ai);
2177 GNUNET_free (ai);
2178 GNUNET_SERVICE_client_continue (idp->client);
2179}
2180
2181
2182/**
2183 * Client requests next credential from iterator
2184 *
2185 * @param cls the client
2186 * @param ais_msg the message
2187 */
2188static void
2189handle_credential_iteration_next (void *cls,
2190 const struct
2191 CredentialIterationNextMessage *ais_msg)
2192{
2193 struct IdpClient *idp = cls;
2194 struct Iterator *ai;
2195 uint32_t rid;
2196
2197 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2198 "Received CREDENTIAL_ITERATION_NEXT message\n");
2199 rid = ntohl (ais_msg->id);
2200 for (ai = idp->cred_iter_head; NULL != ai; ai = ai->next)
2201 if (ai->request_id == rid)
2202 break;
2203 if (NULL == ai)
2204 {
2205 GNUNET_break (0);
2206 GNUNET_SERVICE_client_drop (idp->client);
2207 return;
2208 }
2209 GNUNET_NAMESTORE_zone_iterator_next (ai->ns_it, 1);
2210 GNUNET_SERVICE_client_continue (idp->client);
2211}
2212
2213
2214/******************************************************
2215 * Ticket iteration
2216 ******************************************************/
2217
2218/**
2219 * Got a ticket. Return to client
2220 *
2221 * @param cls our ticket iterator
2222 * @param ticket the ticket
2223 */
2224static void
2225ticket_iter_cb (void *cls, struct GNUNET_RECLAIM_Ticket *ticket)
2226{
2227 struct TicketIteration *ti = cls;
2228 struct GNUNET_MQ_Envelope *env;
2229 struct TicketResultMessage *trm;
2230
2231 env = GNUNET_MQ_msg (trm, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT);
2232 if (NULL == ticket)
2233 {
2234 /* send empty response to indicate end of list */
2235 GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head,
2236 ti->client->ticket_iter_tail,
2237 ti);
2238 }
2239 else
2240 {
2241 trm->ticket = *ticket;
2242 }
2243 trm->id = htonl (ti->r_id);
2244 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending TICKET_RESULT message\n");
2245 GNUNET_MQ_send (ti->client->mq, env);
2246 if (NULL == ticket)
2247 GNUNET_free (ti);
2248}
2249
2250
2251/**
2252 * Client requests a ticket iteration
2253 *
2254 * @param cls the client
2255 * @param tis_msg the iteration request message
2256 */
2257static void
2258handle_ticket_iteration_start (
2259 void *cls,
2260 const struct TicketIterationStartMessage *tis_msg)
2261{
2262 struct IdpClient *client = cls;
2263 struct TicketIteration *ti;
2264
2265 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2266 "Received TICKET_ITERATION_START message\n");
2267 ti = GNUNET_new (struct TicketIteration);
2268 ti->r_id = ntohl (tis_msg->id);
2269 ti->client = client;
2270
2271 GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head,
2272 client->ticket_iter_tail,
2273 ti);
2274 ti->iter
2275 = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, &ticket_iter_cb, ti);
2276 GNUNET_SERVICE_client_continue (client->client);
2277}
2278
2279
2280/**
2281 * Client has had enough tickets
2282 *
2283 * @param cls the client
2284 * @param tis_msg the stop message
2285 */
2286static void
2287handle_ticket_iteration_stop (void *cls,
2288 const struct TicketIterationStopMessage *tis_msg)
2289{
2290 struct IdpClient *client = cls;
2291 struct TicketIteration *ti;
2292 uint32_t rid;
2293
2294 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2295 "Received `%s' message\n",
2296 "TICKET_ITERATION_STOP");
2297 rid = ntohl (tis_msg->id);
2298 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2299 if (ti->r_id == rid)
2300 break;
2301 if (NULL == ti)
2302 {
2303 GNUNET_break (0);
2304 GNUNET_SERVICE_client_drop (client->client);
2305 return;
2306 }
2307 RECLAIM_TICKETS_iteration_stop (ti->iter);
2308 GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head,
2309 client->ticket_iter_tail,
2310 ti);
2311 GNUNET_free (ti);
2312 GNUNET_SERVICE_client_continue (client->client);
2313}
2314
2315
2316/**
2317 * Client requests next result.
2318 *
2319 * @param cls the client
2320 * @param tis_msg the message
2321 */
2322static void
2323handle_ticket_iteration_next (void *cls,
2324 const struct TicketIterationNextMessage *tis_msg)
2325{
2326 struct IdpClient *client = cls;
2327 struct TicketIteration *ti;
2328 uint32_t rid;
2329
2330 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2331 "Received TICKET_ITERATION_NEXT message\n");
2332 rid = ntohl (tis_msg->id);
2333 for (ti = client->ticket_iter_head; NULL != ti; ti = ti->next)
2334 if (ti->r_id == rid)
2335 break;
2336 if (NULL == ti)
2337 {
2338 GNUNET_break (0);
2339 GNUNET_SERVICE_client_drop (client->client);
2340 return;
2341 }
2342 RECLAIM_TICKETS_iteration_next (ti->iter);
2343 GNUNET_SERVICE_client_continue (client->client);
2344}
2345
2346
2347/**
2348 * Main function that will be run
2349 *
2350 * @param cls closure
2351 * @param c the configuration used
2352 * @param server the service handle
2353 */
2354static void
2355run (void *cls,
2356 const struct GNUNET_CONFIGURATION_Handle *c,
2357 struct GNUNET_SERVICE_Handle *server)
2358{
2359 cfg = c;
2360
2361 if (GNUNET_OK != RECLAIM_TICKETS_init (cfg))
2362 {
2363 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2364 "Unable to initialize TICKETS subsystem.\n");
2365 GNUNET_SCHEDULER_shutdown ();
2366 return;
2367 }
2368 // Connect to identity and namestore services
2369 nsh = GNUNET_NAMESTORE_connect (cfg);
2370 if (NULL == nsh)
2371 {
2372 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
2373 "error connecting to namestore");
2374 }
2375
2376 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
2377}
2378
2379
2380/**
2381 * Called whenever a client is disconnected.
2382 *
2383 * @param cls closure
2384 * @param client identification of the client
2385 * @param app_ctx @a client
2386 */
2387static void
2388client_disconnect_cb (void *cls,
2389 struct GNUNET_SERVICE_Client *client,
2390 void *app_ctx)
2391{
2392 struct IdpClient *idp = app_ctx;
2393
2394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
2395 GNUNET_CONTAINER_DLL_remove (client_list_head,
2396 client_list_tail,
2397 idp);
2398 cleanup_client (idp);
2399}
2400
2401
2402/**
2403 * Add a client to our list of active clients.
2404 *
2405 * @param cls NULL
2406 * @param client client to add
2407 * @param mq message queue for @a client
2408 * @return internal namestore client structure for this client
2409 */
2410static void *
2411client_connect_cb (void *cls,
2412 struct GNUNET_SERVICE_Client *client,
2413 struct GNUNET_MQ_Handle *mq)
2414{
2415 struct IdpClient *idp;
2416
2417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
2418 idp = GNUNET_new (struct IdpClient);
2419 idp->client = client;
2420 idp->mq = mq;
2421 GNUNET_CONTAINER_DLL_insert (client_list_head,
2422 client_list_tail,
2423 idp);
2424 return idp;
2425}
2426
2427
2428/**
2429 * Define "main" method using service macro.
2430 */
2431GNUNET_SERVICE_MAIN (
2432 "reclaim",
2433 GNUNET_SERVICE_OPTION_NONE,
2434 &run,
2435 &client_connect_cb,
2436 &client_disconnect_cb,
2437 NULL,
2438 GNUNET_MQ_hd_var_size (attribute_store_message,
2439 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE,
2440 struct AttributeStoreMessage,
2441 NULL),
2442 GNUNET_MQ_hd_var_size (credential_store_message,
2443 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_STORE,
2444 struct AttributeStoreMessage,
2445 NULL),
2446 GNUNET_MQ_hd_var_size (attribute_delete_message,
2447 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_DELETE,
2448 struct AttributeDeleteMessage,
2449 NULL),
2450 GNUNET_MQ_hd_var_size (credential_delete_message,
2451 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_DELETE,
2452 struct AttributeDeleteMessage,
2453 NULL),
2454 GNUNET_MQ_hd_fixed_size (iteration_start,
2455 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START,
2456 struct AttributeIterationStartMessage,
2457 NULL),
2458 GNUNET_MQ_hd_fixed_size (iteration_next,
2459 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT,
2460 struct AttributeIterationNextMessage,
2461 NULL),
2462 GNUNET_MQ_hd_fixed_size (iteration_stop,
2463 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP,
2464 struct AttributeIterationStopMessage,
2465 NULL),
2466 GNUNET_MQ_hd_fixed_size (credential_iteration_start,
2467 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_START,
2468 struct CredentialIterationStartMessage,
2469 NULL),
2470 GNUNET_MQ_hd_fixed_size (credential_iteration_next,
2471 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_NEXT,
2472 struct CredentialIterationNextMessage,
2473 NULL),
2474 GNUNET_MQ_hd_fixed_size (credential_iteration_stop,
2475 GNUNET_MESSAGE_TYPE_RECLAIM_CREDENTIAL_ITERATION_STOP,
2476 struct CredentialIterationStopMessage,
2477 NULL),
2478
2479 GNUNET_MQ_hd_var_size (issue_ticket_message,
2480 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET,
2481 struct IssueTicketMessage,
2482 NULL),
2483 GNUNET_MQ_hd_var_size (consume_ticket_message,
2484 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET,
2485 struct ConsumeTicketMessage,
2486 NULL),
2487 GNUNET_MQ_hd_fixed_size (ticket_iteration_start,
2488 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START,
2489 struct TicketIterationStartMessage,
2490 NULL),
2491 GNUNET_MQ_hd_fixed_size (ticket_iteration_next,
2492 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT,
2493 struct TicketIterationNextMessage,
2494 NULL),
2495 GNUNET_MQ_hd_fixed_size (ticket_iteration_stop,
2496 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP,
2497 struct TicketIterationStopMessage,
2498 NULL),
2499 GNUNET_MQ_hd_var_size (revoke_ticket_message,
2500 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET,
2501 struct RevokeTicketMessage,
2502 NULL),
2503 GNUNET_MQ_handler_end ());
2504/* end of gnunet-service-reclaim.c */