2 This file is part of GNUnet.
3 Copyright (C) 2016 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 * @file reclaim/reclaim_api.c
23 * @brief api to interact with the reclaim service
24 * @author Martin Schanzenbach
28 #include "gnunet_util_lib.h"
30 #include "gnunet_constants.h"
31 #include "gnunet_mq_lib.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_reclaim_attribute_lib.h"
34 #include "gnunet_reclaim_service.h"
37 #define LOG(kind, ...) GNUNET_log_from (kind, "reclaim-api", __VA_ARGS__)
41 * Handle for an operation with the service.
43 struct GNUNET_RECLAIM_Operation
49 struct GNUNET_RECLAIM_Handle *h;
52 * We keep operations in a DLL.
54 struct GNUNET_RECLAIM_Operation *next;
57 * We keep operations in a DLL.
59 struct GNUNET_RECLAIM_Operation *prev;
62 * Message to send to the service.
63 * Allocated at the end of this struct.
65 const struct GNUNET_MessageHeader *msg;
68 * Continuation to invoke after attribute store call
70 GNUNET_RECLAIM_ContinuationWithStatus as_cb;
73 * Attribute result callback
75 GNUNET_RECLAIM_AttributeResult ar_cb;
78 * Revocation result callback
80 GNUNET_RECLAIM_ContinuationWithStatus rvk_cb;
83 * Ticket result callback
85 GNUNET_RECLAIM_TicketCallback tr_cb;
88 * Envelope with the message for this queue entry.
90 struct GNUNET_MQ_Envelope *env;
98 * Closure for @e cont or @e cb.
105 * Handle for a ticket iterator operation
107 struct GNUNET_RECLAIM_TicketIterator
113 struct GNUNET_RECLAIM_TicketIterator *next;
118 struct GNUNET_RECLAIM_TicketIterator *prev;
121 * Main handle to access the idp.
123 struct GNUNET_RECLAIM_Handle *h;
126 * Function to call on completion.
128 GNUNET_SCHEDULER_TaskCallback finish_cb;
131 * Closure for @e finish_cb.
136 * The continuation to call with the results
138 GNUNET_RECLAIM_TicketCallback tr_cb;
141 * Closure for @e tr_cb.
146 * Function to call on errors.
148 GNUNET_SCHEDULER_TaskCallback error_cb;
151 * Closure for @e error_cb.
156 * Envelope of the message to send to the service, if not yet
159 struct GNUNET_MQ_Envelope *env;
162 * The operation id this zone iteration operation has
169 * Handle for a attribute iterator operation
171 struct GNUNET_RECLAIM_AttributeIterator
177 struct GNUNET_RECLAIM_AttributeIterator *next;
182 struct GNUNET_RECLAIM_AttributeIterator *prev;
185 * Main handle to access the service.
187 struct GNUNET_RECLAIM_Handle *h;
190 * Function to call on completion.
192 GNUNET_SCHEDULER_TaskCallback finish_cb;
195 * Closure for @e finish_cb.
200 * The continuation to call with the results
202 GNUNET_RECLAIM_AttributeResult proc;
205 * Closure for @e proc.
210 * Function to call on errors.
212 GNUNET_SCHEDULER_TaskCallback error_cb;
215 * Closure for @e error_cb.
220 * Envelope of the message to send to the service, if not yet
223 struct GNUNET_MQ_Envelope *env;
226 * Private key of the zone.
228 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
231 * The operation id this zone iteration operation has
238 * Handle to the service.
240 struct GNUNET_RECLAIM_Handle
243 * Configuration to use.
245 const struct GNUNET_CONFIGURATION_Handle *cfg;
248 * Socket (if available).
250 struct GNUNET_CLIENT_Connection *client;
258 * Head of active operations.
260 struct GNUNET_RECLAIM_Operation *op_head;
263 * Tail of active operations.
265 struct GNUNET_RECLAIM_Operation *op_tail;
268 * Head of active iterations
270 struct GNUNET_RECLAIM_AttributeIterator *it_head;
273 * Tail of active iterations
275 struct GNUNET_RECLAIM_AttributeIterator *it_tail;
278 * Head of active iterations
280 struct GNUNET_RECLAIM_TicketIterator *ticket_it_head;
283 * Tail of active iterations
285 struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail;
288 * Currently pending transmission request, or NULL for none.
290 struct GNUNET_CLIENT_TransmitHandle *th;
293 * Task doing exponential back-off trying to reconnect.
295 struct GNUNET_SCHEDULER_Task *reconnect_task;
298 * Time for next connect retry.
300 struct GNUNET_TIME_Relative reconnect_backoff;
303 * Connection to service (if available).
305 struct GNUNET_MQ_Handle *mq;
308 * Request Id generator. Incremented by one for each request.
313 * Are we polling for incoming messages right now?
320 * Try again to connect to the service.
322 * @param h handle to the reclaim service.
325 reconnect (struct GNUNET_RECLAIM_Handle *h);
331 * @param cls the handle
334 reconnect_task (void *cls)
336 struct GNUNET_RECLAIM_Handle *handle = cls;
338 handle->reconnect_task = NULL;
344 * Disconnect from service and then reconnect.
346 * @param handle our service
349 force_reconnect (struct GNUNET_RECLAIM_Handle *handle)
351 GNUNET_MQ_destroy (handle->mq);
353 handle->reconnect_backoff =
354 GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
355 handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (
356 handle->reconnect_backoff, &reconnect_task, handle);
363 * @param it entry to free
366 free_it (struct GNUNET_RECLAIM_AttributeIterator *it)
368 struct GNUNET_RECLAIM_Handle *h = it->h;
370 GNUNET_CONTAINER_DLL_remove (h->it_head, h->it_tail, it);
372 GNUNET_MQ_discard (it->env);
379 * @param op the operation to free
382 free_op (struct GNUNET_RECLAIM_Operation *op)
387 GNUNET_MQ_discard (op->env);
393 * Generic error handler, called with the appropriate error code and
394 * the same closure specified at the creation of the message queue.
395 * Not every message queue implementation supports an error handler.
397 * @param cls closure with the `struct GNUNET_GNS_Handle *`
398 * @param error error code
401 mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
403 struct GNUNET_RECLAIM_Handle *handle = cls;
404 force_reconnect (handle);
409 * Handle an incoming message of type
410 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
413 * @param msg the message we received
416 handle_attribute_store_response (void *cls,
417 const struct AttributeStoreResultMessage *msg)
419 struct GNUNET_RECLAIM_Handle *h = cls;
420 struct GNUNET_RECLAIM_Operation *op;
421 uint32_t r_id = ntohl (msg->id);
425 for (op = h->op_head; NULL != op; op = op->next)
426 if (op->r_id == r_id)
431 res = ntohl (msg->op_result);
432 LOG (GNUNET_ERROR_TYPE_DEBUG,
433 "Received ATTRIBUTE_STORE_RESPONSE with result %d\n", res);
435 /* TODO: add actual error message to response... */
436 if (GNUNET_SYSERR == res)
437 emsg = _ ("failed to store record\n");
440 if (NULL != op->as_cb)
441 op->as_cb (op->cls, res, emsg);
442 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
448 * Handle an incoming message of type
449 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
452 * @param msg the message we received
453 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
456 check_consume_ticket_result (void *cls,
457 const struct ConsumeTicketResultMessage *msg)
462 msg_len = ntohs (msg->header.size);
463 attrs_len = ntohs (msg->attrs_len);
464 if (msg_len != sizeof (struct ConsumeTicketResultMessage) + attrs_len) {
466 return GNUNET_SYSERR;
473 * Handle an incoming message of type
474 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
477 * @param msg the message we received
480 handle_consume_ticket_result (void *cls,
481 const struct ConsumeTicketResultMessage *msg)
483 struct GNUNET_RECLAIM_Handle *h = cls;
484 struct GNUNET_RECLAIM_Operation *op;
486 uint32_t r_id = ntohl (msg->id);
488 attrs_len = ntohs (msg->attrs_len);
489 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
492 for (op = h->op_head; NULL != op; op = op->next)
493 if (op->r_id == r_id)
499 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
500 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
502 GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char *)&msg[1], attrs_len);
503 if (NULL != op->ar_cb) {
505 op->ar_cb (op->cls, &msg->identity, NULL);
507 for (le = attrs->list_head; NULL != le; le = le->next)
508 op->ar_cb (op->cls, &msg->identity, le->claim);
509 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
513 op->ar_cb (op->cls, NULL, NULL);
514 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
524 * Handle an incoming message of type
525 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
528 * @param msg the message we received
529 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
532 check_attribute_result (void *cls, const struct AttributeResultMessage *msg)
537 msg_len = ntohs (msg->header.size);
538 attr_len = ntohs (msg->attr_len);
539 if (msg_len != sizeof (struct AttributeResultMessage) + attr_len) {
541 return GNUNET_SYSERR;
548 * Handle an incoming message of type
549 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
552 * @param msg the message we received
555 handle_attribute_result (void *cls, const struct AttributeResultMessage *msg)
557 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
558 struct GNUNET_RECLAIM_Handle *h = cls;
559 struct GNUNET_RECLAIM_AttributeIterator *it;
560 struct GNUNET_RECLAIM_Operation *op;
562 uint32_t r_id = ntohl (msg->id);
564 attr_len = ntohs (msg->attr_len);
565 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing attribute result.\n");
568 for (it = h->it_head; NULL != it; it = it->next)
569 if (it->r_id == r_id)
571 for (op = h->op_head; NULL != op; op = op->next)
572 if (op->r_id == r_id)
574 if ((NULL == it) && (NULL == op))
578 (memcmp (&msg->identity, &identity_dummy, sizeof (identity_dummy))))) {
579 if ((NULL == it) && (NULL == op)) {
585 if (NULL != it->finish_cb)
586 it->finish_cb (it->finish_cb_cls);
590 if (NULL != op->ar_cb)
591 op->ar_cb (op->cls, NULL, NULL);
592 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
599 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
600 attr = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char *)&msg[1], attr_len);
602 if (NULL != it->proc)
603 it->proc (it->proc_cls, &msg->identity, attr);
604 } else if (NULL != op) {
605 if (NULL != op->ar_cb)
606 op->ar_cb (op->cls, &msg->identity, attr);
615 * Handle an incoming message of type
616 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
619 * @param msg the message we received
620 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
623 check_ticket_result (void *cls, const struct TicketResultMessage *msg)
627 msg_len = ntohs (msg->header.size);
628 if (msg_len < sizeof (struct TicketResultMessage)) {
630 return GNUNET_SYSERR;
637 * Handle an incoming message of type
638 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
641 * @param msg the message we received
644 handle_ticket_result (void *cls, const struct TicketResultMessage *msg)
646 struct GNUNET_RECLAIM_Handle *handle = cls;
647 struct GNUNET_RECLAIM_Operation *op;
648 struct GNUNET_RECLAIM_TicketIterator *it;
649 const struct GNUNET_RECLAIM_Ticket *ticket;
650 uint32_t r_id = ntohl (msg->id);
653 for (op = handle->op_head; NULL != op; op = op->next)
654 if (op->r_id == r_id)
656 for (it = handle->ticket_it_head; NULL != it; it = it->next)
657 if (it->r_id == r_id)
659 if ((NULL == op) && (NULL == it))
661 msg_len = ntohs (msg->header.size);
663 GNUNET_CONTAINER_DLL_remove (handle->op_head, handle->op_tail, op);
664 if (msg_len == sizeof (struct TicketResultMessage)) {
665 if (NULL != op->tr_cb)
666 op->tr_cb (op->cls, NULL);
668 ticket = (struct GNUNET_RECLAIM_Ticket *)&msg[1];
669 if (NULL != op->tr_cb)
670 op->tr_cb (op->cls, ticket);
674 } else if (NULL != it) {
675 if (msg_len == sizeof (struct TicketResultMessage)) {
676 if (NULL != it->tr_cb)
677 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
678 handle->ticket_it_tail, it);
679 it->finish_cb (it->finish_cb_cls);
682 ticket = (struct GNUNET_RECLAIM_Ticket *)&msg[1];
683 if (NULL != it->tr_cb)
684 it->tr_cb (it->cls, ticket);
693 * Handle an incoming message of type
694 * #GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT
697 * @param msg the message we received
700 handle_revoke_ticket_result (void *cls,
701 const struct RevokeTicketResultMessage *msg)
703 struct GNUNET_RECLAIM_Handle *h = cls;
704 struct GNUNET_RECLAIM_Operation *op;
705 uint32_t r_id = ntohl (msg->id);
708 LOG (GNUNET_ERROR_TYPE_DEBUG, "Processing revocation result.\n");
711 for (op = h->op_head; NULL != op; op = op->next)
712 if (op->r_id == r_id)
716 success = ntohl (msg->success);
718 if (NULL != op->rvk_cb) {
719 op->rvk_cb (op->cls, success, NULL);
721 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
730 * Try again to connect to the service.
732 * @param h handle to the reclaim service.
735 reconnect (struct GNUNET_RECLAIM_Handle *h)
737 struct GNUNET_MQ_MessageHandler handlers[] = {
738 GNUNET_MQ_hd_fixed_size (
739 attribute_store_response,
740 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE,
741 struct AttributeStoreResultMessage, h),
742 GNUNET_MQ_hd_var_size (attribute_result,
743 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
744 struct AttributeResultMessage, h),
745 GNUNET_MQ_hd_var_size (ticket_result,
746 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
747 struct TicketResultMessage, h),
748 GNUNET_MQ_hd_var_size (consume_ticket_result,
749 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT,
750 struct ConsumeTicketResultMessage, h),
751 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
752 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT,
753 struct RevokeTicketResultMessage, h),
754 GNUNET_MQ_handler_end ()};
755 struct GNUNET_RECLAIM_Operation *op;
757 GNUNET_assert (NULL == h->mq);
758 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to reclaim service.\n");
761 GNUNET_CLIENT_connect (h->cfg, "reclaim", handlers, &mq_error_handler, h);
764 for (op = h->op_head; NULL != op; op = op->next)
765 GNUNET_MQ_send_copy (h->mq, op->env);
770 * Connect to the reclaim service.
772 * @param cfg the configuration to use
773 * @return handle to use
775 struct GNUNET_RECLAIM_Handle *
776 GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
778 struct GNUNET_RECLAIM_Handle *h;
780 h = GNUNET_new (struct GNUNET_RECLAIM_Handle);
792 * Cancel an operation. Note that the operation MAY still
793 * be executed; this merely cancels the continuation; if the request
794 * was already transmitted, the service may still choose to complete
797 * @param op operation to cancel
800 GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op)
802 struct GNUNET_RECLAIM_Handle *h = op->h;
804 GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op);
810 * Disconnect from service
812 * @param h handle to destroy
815 GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h)
817 GNUNET_assert (NULL != h);
819 GNUNET_MQ_destroy (h->mq);
822 if (NULL != h->reconnect_task) {
823 GNUNET_SCHEDULER_cancel (h->reconnect_task);
824 h->reconnect_task = NULL;
826 GNUNET_assert (NULL == h->op_head);
831 * Store an attribute. If the attribute is already present,
832 * it is replaced with the new attribute.
834 * @param h handle to the re:claimID service
835 * @param pkey private key of the identity
836 * @param attr the attribute value
837 * @param exp_interval the relative expiration interval for the attribute
838 * @param cont continuation to call when done
839 * @param cont_cls closure for @a cont
840 * @return handle to abort the request
842 struct GNUNET_RECLAIM_Operation *
843 GNUNET_RECLAIM_attribute_store (
844 struct GNUNET_RECLAIM_Handle *h,
845 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
846 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
847 const struct GNUNET_TIME_Relative *exp_interval,
848 GNUNET_RECLAIM_ContinuationWithStatus cont, void *cont_cls)
850 struct GNUNET_RECLAIM_Operation *op;
851 struct AttributeStoreMessage *sam;
854 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
858 op->r_id = h->r_id_gen++;
859 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
860 attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (attr);
861 op->env = GNUNET_MQ_msg_extra (sam, attr_len,
862 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE);
863 sam->identity = *pkey;
864 sam->id = htonl (op->r_id);
865 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
867 GNUNET_RECLAIM_ATTRIBUTE_serialize (attr, (char *)&sam[1]);
869 sam->attr_len = htons (attr_len);
871 GNUNET_MQ_send_copy (h->mq, op->env);
877 * List all attributes for a local identity.
878 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
879 * for any other calls than #GNUNET_RECLAIM_get_attributes_next() and
880 * #GNUNET_RECLAIM_get_attributes_stop. @a proc will be called once
881 * immediately, and then again after
882 * #GNUNET_RECLAIM_get_attributes_next() is invoked.
884 * On error (disconnect), @a error_cb will be invoked.
885 * On normal completion, @a finish_cb proc will be
888 * @param h Handle to the re:claimID service
889 * @param identity Identity to iterate over
890 * @param error_cb Function to call on error (i.e. disconnect),
891 * the handle is afterwards invalid
892 * @param error_cb_cls Closure for @a error_cb
893 * @param proc Function to call on each attribute
894 * @param proc_cls Closure for @a proc
895 * @param finish_cb Function to call on completion
896 * the handle is afterwards invalid
897 * @param finish_cb_cls Closure for @a finish_cb
898 * @return an iterator Handle to use for iteration
900 struct GNUNET_RECLAIM_AttributeIterator *
901 GNUNET_RECLAIM_get_attributes_start (
902 struct GNUNET_RECLAIM_Handle *h,
903 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
904 GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls,
905 GNUNET_RECLAIM_AttributeResult proc, void *proc_cls,
906 GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls)
908 struct GNUNET_RECLAIM_AttributeIterator *it;
909 struct GNUNET_MQ_Envelope *env;
910 struct AttributeIterationStartMessage *msg;
914 it = GNUNET_new (struct GNUNET_RECLAIM_AttributeIterator);
916 it->error_cb = error_cb;
917 it->error_cb_cls = error_cb_cls;
918 it->finish_cb = finish_cb;
919 it->finish_cb_cls = finish_cb_cls;
921 it->proc_cls = proc_cls;
923 it->identity = *identity;
924 GNUNET_CONTAINER_DLL_insert_tail (h->it_head, h->it_tail, it);
925 env = GNUNET_MQ_msg (msg,
926 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START);
927 msg->id = htonl (rid);
928 msg->identity = *identity;
932 GNUNET_MQ_send (h->mq, env);
938 * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
939 * for the next record.
941 * @param it the iterator
944 GNUNET_RECLAIM_get_attributes_next (struct GNUNET_RECLAIM_AttributeIterator *it)
946 struct GNUNET_RECLAIM_Handle *h = it->h;
947 struct AttributeIterationNextMessage *msg;
948 struct GNUNET_MQ_Envelope *env;
951 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT);
952 msg->id = htonl (it->r_id);
953 GNUNET_MQ_send (h->mq, env);
958 * Stops iteration and releases the handle for further calls. Must
959 * be called on any iteration that has not yet completed prior to calling
960 * #GNUNET_RECLAIM_disconnect.
962 * @param it the iterator
965 GNUNET_RECLAIM_get_attributes_stop (struct GNUNET_RECLAIM_AttributeIterator *it)
967 struct GNUNET_RECLAIM_Handle *h = it->h;
968 struct GNUNET_MQ_Envelope *env;
969 struct AttributeIterationStopMessage *msg;
972 env = GNUNET_MQ_msg (msg,
973 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP);
974 msg->id = htonl (it->r_id);
975 GNUNET_MQ_send (h->mq, env);
982 * Issues a ticket to another relying party. The identity may use
983 * @GNUNET_RECLAIM_ticket_consume to consume the ticket
984 * and retrieve the attributes specified in the attribute list.
986 * @param h the reclaim to use
987 * @param iss the issuing identity (= the user)
988 * @param rp the subject of the ticket (= the relying party)
989 * @param attrs the attributes that the relying party is given access to
990 * @param cb the callback
991 * @param cb_cls the callback closure
992 * @return handle to abort the operation
994 struct GNUNET_RECLAIM_Operation *
995 GNUNET_RECLAIM_ticket_issue (
996 struct GNUNET_RECLAIM_Handle *h,
997 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
998 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
999 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
1000 GNUNET_RECLAIM_TicketCallback cb, void *cb_cls)
1002 struct GNUNET_RECLAIM_Operation *op;
1003 struct IssueTicketMessage *tim;
1006 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1010 op->r_id = h->r_id_gen++;
1011 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1012 attr_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
1013 op->env = GNUNET_MQ_msg_extra (tim, attr_len,
1014 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET);
1015 tim->identity = *iss;
1017 tim->id = htonl (op->r_id);
1019 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs, (char *)&tim[1]);
1021 tim->attr_len = htons (attr_len);
1023 GNUNET_MQ_send_copy (h->mq, op->env);
1029 * Consumes an issued ticket. The ticket is persisted
1030 * and used to retrieve identity information from the issuer
1032 * @param h the reclaim to use
1033 * @param identity the identity that is the subject of the issued ticket (the
1035 * @param ticket the issued ticket to consume
1036 * @param cb the callback to call
1037 * @param cb_cls the callback closure
1038 * @return handle to abort the operation
1040 struct GNUNET_RECLAIM_Operation *
1041 GNUNET_RECLAIM_ticket_consume (
1042 struct GNUNET_RECLAIM_Handle *h,
1043 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1044 const struct GNUNET_RECLAIM_Ticket *ticket,
1045 GNUNET_RECLAIM_AttributeResult cb, void *cb_cls)
1047 struct GNUNET_RECLAIM_Operation *op;
1048 struct ConsumeTicketMessage *ctm;
1050 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1054 op->r_id = h->r_id_gen++;
1055 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1057 GNUNET_MQ_msg_extra (ctm, sizeof (const struct GNUNET_RECLAIM_Ticket),
1058 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET);
1059 ctm->identity = *identity;
1060 ctm->id = htonl (op->r_id);
1062 GNUNET_memcpy ((char *)&ctm[1], ticket,
1063 sizeof (const struct GNUNET_RECLAIM_Ticket));
1066 GNUNET_MQ_send_copy (h->mq, op->env);
1072 * Lists all tickets that have been issued to remote
1073 * identites (relying parties)
1075 * @param h the reclaim to use
1076 * @param identity the issuing identity
1077 * @param error_cb function to call on error (i.e. disconnect),
1078 * the handle is afterwards invalid
1079 * @param error_cb_cls closure for @a error_cb
1080 * @param proc function to call on each ticket; it
1081 * will be called repeatedly with a value (if available)
1082 * @param proc_cls closure for @a proc
1083 * @param finish_cb function to call on completion
1084 * the handle is afterwards invalid
1085 * @param finish_cb_cls closure for @a finish_cb
1086 * @return an iterator handle to use for iteration
1088 struct GNUNET_RECLAIM_TicketIterator *
1089 GNUNET_RECLAIM_ticket_iteration_start (
1090 struct GNUNET_RECLAIM_Handle *h,
1091 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1092 GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls,
1093 GNUNET_RECLAIM_TicketCallback proc, void *proc_cls,
1094 GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls)
1096 struct GNUNET_RECLAIM_TicketIterator *it;
1097 struct GNUNET_MQ_Envelope *env;
1098 struct TicketIterationStartMessage *msg;
1101 rid = h->r_id_gen++;
1102 it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator);
1104 it->error_cb = error_cb;
1105 it->error_cb_cls = error_cb_cls;
1106 it->finish_cb = finish_cb;
1107 it->finish_cb_cls = finish_cb_cls;
1111 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, h->ticket_it_tail, it);
1112 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
1113 msg->id = htonl (rid);
1114 msg->identity = *identity;
1118 GNUNET_MQ_send (h->mq, env);
1124 * Calls the ticket processor specified in
1125 * #GNUNET_RECLAIM_ticket_iteration_start for the next record.
1127 * @param it the iterator
1130 GNUNET_RECLAIM_ticket_iteration_next (struct GNUNET_RECLAIM_TicketIterator *it)
1132 struct GNUNET_RECLAIM_Handle *h = it->h;
1133 struct TicketIterationNextMessage *msg;
1134 struct GNUNET_MQ_Envelope *env;
1136 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT);
1137 msg->id = htonl (it->r_id);
1138 GNUNET_MQ_send (h->mq, env);
1143 * Stops iteration and releases the handle for further calls. Must
1144 * be called on any iteration that has not yet completed prior to calling
1145 * #GNUNET_RECLAIM_disconnect.
1147 * @param it the iterator
1150 GNUNET_RECLAIM_ticket_iteration_stop (struct GNUNET_RECLAIM_TicketIterator *it)
1152 struct GNUNET_RECLAIM_Handle *h = it->h;
1153 struct GNUNET_MQ_Envelope *env;
1154 struct TicketIterationStopMessage *msg;
1156 if (NULL != h->mq) {
1158 GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP);
1159 msg->id = htonl (it->r_id);
1160 GNUNET_MQ_send (h->mq, env);
1167 * Revoked an issued ticket. The relying party will be unable to retrieve
1168 * attributes. Other issued tickets remain unaffected.
1169 * This includes tickets issued to other relying parties as well as to
1170 * other tickets issued to the audience specified in this ticket.
1172 * @param h the identity provider to use
1173 * @param identity the issuing identity
1174 * @param ticket the ticket to revoke
1175 * @param cb the callback
1176 * @param cb_cls the callback closure
1177 * @return handle to abort the operation
1179 struct GNUNET_RECLAIM_Operation *
1180 GNUNET_RECLAIM_ticket_revoke (
1181 struct GNUNET_RECLAIM_Handle *h,
1182 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1183 const struct GNUNET_RECLAIM_Ticket *ticket,
1184 GNUNET_RECLAIM_ContinuationWithStatus cb, void *cb_cls)
1186 struct GNUNET_RECLAIM_Operation *op;
1187 struct RevokeTicketMessage *msg;
1190 rid = h->r_id_gen++;
1191 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1196 GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, op);
1197 op->env = GNUNET_MQ_msg_extra (msg, sizeof (struct GNUNET_RECLAIM_Ticket),
1198 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET);
1199 msg->id = htonl (rid);
1200 msg->identity = *identity;
1201 GNUNET_memcpy (&msg[1], ticket, sizeof (struct GNUNET_RECLAIM_Ticket));
1202 if (NULL != h->mq) {
1203 GNUNET_MQ_send (h->mq, op->env);
1210 /* end of reclaim_api.c */