From fd73cedc0d24fd486ecb552d8c228050b1dc3c3f Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Fri, 12 Apr 2019 16:34:16 +0200 Subject: [PATCH] RECLAIM: Towards -sql --- src/reclaim/gnunet-reclaim.c | 57 +++++- src/reclaim/gnunet-service-reclaim.c | 168 +++-------------- src/reclaim/gnunet-service-reclaim_tickets.c | 189 +++++++++++++++++++ src/reclaim/gnunet-service-reclaim_tickets.h | 31 +++ src/reclaim/reclaim.h | 10 +- src/reclaim/reclaim_api.c | 66 +------ 6 files changed, 305 insertions(+), 216 deletions(-) diff --git a/src/reclaim/gnunet-reclaim.c b/src/reclaim/gnunet-reclaim.c index df6ebc66f..c36955a04 100644 --- a/src/reclaim/gnunet-reclaim.c +++ b/src/reclaim/gnunet-reclaim.c @@ -76,6 +76,11 @@ static char* type_str; */ static char* revoke_ticket; +/** + * Ticket listing + */ +static int list_tickets; + /** * Ego name */ @@ -101,6 +106,11 @@ static struct GNUNET_RECLAIM_Operation *reclaim_op; */ static struct GNUNET_RECLAIM_AttributeIterator *attr_iterator; +/** + * Ticket iterator + */ +static struct GNUNET_RECLAIM_TicketIterator *ticket_iterator; + /** * Master ABE key */ @@ -156,6 +166,8 @@ do_cleanup(void *cls) GNUNET_RECLAIM_cancel (reclaim_op); if (NULL != attr_iterator) GNUNET_RECLAIM_get_attributes_stop (attr_iterator); + if (NULL != ticket_iterator) + GNUNET_RECLAIM_ticket_iteration_stop (ticket_iterator); if (NULL != reclaim_handle) GNUNET_RECLAIM_disconnect (reclaim_handle); if (NULL != identity_handle) @@ -223,6 +235,30 @@ process_attrs (void *cls, attr->name, value_str, attr_type, attr->version, attr->id); } +static void +ticket_iter_err (void *cls) +{ + ticket_iterator = NULL; + fprintf (stderr, + "Failed to iterate over tickets\n"); + cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); +} + +static void +ticket_iter_fin (void *cls) +{ + ticket_iterator = NULL; + cleanup_task = GNUNET_SCHEDULER_add_now (&do_cleanup, NULL); +} + +static void +ticket_iter (void *cls, + const struct GNUNET_RECLAIM_Ticket *ticket) +{ + fprintf (stdout, + "Found ticket\n"); + GNUNET_RECLAIM_ticket_iteration_next (ticket_iterator); +} static void iter_error (void *cls) @@ -396,7 +432,7 @@ iter_cb (void *cls, } static void -start_get_attributes () +start_process () { if (NULL == pkey) { @@ -406,6 +442,19 @@ start_get_attributes () return; } + if (list_tickets) + { + ticket_iterator = GNUNET_RECLAIM_ticket_iteration_start (reclaim_handle, + pkey, + &ticket_iter_err, + NULL, + &ticket_iter, + NULL, + &ticket_iter_fin, + NULL); + return; + } + if (NULL != rp) GNUNET_CRYPTO_ecdsa_public_key_from_string (rp, strlen (rp), @@ -446,7 +495,7 @@ ego_cb (void *cls, if (NULL == name) { if (GNUNET_YES == init) { init = GNUNET_NO; - start_get_attributes(); + start_process (); } return; } @@ -548,6 +597,10 @@ main(int argc, char *const argv[]) "TYPE", gettext_noop ("Type of attribute"), &type_str), + GNUNET_GETOPT_option_flag ('T', + "tickets", + gettext_noop ("List tickets of ego"), + &list_tickets), GNUNET_GETOPT_option_relative_time ('E', "expiration", "INTERVAL", diff --git a/src/reclaim/gnunet-service-reclaim.c b/src/reclaim/gnunet-service-reclaim.c index b963b0a9b..634de0dfe 100644 --- a/src/reclaim/gnunet-service-reclaim.c +++ b/src/reclaim/gnunet-service-reclaim.c @@ -134,30 +134,15 @@ struct TicketIteration */ struct IdpClient *client; - /** - * Key of the identity we are iterating over. - */ - struct GNUNET_CRYPTO_EcdsaPublicKey identity; - - /** - * Identity is audience - */ - uint32_t is_audience; - /** * The operation id fot the iteration in the response for the client */ uint32_t r_id; /** - * Offset of the iteration used to address next result of the - * iteration in the store - * - * Initialy set to 0 in handle_iteration_start - * Incremented with by every call to handle_iteration_next + * The ticket iterator */ - uint32_t offset; - + struct RECLAIM_TICKETS_Iterator *iter; }; @@ -592,6 +577,7 @@ cleanup() GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); + RECLAIM_TICKETS_deinit (); if (NULL != stats) { GNUNET_STATISTICS_destroy (stats, GNUNET_NO); @@ -1870,134 +1856,32 @@ handle_iteration_next (void *cls, GNUNET_SERVICE_client_continue (idp->client); } -/** - * Ticket iteration processor result - */ -enum ZoneIterationResult -{ - /** - * Iteration start. - */ - IT_START = 0, - - /** - * Found tickets, - * Continue to iterate with next iteration_next call - */ - IT_SUCCESS_MORE_AVAILABLE = 1, - - /** - * Iteration complete - */ - IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE = 2 -}; - - -/** - * Context for ticket iteration - */ -struct TicketIterationProcResult -{ - /** - * The ticket iteration handle - */ - struct TicketIteration *ti; - - /** - * Iteration result: iteration done? - * #IT_SUCCESS_MORE_AVAILABLE: if there may be more results overall but - * we got one for now and have sent it to the client - * #IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE: if there are no further results, - * #IT_START: if we are still trying to find a result. - */ - int res_iteration_finished; - -}; - static void -cleanup_ticket_iter_handle (struct TicketIteration *ti) +ticket_iter_cb (void *cls, + struct GNUNET_RECLAIM_Ticket *ticket) { - GNUNET_free (ti); -} - -/** - * Process ticket from database - * - * @param cls struct TicketIterationProcResult - * @param ticket the ticket - * @param attrs the attributes - */ -static void -ticket_iterate_proc (void *cls, - const struct GNUNET_RECLAIM_Ticket *ticket, - const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs) -{ - struct TicketIterationProcResult *proc = cls; - - if (NULL == ticket) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Iteration done\n"); - proc->res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE; - return; - } - proc->res_iteration_finished = IT_SUCCESS_MORE_AVAILABLE; - send_ticket_result (proc->ti->client, - proc->ti->r_id, - ticket, - GNUNET_OK); - -} - -/** - * Perform ticket iteration step - * - * @param ti ticket iterator to process - */ -static void -run_ticket_iteration_round (struct TicketIteration *ti) -{ - struct TicketIterationProcResult proc; + struct TicketIteration *ti = cls; struct GNUNET_MQ_Envelope *env; struct TicketResultMessage *trm; - int ret; - memset (&proc, 0, sizeof (proc)); - proc.ti = ti; - proc.res_iteration_finished = IT_START; - while (IT_START == proc.res_iteration_finished) - { - if (GNUNET_SYSERR == - (ret = TKT_database->iterate_tickets (TKT_database->cls, - &ti->identity, - ti->is_audience, - ti->offset, - &ticket_iterate_proc, - &proc))) - { - GNUNET_break (0); - break; - } - if (GNUNET_NO == ret) - proc.res_iteration_finished = IT_SUCCESS_NOT_MORE_RESULTS_AVAILABLE; - ti->offset++; - } - if (IT_SUCCESS_MORE_AVAILABLE == proc.res_iteration_finished) + if (NULL == ticket) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "More results available\n"); - return; /* more later */ + /* send empty response to indicate end of list */ + env = GNUNET_MQ_msg (trm, + GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); + GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head, + ti->client->ticket_iter_tail, + ti); + } else { + env = GNUNET_MQ_msg_extra (trm, + sizeof (struct GNUNET_RECLAIM_Ticket), + GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); } - /* send empty response to indicate end of list */ - env = GNUNET_MQ_msg (trm, - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_RESULT); trm->id = htonl (ti->r_id); GNUNET_MQ_send (ti->client->mq, env); - GNUNET_CONTAINER_DLL_remove (ti->client->ticket_iter_head, - ti->client->ticket_iter_tail, - ti); - cleanup_ticket_iter_handle (ti); + if (NULL == ticket) + GNUNET_free (ti); } static void @@ -2011,15 +1895,14 @@ handle_ticket_iteration_start (void *cls, "Received TICKET_ITERATION_START message\n"); ti = GNUNET_new (struct TicketIteration); ti->r_id = ntohl (tis_msg->id); - ti->offset = 0; ti->client = client; - ti->identity = tis_msg->identity; - ti->is_audience = ntohl (tis_msg->is_audience); GNUNET_CONTAINER_DLL_insert (client->ticket_iter_head, client->ticket_iter_tail, ti); - run_ticket_iteration_round (ti); + ti->iter = RECLAIM_TICKETS_iteration_start (&tis_msg->identity, + &ticket_iter_cb, + ti); GNUNET_SERVICE_client_continue (client->client); } @@ -2045,10 +1928,11 @@ handle_ticket_iteration_stop (void *cls, GNUNET_SERVICE_client_drop (client->client); return; } + RECLAIM_TICKETS_iteration_stop (ti->iter); GNUNET_CONTAINER_DLL_remove (client->ticket_iter_head, client->ticket_iter_tail, ti); - cleanup_ticket_iter_handle (ti); + GNUNET_free (ti); GNUNET_SERVICE_client_continue (client->client); } @@ -2073,7 +1957,7 @@ handle_ticket_iteration_next (void *cls, GNUNET_SERVICE_client_drop (client->client); return; } - run_ticket_iteration_round (ti); + RECLAIM_TICKETS_iteration_next (ti->iter); GNUNET_SERVICE_client_continue (client->client); } @@ -2226,7 +2110,7 @@ client_disconnect_cb (void *cls, GNUNET_CONTAINER_DLL_remove (idp->ticket_iter_head, idp->ticket_iter_tail, ti); - cleanup_ticket_iter_handle (ti); + GNUNET_free (ti); } GNUNET_free (idp); } diff --git a/src/reclaim/gnunet-service-reclaim_tickets.c b/src/reclaim/gnunet-service-reclaim_tickets.c index f93e934ee..033684f71 100644 --- a/src/reclaim/gnunet-service-reclaim_tickets.c +++ b/src/reclaim/gnunet-service-reclaim_tickets.c @@ -105,6 +105,47 @@ struct TicketIssueHandle }; +/** + * Ticket iterator + */ +struct RECLAIM_TICKETS_Iterator +{ + /** + * Issuer Key + */ + struct GNUNET_CRYPTO_EcdsaPrivateKey identity; + + /** + * Issuer pubkey + */ + struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub; + + /** + * Namestore queue entry + */ + struct GNUNET_NAMESTORE_QueueEntry *ns_qe; + + /** + * Iter callback + */ + RECLAIM_TICKETS_TicketIter cb; + + /** + * Iter cls + */ + void *cb_cls; + + /** + * Ticket reference list + */ + struct TicketReference *tickets_head; + + /** + * Ticket reference list + */ + struct TicketReference *tickets_tail; +}; + static struct GNUNET_NAMESTORE_Handle *nsh; /** @@ -440,6 +481,146 @@ RECLAIM_TICKETS_issue_ticket (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identi } +static void +cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter) +{ + struct TicketReference *tr; + struct TicketReference *tr_tmp; + if (NULL != iter->ns_qe) + GNUNET_NAMESTORE_cancel (iter->ns_qe); + for (tr = iter->tickets_head; NULL != tr;) + { + if (NULL != tr->attrs) + GNUNET_RECLAIM_ATTRIBUTE_list_destroy (tr->attrs); + tr_tmp = tr; + tr = tr->next; + GNUNET_free (tr_tmp); + } + GNUNET_free (iter); +} + +static void +do_cleanup_iter (void* cls) +{ + struct RECLAIM_TICKETS_Iterator *iter = cls; + cleanup_iter (iter); +} + +/** + * Perform ticket iteration step + * + * @param ti ticket iterator to process + */ +static void +run_ticket_iteration_round (struct RECLAIM_TICKETS_Iterator *iter) +{ + struct TicketReference *tr; + if (NULL == iter->tickets_head) + { + //No more tickets + iter->cb (iter->cb_cls, + NULL); + GNUNET_SCHEDULER_add_now (&do_cleanup_iter, iter); + return; + } + tr = iter->tickets_head; + GNUNET_CONTAINER_DLL_remove (iter->tickets_head, + iter->tickets_tail, + tr); + iter->cb (iter->cb_cls, + &tr->ticket); + if (NULL != tr->attrs) + GNUNET_RECLAIM_ATTRIBUTE_list_destroy (tr->attrs); + GNUNET_free (tr); +} + +static void +collect_tickets_cb (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const char *label, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd) +{ + struct RECLAIM_TICKETS_Iterator *iter = cls; + struct TicketReference *tr; + size_t attr_data_len; + const char* attr_data; + iter->ns_qe = NULL; + + for (int i = 0; i < rd_count; i++) + { + if (GNUNET_GNSRECORD_TYPE_RECLAIM_TICKETREF != rd[i].record_type) + continue; + tr = GNUNET_new (struct TicketReference); + memcpy (&tr->ticket, rd[i].data, + sizeof (struct GNUNET_RECLAIM_Ticket)); + if (0 != memcmp (&tr->ticket.identity, + &iter->identity_pub, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) + { + //Not our ticket + GNUNET_free (tr); + continue; + } + attr_data = rd[i].data + sizeof (struct GNUNET_RECLAIM_Ticket); + attr_data_len = rd[i].data_size - sizeof (struct GNUNET_RECLAIM_Ticket); + tr->attrs = GNUNET_RECLAIM_ATTRIBUTE_list_deserialize (attr_data, + attr_data_len); + GNUNET_CONTAINER_DLL_insert (iter->tickets_head, + iter->tickets_tail, + tr); + } + run_ticket_iteration_round (iter); +} + +static void +collect_tickets_error_cb (void *cls) +{ + struct RECLAIM_TICKETS_Iterator *iter = cls; + iter->ns_qe = NULL; + iter->cb (iter->cb_cls, + NULL); + cleanup_iter (iter); +} + +void +RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter) +{ + run_ticket_iteration_round (iter); +} + +void +RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter) +{ + cleanup_iter (iter); +} + +struct RECLAIM_TICKETS_Iterator* +RECLAIM_TICKETS_iteration_start (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + RECLAIM_TICKETS_TicketIter cb, + void* cb_cls) +{ + struct RECLAIM_TICKETS_Iterator *iter; + + iter = GNUNET_new (struct RECLAIM_TICKETS_Iterator); + iter->identity = *identity; + GNUNET_CRYPTO_ecdsa_key_get_public (identity, + &iter->identity_pub); + iter->cb = cb; + iter->cb_cls = cb_cls; + iter->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh, + identity, + GNUNET_GNS_EMPTY_LABEL_AT, + &collect_tickets_error_cb, + iter, + &collect_tickets_cb, + iter); + return iter; +} + + + + int RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c) { @@ -453,3 +634,11 @@ RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c) } return GNUNET_OK; } + +void +RECLAIM_TICKETS_deinit (void) +{ + if (NULL != nsh) + GNUNET_NAMESTORE_disconnect (nsh); + nsh = NULL; +} diff --git a/src/reclaim/gnunet-service-reclaim_tickets.h b/src/reclaim/gnunet-service-reclaim_tickets.h index 7ad86dba5..81455fe53 100644 --- a/src/reclaim/gnunet-service-reclaim_tickets.h +++ b/src/reclaim/gnunet-service-reclaim_tickets.h @@ -30,6 +30,19 @@ #include "gnunet_signatures.h" #include "reclaim.h" +struct RECLAIM_TICKETS_Iterator; + +/** + * Continuation called with ticket. + * + * @param cls closure + * @param ticket the ticket + */ +typedef void +(*RECLAIM_TICKETS_TicketIter) (void *cls, + struct GNUNET_RECLAIM_Ticket *ticket); + + /** * Continuation called with ticket. * @@ -59,5 +72,23 @@ RECLAIM_TICKETS_issue_ticket (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identi RECLAIM_TICKETS_TicketResult cb, void* cb_cls); +void +RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter); + + +void +RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter); + + +struct RECLAIM_TICKETS_Iterator* +RECLAIM_TICKETS_iteration_start (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity, + RECLAIM_TICKETS_TicketIter cb, + void* cb_cls); + + int RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c); + +void +RECLAIM_TICKETS_deinit (void); + diff --git a/src/reclaim/reclaim.h b/src/reclaim/reclaim.h index 38f32426a..cff12c6e4 100644 --- a/src/reclaim/reclaim.h +++ b/src/reclaim/reclaim.h @@ -11,7 +11,7 @@ WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. - + You should have received a copy of the GNU Affero General Public License along with this program. If not, see . @@ -76,7 +76,7 @@ struct AttributeStoreResultMessage * Message header */ struct GNUNET_MessageHeader header; - + /** * Unique identifier for this request (for key collisions). */ @@ -201,12 +201,8 @@ struct TicketIterationStartMessage /** * Identity. */ - struct GNUNET_CRYPTO_EcdsaPublicKey identity; + struct GNUNET_CRYPTO_EcdsaPrivateKey identity; - /** - * Identity is audience or issuer - */ - uint32_t is_audience GNUNET_PACKED; }; diff --git a/src/reclaim/reclaim_api.c b/src/reclaim/reclaim_api.c index c8fde121b..dd6a249b5 100644 --- a/src/reclaim/reclaim_api.c +++ b/src/reclaim/reclaim_api.c @@ -1190,69 +1190,6 @@ GNUNET_RECLAIM_ticket_iteration_start (struct GNUNET_RECLAIM_Handle *h, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls) -{ - struct GNUNET_RECLAIM_TicketIterator *it; - struct GNUNET_CRYPTO_EcdsaPublicKey identity_pub; - struct GNUNET_MQ_Envelope *env; - struct TicketIterationStartMessage *msg; - uint32_t rid; - - GNUNET_CRYPTO_ecdsa_key_get_public (identity, - &identity_pub); - rid = h->r_id_gen++; - it = GNUNET_new (struct GNUNET_RECLAIM_TicketIterator); - it->h = h; - it->error_cb = error_cb; - it->error_cb_cls = error_cb_cls; - it->finish_cb = finish_cb; - it->finish_cb_cls = finish_cb_cls; - it->tr_cb = proc; - it->cls = proc_cls; - it->r_id = rid; - GNUNET_CONTAINER_DLL_insert_tail (h->ticket_it_head, - h->ticket_it_tail, - it); - env = GNUNET_MQ_msg (msg, - GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START); - msg->id = htonl (rid); - msg->identity = identity_pub; - msg->is_audience = htonl (GNUNET_NO); - if (NULL == h->mq) - it->env = env; - else - GNUNET_MQ_send (h->mq, - env); - return it; - -} - - -/** - * Lists all tickets that have been issued to remote - * identites (relying parties) - * - * @param h the reclaim to use - * @param identity the issuing identity - * @param error_cb function to call on error (i.e. disconnect), - * the handle is afterwards invalid - * @param error_cb_cls closure for @a error_cb - * @param proc function to call on each ticket; it - * will be called repeatedly with a value (if available) - * @param proc_cls closure for @a proc - * @param finish_cb function to call on completion - * the handle is afterwards invalid - * @param finish_cb_cls closure for @a finish_cb - * @return an iterator handle to use for iteration - */ -struct GNUNET_RECLAIM_TicketIterator * -GNUNET_RECLAIM_ticket_iteration_start_rp (struct GNUNET_RECLAIM_Handle *h, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, - GNUNET_SCHEDULER_TaskCallback error_cb, - void *error_cb_cls, - GNUNET_RECLAIM_TicketCallback proc, - void *proc_cls, - GNUNET_SCHEDULER_TaskCallback finish_cb, - void *finish_cb_cls) { struct GNUNET_RECLAIM_TicketIterator *it; struct GNUNET_MQ_Envelope *env; @@ -1276,7 +1213,6 @@ GNUNET_RECLAIM_ticket_iteration_start_rp (struct GNUNET_RECLAIM_Handle *h, GNUNET_MESSAGE_TYPE_RECLAIM_TICKET_ITERATION_START); msg->id = htonl (rid); msg->identity = *identity; - msg->is_audience = htonl (GNUNET_YES); if (NULL == h->mq) it->env = env; else @@ -1284,9 +1220,9 @@ GNUNET_RECLAIM_ticket_iteration_start_rp (struct GNUNET_RECLAIM_Handle *h, env); return it; - } + /** * Calls the record processor specified in #GNUNET_RECLAIM_ticket_iteration_start * for the next record. -- 2.25.1