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/>.
20 * @file reclaim/reclaim_api.c
21 * @brief api to interact with the reclaim service
22 * @author Martin Schanzenbach
25 #include "gnunet_util_lib.h"
26 #include "gnunet_constants.h"
27 #include "gnunet_protocols.h"
28 #include "gnunet_mq_lib.h"
29 #include "gnunet_reclaim_service.h"
30 #include "gnunet_reclaim_attribute_lib.h"
33 #define LOG(kind,...) GNUNET_log_from (kind, "reclaim-api",__VA_ARGS__)
37 * Handle for an operation with the service.
39 struct GNUNET_RECLAIM_Operation
45 struct GNUNET_RECLAIM_Handle *h;
48 * We keep operations in a DLL.
50 struct GNUNET_RECLAIM_Operation *next;
53 * We keep operations in a DLL.
55 struct GNUNET_RECLAIM_Operation *prev;
58 * Message to send to the service.
59 * Allocated at the end of this struct.
61 const struct GNUNET_MessageHeader *msg;
64 * Continuation to invoke after attribute store call
66 GNUNET_RECLAIM_ContinuationWithStatus as_cb;
69 * Attribute result callback
71 GNUNET_RECLAIM_AttributeResult ar_cb;
74 * Revocation result callback
76 GNUNET_RECLAIM_ContinuationWithStatus rvk_cb;
79 * Ticket result callback
81 GNUNET_RECLAIM_TicketCallback tr_cb;
84 * Envelope with the message for this queue entry.
86 struct GNUNET_MQ_Envelope *env;
94 * Closure for @e cont or @e cb.
101 * Handle for a ticket iterator operation
103 struct GNUNET_RECLAIM_TicketIterator
109 struct GNUNET_RECLAIM_TicketIterator *next;
114 struct GNUNET_RECLAIM_TicketIterator *prev;
117 * Main handle to access the idp.
119 struct GNUNET_RECLAIM_Handle *h;
122 * Function to call on completion.
124 GNUNET_SCHEDULER_TaskCallback finish_cb;
127 * Closure for @e error_cb.
132 * The continuation to call with the results
134 GNUNET_RECLAIM_TicketCallback tr_cb;
137 * Closure for @e tr_cb.
142 * Function to call on errors.
144 GNUNET_SCHEDULER_TaskCallback error_cb;
147 * Closure for @e error_cb.
152 * Envelope of the message to send to the service, if not yet
155 struct GNUNET_MQ_Envelope *env;
158 * The operation id this zone iteration operation has
166 * Handle for a attribute iterator operation
168 struct GNUNET_RECLAIM_AttributeIterator
174 struct GNUNET_RECLAIM_AttributeIterator *next;
179 struct GNUNET_RECLAIM_AttributeIterator *prev;
182 * Main handle to access the idp.
184 struct GNUNET_RECLAIM_Handle *h;
187 * Function to call on completion.
189 GNUNET_SCHEDULER_TaskCallback finish_cb;
192 * Closure for @e error_cb.
197 * The continuation to call with the results
199 GNUNET_RECLAIM_AttributeResult proc;
202 * Closure for @e proc.
207 * Function to call on errors.
209 GNUNET_SCHEDULER_TaskCallback error_cb;
212 * Closure for @e error_cb.
217 * Envelope of the message to send to the service, if not yet
220 struct GNUNET_MQ_Envelope *env;
223 * Private key of the zone.
225 struct GNUNET_CRYPTO_EcdsaPrivateKey identity;
228 * The operation id this zone iteration operation has
236 * Handle for the service.
238 struct GNUNET_RECLAIM_Handle
241 * Configuration to use.
243 const struct GNUNET_CONFIGURATION_Handle *cfg;
246 * Socket (if available).
248 struct GNUNET_CLIENT_Connection *client;
256 * Head of active operations.
258 struct GNUNET_RECLAIM_Operation *op_head;
261 * Tail of active operations.
263 struct GNUNET_RECLAIM_Operation *op_tail;
266 * Head of active iterations
268 struct GNUNET_RECLAIM_AttributeIterator *it_head;
271 * Tail of active iterations
273 struct GNUNET_RECLAIM_AttributeIterator *it_tail;
276 * Head of active iterations
278 struct GNUNET_RECLAIM_TicketIterator *ticket_it_head;
281 * Tail of active iterations
283 struct GNUNET_RECLAIM_TicketIterator *ticket_it_tail;
287 * Currently pending transmission request, or NULL for none.
289 struct GNUNET_CLIENT_TransmitHandle *th;
292 * Task doing exponential back-off trying to reconnect.
294 struct GNUNET_SCHEDULER_Task * reconnect_task;
297 * Time for next connect retry.
299 struct GNUNET_TIME_Relative reconnect_backoff;
302 * Connection to service (if available).
304 struct GNUNET_MQ_Handle *mq;
307 * Request Id generator. Incremented by one for each request.
312 * Are we polling for incoming messages right now?
319 * Try again to connect to the service.
321 * @param h handle to the reclaim service.
324 reconnect (struct GNUNET_RECLAIM_Handle *h);
329 * @param cls the handle
332 reconnect_task (void *cls)
334 struct GNUNET_RECLAIM_Handle *handle = cls;
336 handle->reconnect_task = NULL;
342 * Disconnect from service and then reconnect.
344 * @param handle our service
347 force_reconnect (struct GNUNET_RECLAIM_Handle *handle)
349 GNUNET_MQ_destroy (handle->mq);
351 handle->reconnect_backoff
352 = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
353 handle->reconnect_task
354 = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
362 * @param it entry to free
365 free_it (struct GNUNET_RECLAIM_AttributeIterator *it)
367 struct GNUNET_RECLAIM_Handle *h = it->h;
369 GNUNET_CONTAINER_DLL_remove (h->it_head,
373 GNUNET_MQ_discard (it->env);
378 free_op (struct GNUNET_RECLAIM_Operation* op)
383 GNUNET_MQ_discard (op->env);
389 * Generic error handler, called with the appropriate error code and
390 * the same closure specified at the creation of the message queue.
391 * Not every message queue implementation supports an error handler.
393 * @param cls closure with the `struct GNUNET_GNS_Handle *`
394 * @param error error code
397 mq_error_handler (void *cls,
398 enum GNUNET_MQ_Error error)
400 struct GNUNET_RECLAIM_Handle *handle = cls;
401 force_reconnect (handle);
405 * Handle an incoming message of type
406 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
409 * @param msg the message we received
412 handle_attribute_store_response (void *cls,
413 const struct AttributeStoreResultMessage *msg)
415 struct GNUNET_RECLAIM_Handle *h = cls;
416 struct GNUNET_RECLAIM_Operation *op;
417 uint32_t r_id = ntohl (msg->id);
421 for (op = h->op_head; NULL != op; op = op->next)
422 if (op->r_id == r_id)
427 res = ntohl (msg->op_result);
428 LOG (GNUNET_ERROR_TYPE_DEBUG,
429 "Received ATTRIBUTE_STORE_RESPONSE with result %d\n",
432 /* TODO: add actual error message to response... */
433 if (GNUNET_SYSERR == res)
434 emsg = _("failed to store record\n");
437 if (NULL != op->as_cb)
441 GNUNET_CONTAINER_DLL_remove (h->op_head,
450 * Handle an incoming message of type
451 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
454 * @param msg the message we received
455 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
458 check_consume_ticket_result (void *cls,
459 const struct ConsumeTicketResultMessage *msg)
464 msg_len = ntohs (msg->header.size);
465 attrs_len = ntohs (msg->attrs_len);
466 if (msg_len != sizeof (struct ConsumeTicketResultMessage) + attrs_len)
469 return GNUNET_SYSERR;
476 * Handle an incoming message of type
477 * #GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT
480 * @param msg the message we received
483 handle_consume_ticket_result (void *cls,
484 const struct ConsumeTicketResultMessage *msg)
486 struct GNUNET_RECLAIM_Handle *h = cls;
487 struct GNUNET_RECLAIM_Operation *op;
489 uint32_t r_id = ntohl (msg->id);
491 attrs_len = ntohs (msg->attrs_len);
492 LOG (GNUNET_ERROR_TYPE_DEBUG,
493 "Processing attribute result.\n");
496 for (op = h->op_head; NULL != op; op = op->next)
497 if (op->r_id == r_id)
503 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs;
504 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
505 attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize ((char*)&msg[1],
507 if (NULL != op->ar_cb)
517 for (le = attrs->list_head; NULL != le; le = le->next)
521 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (attrs);
529 GNUNET_CONTAINER_DLL_remove (h->op_head,
541 * Handle an incoming message of type
542 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
545 * @param msg the message we received
546 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
549 check_attribute_result (void *cls,
550 const struct AttributeResultMessage *msg)
555 msg_len = ntohs (msg->header.size);
556 attr_len = ntohs (msg->attr_len);
557 if (msg_len != sizeof (struct AttributeResultMessage) + attr_len)
560 return GNUNET_SYSERR;
567 * Handle an incoming message of type
568 * #GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT
571 * @param msg the message we received
574 handle_attribute_result (void *cls,
575 const struct AttributeResultMessage *msg)
577 static struct GNUNET_CRYPTO_EcdsaPrivateKey identity_dummy;
578 struct GNUNET_RECLAIM_Handle *h = cls;
579 struct GNUNET_RECLAIM_AttributeIterator *it;
580 struct GNUNET_RECLAIM_Operation *op;
582 uint32_t r_id = ntohl (msg->id);
584 attr_len = ntohs (msg->attr_len);
585 LOG (GNUNET_ERROR_TYPE_DEBUG,
586 "Processing attribute result.\n");
589 for (it = h->it_head; NULL != it; it = it->next)
590 if (it->r_id == r_id)
592 for (op = h->op_head; NULL != op; op = op->next)
593 if (op->r_id == r_id)
595 if ((NULL == it) && (NULL == op))
598 if ( (0 == (memcmp (&msg->identity,
600 sizeof (identity_dummy)))) )
602 if ((NULL == it) && (NULL == op))
610 if (NULL != it->finish_cb)
611 it->finish_cb (it->finish_cb_cls);
616 if (NULL != op->ar_cb)
620 GNUNET_CONTAINER_DLL_remove (h->op_head,
630 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr;
631 attr = GNUNET_RECLAIM_ATTRIBUTE_deserialize ((char*)&msg[1],
635 if (NULL != it->proc)
636 it->proc (it->proc_cls,
639 } else if (NULL != op)
641 if (NULL != op->ar_cb)
654 * Handle an incoming message of type
655 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
658 * @param msg the message we received
659 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
662 check_ticket_result (void *cls,
663 const struct TicketResultMessage *msg)
667 msg_len = ntohs (msg->header.size);
668 if (msg_len < sizeof (struct TicketResultMessage))
671 return GNUNET_SYSERR;
679 * Handle an incoming message of type
680 * #GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT
683 * @param msg the message we received
686 handle_ticket_result (void *cls,
687 const struct TicketResultMessage *msg)
689 struct GNUNET_RECLAIM_Handle *handle = cls;
690 struct GNUNET_RECLAIM_Operation *op;
691 struct GNUNET_RECLAIM_TicketIterator *it;
692 const struct GNUNET_RECLAIM_Ticket *ticket;
693 uint32_t r_id = ntohl (msg->id);
696 for (op = handle->op_head; NULL != op; op = op->next)
697 if (op->r_id == r_id)
699 for (it = handle->ticket_it_head; NULL != it; it = it->next)
700 if (it->r_id == r_id)
702 if ((NULL == op) && (NULL == it))
704 msg_len = ntohs (msg->header.size);
707 GNUNET_CONTAINER_DLL_remove (handle->op_head,
710 if (msg_len == sizeof (struct TicketResultMessage))
712 if (NULL != op->tr_cb)
713 op->tr_cb (op->cls, NULL);
715 ticket = (struct GNUNET_RECLAIM_Ticket *)&msg[1];
716 if (NULL != op->tr_cb)
717 op->tr_cb (op->cls, ticket);
721 } else if (NULL != it) {
722 if (msg_len == sizeof (struct TicketResultMessage))
724 if (NULL != it->tr_cb)
725 GNUNET_CONTAINER_DLL_remove (handle->ticket_it_head,
726 handle->ticket_it_tail,
728 it->finish_cb (it->finish_cb_cls);
731 ticket = (struct GNUNET_RECLAIM_Ticket *)&msg[1];
732 if (NULL != it->tr_cb)
733 it->tr_cb (it->cls, ticket);
742 * Handle an incoming message of type
743 * #GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT
746 * @param msg the message we received
749 handle_revoke_ticket_result (void *cls,
750 const struct RevokeTicketResultMessage *msg)
752 struct GNUNET_RECLAIM_Handle *h = cls;
753 struct GNUNET_RECLAIM_Operation *op;
754 uint32_t r_id = ntohl (msg->id);
757 LOG (GNUNET_ERROR_TYPE_DEBUG,
758 "Processing revocation result.\n");
761 for (op = h->op_head; NULL != op; op = op->next)
762 if (op->r_id == r_id)
766 success = ntohl (msg->success);
768 if (NULL != op->rvk_cb)
774 GNUNET_CONTAINER_DLL_remove (h->op_head,
786 * Try again to connect to the service.
788 * @param h handle to the reclaim service.
791 reconnect (struct GNUNET_RECLAIM_Handle *h)
793 struct GNUNET_MQ_MessageHandler handlers[] = {
794 GNUNET_MQ_hd_fixed_size (attribute_store_response,
795 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE_RESPONSE,
796 struct AttributeStoreResultMessage,
798 GNUNET_MQ_hd_var_size (attribute_result,
799 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_RESULT,
800 struct AttributeResultMessage,
802 GNUNET_MQ_hd_var_size (ticket_result,
803 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT,
804 struct TicketResultMessage,
806 GNUNET_MQ_hd_var_size (consume_ticket_result,
807 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET_RESULT,
808 struct ConsumeTicketResultMessage,
810 GNUNET_MQ_hd_fixed_size (revoke_ticket_result,
811 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET_RESULT,
812 struct RevokeTicketResultMessage,
814 GNUNET_MQ_handler_end ()
816 struct GNUNET_RECLAIM_Operation *op;
818 GNUNET_assert (NULL == h->mq);
819 LOG (GNUNET_ERROR_TYPE_DEBUG,
820 "Connecting to reclaim service.\n");
822 h->mq = GNUNET_CLIENT_connect (h->cfg,
829 for (op = h->op_head; NULL != op; op = op->next)
830 GNUNET_MQ_send_copy (h->mq,
836 * Connect to the reclaim service.
838 * @param cfg the configuration to use
839 * @return handle to use
841 struct GNUNET_RECLAIM_Handle *
842 GNUNET_RECLAIM_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
844 struct GNUNET_RECLAIM_Handle *h;
846 h = GNUNET_new (struct GNUNET_RECLAIM_Handle);
859 * Cancel an operation. Note that the operation MAY still
860 * be executed; this merely cancels the continuation; if the request
861 * was already transmitted, the service may still choose to complete
864 * @param op operation to cancel
867 GNUNET_RECLAIM_cancel (struct GNUNET_RECLAIM_Operation *op)
869 struct GNUNET_RECLAIM_Handle *h = op->h;
871 GNUNET_CONTAINER_DLL_remove (h->op_head,
879 * Disconnect from service
881 * @param h handle to destroy
884 GNUNET_RECLAIM_disconnect (struct GNUNET_RECLAIM_Handle *h)
886 GNUNET_assert (NULL != h);
889 GNUNET_MQ_destroy (h->mq);
892 if (NULL != h->reconnect_task)
894 GNUNET_SCHEDULER_cancel (h->reconnect_task);
895 h->reconnect_task = NULL;
897 GNUNET_assert (NULL == h->op_head);
902 * Store an attribute. If the attribute is already present,
903 * it is replaced with the new attribute.
905 * @param h handle to the reclaim
906 * @param pkey private key of the identity
907 * @param attr the attribute value
908 * @param exp_interval the relative expiration interval for the attribute
909 * @param cont continuation to call when done
910 * @param cont_cls closure for @a cont
911 * @return handle to abort the request
913 struct GNUNET_RECLAIM_Operation *
914 GNUNET_RECLAIM_attribute_store (struct GNUNET_RECLAIM_Handle *h,
915 const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey,
916 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr,
917 const struct GNUNET_TIME_Relative *exp_interval,
918 GNUNET_RECLAIM_ContinuationWithStatus cont,
921 struct GNUNET_RECLAIM_Operation *op;
922 struct AttributeStoreMessage *sam;
925 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
929 op->r_id = h->r_id_gen++;
930 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
933 attr_len = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (attr);
934 op->env = GNUNET_MQ_msg_extra (sam,
936 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_STORE);
937 sam->identity = *pkey;
938 sam->id = htonl (op->r_id);
939 sam->exp = GNUNET_htonll (exp_interval->rel_value_us);
941 GNUNET_RECLAIM_ATTRIBUTE_serialize (attr,
944 sam->attr_len = htons (attr_len);
946 GNUNET_MQ_send_copy (h->mq,
954 * List all attributes for a local identity.
955 * This MUST lock the `struct GNUNET_RECLAIM_Handle`
956 * for any other calls than #GNUNET_RECLAIM_get_attributes_next() and
957 * #GNUNET_RECLAIM_get_attributes_stop. @a proc will be called once
958 * immediately, and then again after
959 * #GNUNET_RECLAIM_get_attributes_next() is invoked.
961 * On error (disconnect), @a error_cb will be invoked.
962 * On normal completion, @a finish_cb proc will be
965 * @param h handle to the idp
966 * @param identity identity to access
967 * @param error_cb function to call on error (i.e. disconnect),
968 * the handle is afterwards invalid
969 * @param error_cb_cls closure for @a error_cb
970 * @param proc function to call on each attribute; it
971 * will be called repeatedly with a value (if available)
972 * @param proc_cls closure for @a proc
973 * @param finish_cb function to call on completion
974 * the handle is afterwards invalid
975 * @param finish_cb_cls closure for @a finish_cb
976 * @return an iterator handle to use for iteration
978 struct GNUNET_RECLAIM_AttributeIterator *
979 GNUNET_RECLAIM_get_attributes_start (struct GNUNET_RECLAIM_Handle *h,
980 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
981 GNUNET_SCHEDULER_TaskCallback error_cb,
983 GNUNET_RECLAIM_AttributeResult proc,
985 GNUNET_SCHEDULER_TaskCallback finish_cb,
988 struct GNUNET_RECLAIM_AttributeIterator *it;
989 struct GNUNET_MQ_Envelope *env;
990 struct AttributeIterationStartMessage *msg;
994 it = GNUNET_new (struct GNUNET_RECLAIM_AttributeIterator);
996 it->error_cb = error_cb;
997 it->error_cb_cls = error_cb_cls;
998 it->finish_cb = finish_cb;
999 it->finish_cb_cls = finish_cb_cls;
1001 it->proc_cls = proc_cls;
1003 it->identity = *identity;
1004 GNUNET_CONTAINER_DLL_insert_tail (h->it_head,
1007 env = GNUNET_MQ_msg (msg,
1008 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_START);
1009 msg->id = htonl (rid);
1010 msg->identity = *identity;
1014 GNUNET_MQ_send (h->mq,
1021 * Calls the record processor specified in #GNUNET_RECLAIM_get_attributes_start
1022 * for the next record.
1024 * @param it the iterator
1027 GNUNET_RECLAIM_get_attributes_next (struct GNUNET_RECLAIM_AttributeIterator *it)
1029 struct GNUNET_RECLAIM_Handle *h = it->h;
1030 struct AttributeIterationNextMessage *msg;
1031 struct GNUNET_MQ_Envelope *env;
1033 env = GNUNET_MQ_msg (msg,
1034 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_NEXT);
1035 msg->id = htonl (it->r_id);
1036 GNUNET_MQ_send (h->mq,
1042 * Stops iteration and releases the idp handle for further calls. Must
1043 * be called on any iteration that has not yet completed prior to calling
1044 * #GNUNET_RECLAIM_disconnect.
1046 * @param it the iterator
1049 GNUNET_RECLAIM_get_attributes_stop (struct GNUNET_RECLAIM_AttributeIterator *it)
1051 struct GNUNET_RECLAIM_Handle *h = it->h;
1052 struct GNUNET_MQ_Envelope *env;
1053 struct AttributeIterationStopMessage *msg;
1057 env = GNUNET_MQ_msg (msg,
1058 GNUNET_MESSAGE_TYPE_RECLAIM_ATTRIBUTE_ITERATION_STOP);
1059 msg->id = htonl (it->r_id);
1060 GNUNET_MQ_send (h->mq,
1068 * Issues a ticket to another identity. The identity may use
1069 * @GNUNET_RECLAIM_authorization_ticket_consume to consume the ticket
1070 * and retrieve the attributes specified in the AttributeList.
1072 * @param h the reclaim to use
1073 * @param iss the issuing identity
1074 * @param rp the subject of the ticket (the relying party)
1075 * @param attrs the attributes that the relying party is given access to
1076 * @param cb the callback
1077 * @param cb_cls the callback closure
1078 * @return handle to abort the operation
1080 struct GNUNET_RECLAIM_Operation *
1081 GNUNET_RECLAIM_ticket_issue (struct GNUNET_RECLAIM_Handle *h,
1082 const struct GNUNET_CRYPTO_EcdsaPrivateKey *iss,
1083 const struct GNUNET_CRYPTO_EcdsaPublicKey *rp,
1084 const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
1085 GNUNET_RECLAIM_TicketCallback cb,
1088 struct GNUNET_RECLAIM_Operation *op;
1089 struct IssueTicketMessage *tim;
1092 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1096 op->r_id = h->r_id_gen++;
1097 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1100 attr_len = GNUNET_RECLAIM_ATTRIBUTE_list_serialize_get_size (attrs);
1101 op->env = GNUNET_MQ_msg_extra (tim,
1103 GNUNET_MESSAGE_TYPE_RECLAIM_ISSUE_TICKET);
1104 tim->identity = *iss;
1106 tim->id = htonl (op->r_id);
1108 GNUNET_RECLAIM_ATTRIBUTE_list_serialize (attrs,
1111 tim->attr_len = htons (attr_len);
1113 GNUNET_MQ_send_copy (h->mq,
1119 * Consumes an issued ticket. The ticket is persisted
1120 * and used to retrieve identity information from the issuer
1122 * @param h the reclaim to use
1123 * @param identity the identity that is the subject of the issued ticket (the relying party)
1124 * @param ticket the issued ticket to consume
1125 * @param cb the callback to call
1126 * @param cb_cls the callback closure
1127 * @return handle to abort the operation
1129 struct GNUNET_RECLAIM_Operation *
1130 GNUNET_RECLAIM_ticket_consume (struct GNUNET_RECLAIM_Handle *h,
1131 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1132 const struct GNUNET_RECLAIM_Ticket *ticket,
1133 GNUNET_RECLAIM_AttributeResult cb,
1136 struct GNUNET_RECLAIM_Operation *op;
1137 struct ConsumeTicketMessage *ctm;
1139 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1143 op->r_id = h->r_id_gen++;
1144 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1147 op->env = GNUNET_MQ_msg_extra (ctm,
1148 sizeof (const struct GNUNET_RECLAIM_Ticket),
1149 GNUNET_MESSAGE_TYPE_RECLAIM_CONSUME_TICKET);
1150 ctm->identity = *identity;
1151 ctm->id = htonl (op->r_id);
1153 GNUNET_memcpy ((char*)&ctm[1],
1155 sizeof (const struct GNUNET_RECLAIM_Ticket));
1158 GNUNET_MQ_send_copy (h->mq,
1166 * Lists all tickets that have been issued to remote
1167 * identites (relying parties)
1169 * @param h the reclaim to use
1170 * @param identity the issuing identity
1171 * @param error_cb function to call on error (i.e. disconnect),
1172 * the handle is afterwards invalid
1173 * @param error_cb_cls closure for @a error_cb
1174 * @param proc function to call on each ticket; it
1175 * will be called repeatedly with a value (if available)
1176 * @param proc_cls closure for @a proc
1177 * @param finish_cb function to call on completion
1178 * the handle is afterwards invalid
1179 * @param finish_cb_cls closure for @a finish_cb
1180 * @return an iterator handle to use for iteration
1182 struct GNUNET_RECLAIM_TicketIterator *
1183 GNUNET_RECLAIM_ticket_iteration_start (struct GNUNET_RECLAIM_Handle *h,
1184 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1185 GNUNET_SCHEDULER_TaskCallback error_cb,
1187 GNUNET_RECLAIM_TicketCallback proc,
1189 GNUNET_SCHEDULER_TaskCallback finish_cb,
1190 void *finish_cb_cls)
1192 struct GNUNET_RECLAIM_TicketIterator *it;
1193 struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub;
1194 struct GNUNET_MQ_Envelope *env;
1195 struct TicketIterationStartMessage *msg;
1198 GNUNET_CRYPTO_ecdsa_key_get_public (identity,
1200 rid = h->r_id_gen++;
1201 it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator);
1203 it->error_cb = error_cb;
1204 it->error_cb_cls = error_cb_cls;
1205 it->finish_cb = finish_cb;
1206 it->finish_cb_cls = finish_cb_cls;
1210 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1213 env = GNUNET_MQ_msg (msg,
1214 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
1215 msg->id = htonl (rid);
1216 msg->identity = identity_pub;
1217 msg->is_audience = htonl (GNUNET_NO);
1221 GNUNET_MQ_send (h->mq,
1229 * Lists all tickets that have been issued to remote
1230 * identites (relying parties)
1232 * @param h the reclaim to use
1233 * @param identity the issuing identity
1234 * @param error_cb function to call on error (i.e. disconnect),
1235 * the handle is afterwards invalid
1236 * @param error_cb_cls closure for @a error_cb
1237 * @param proc function to call on each ticket; it
1238 * will be called repeatedly with a value (if available)
1239 * @param proc_cls closure for @a proc
1240 * @param finish_cb function to call on completion
1241 * the handle is afterwards invalid
1242 * @param finish_cb_cls closure for @a finish_cb
1243 * @return an iterator handle to use for iteration
1245 struct GNUNET_RECLAIM_TicketIterator *
1246 GNUNET_RECLAIM_ticket_iteration_start_rp (struct GNUNET_RECLAIM_Handle *h,
1247 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1248 GNUNET_SCHEDULER_TaskCallback error_cb,
1250 GNUNET_RECLAIM_TicketCallback proc,
1252 GNUNET_SCHEDULER_TaskCallback finish_cb,
1253 void *finish_cb_cls)
1255 struct GNUNET_RECLAIM_TicketIterator *it;
1256 struct GNUNET_MQ_Envelope *env;
1257 struct TicketIterationStartMessage *msg;
1260 rid = h->r_id_gen++;
1261 it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator);
1263 it->error_cb = error_cb;
1264 it->error_cb_cls = error_cb_cls;
1265 it->finish_cb = finish_cb;
1266 it->finish_cb_cls = finish_cb_cls;
1270 GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head,
1273 env = GNUNET_MQ_msg (msg,
1274 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START);
1275 msg->id = htonl (rid);
1276 msg->identity = *identity;
1277 msg->is_audience = htonl (GNUNET_YES);
1281 GNUNET_MQ_send (h->mq,
1289 * Calls the record processor specified in #GNUNET_RECLAIM_ticket_iteration_start
1290 * for the next record.
1292 * @param it the iterator
1295 GNUNET_RECLAIM_ticket_iteration_next (struct GNUNET_RECLAIM_TicketIterator *it)
1297 struct GNUNET_RECLAIM_Handle *h = it->h;
1298 struct TicketIterationNextMessage *msg;
1299 struct GNUNET_MQ_Envelope *env;
1301 env = GNUNET_MQ_msg (msg,
1302 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_NEXT);
1303 msg->id = htonl (it->r_id);
1304 GNUNET_MQ_send (h->mq,
1310 * Stops iteration and releases the idp handle for further calls. Must
1311 * be called on any iteration that has not yet completed prior to calling
1312 * #GNUNET_RECLAIM_disconnect.
1314 * @param it the iterator
1317 GNUNET_RECLAIM_ticket_iteration_stop (struct GNUNET_RECLAIM_TicketIterator *it)
1319 struct GNUNET_RECLAIM_Handle *h = it->h;
1320 struct GNUNET_MQ_Envelope *env;
1321 struct TicketIterationStopMessage *msg;
1325 env = GNUNET_MQ_msg (msg,
1326 GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_STOP);
1327 msg->id = htonl (it->r_id);
1328 GNUNET_MQ_send (h->mq,
1335 * Revoked an issued ticket. The relying party will be unable to retrieve
1336 * updated attributes.
1338 * @param h the reclaim to use
1339 * @param identity the issuing identity
1340 * @param ticket the ticket to revoke
1341 * @param cb the callback
1342 * @param cb_cls the callback closure
1343 * @return handle to abort the operation
1345 struct GNUNET_RECLAIM_Operation *
1346 GNUNET_RECLAIM_ticket_revoke (struct GNUNET_RECLAIM_Handle *h,
1347 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
1348 const struct GNUNET_RECLAIM_Ticket *ticket,
1349 GNUNET_RECLAIM_ContinuationWithStatus cb,
1352 struct GNUNET_RECLAIM_Operation *op;
1353 struct RevokeTicketMessage *msg;
1356 rid = h->r_id_gen++;
1357 op = GNUNET_new (struct GNUNET_RECLAIM_Operation);
1362 GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
1365 op->env = GNUNET_MQ_msg_extra (msg,
1366 sizeof (struct GNUNET_RECLAIM_Ticket),
1367 GNUNET_MESSAGE_TYPE_RECLAIM_REVOKE_TICKET);
1368 msg->id = htonl (rid);
1369 msg->identity = *identity;
1370 GNUNET_memcpy (&msg[1],
1372 sizeof (struct GNUNET_RECLAIM_Ticket));
1373 if (NULL != h->mq) {
1374 GNUNET_MQ_send (h->mq,
1383 /* end of reclaim_api.c */