along with this program. If not, see <http://www.gnu.org/licenses/>.
SPDX-License-Identifier: AGPL3.0-or-later
- */
+ */
/**
* @author Martin Schanzenbach
#include <inttypes.h>
#include "gnunet-service-reclaim_tickets.h"
+
+/**
+ * FIXME: the defaul ticket iteration interval should probably
+ * be the minimim attribute expiration.
+ */
#define DEFAULT_TICKET_REFRESH_INTERVAL GNUNET_TIME_UNIT_HOURS
+/**
+ * Handle for a parallel GNS lookup job
+ * (Declaration further below)
+ */
struct ParallelLookup;
};
+/**
+ * Handle to a consume operation
+ */
struct RECLAIM_TICKETS_ConsumeHandle
{
/**
void *cb_cls;
};
+
/**
* Handle for a parallel GNS lookup job
*/
void *cb_cls;
};
+
/**
* Ticket iterator
*/
struct TicketRecordsEntry *tickets_to_update_tail;
};
+
/**
* Ticket expiration interval
*/
static struct GNUNET_TIME_Relative ticket_refresh_interval;
+
/* Namestore handle */
static struct GNUNET_NAMESTORE_Handle *nsh;
+
/* GNS handle */
static struct GNUNET_GNS_Handle *gns;
+
/* Handle to the statistics service */
static struct GNUNET_STATISTICS_Handle *stats;
-static void
-move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rh);
-static void
-move_attrs_cont (void *cls)
-{
- move_attrs ((struct RECLAIM_TICKETS_RevokeHandle *) cls);
-}
/**
* Cleanup revoke handle
{
struct RevokedAttributeEntry *ae;
struct TicketRecordsEntry *le;
+
if (NULL != rh->ns_qe)
GNUNET_NAMESTORE_cancel (rh->ns_qe);
if (NULL != rh->ns_it)
GNUNET_free (rh);
}
+
+/**
+ * For each ticket, store new, updated attribute references
+ * (Implementation further below)
+ *
+ * @param cls handle to the operation
+ */
static void
-del_attr_finished (void *cls, int32_t success, const char *emsg)
+process_tickets (void *cls);
+
+
+/**
+ * Finished storing updated attribute references.
+ * Abort on error, else continue processing tickets
+ *
+ * @param cls handle to the operation
+ * @param success result of namestore operation
+ * @param emsg (NULL on success)
+ */
+static void
+ticket_processed (void *cls, int32_t success, const char *emsg)
{
struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
+
rvk->ns_qe = NULL;
- if (GNUNET_SYSERR == success)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Error removing attribute: %s\n",
- emsg);
- rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
- cleanup_rvk (rvk);
- return;
- }
- rvk->move_attr = rvk->move_attr->next;
- GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
+ GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
}
+
+/**
+ * For each ticket, store new, updated attribute references
+ *
+ * @param cls handle to the operation
+ */
static void
-move_attr_finished (void *cls, int32_t success, const char *emsg)
+process_tickets (void *cls)
{
struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
- char *label;
- rvk->ns_qe = NULL;
- if (GNUNET_SYSERR == success)
+ struct TicketRecordsEntry *le;
+ struct RevokedAttributeEntry *ae;
+
+ if (NULL == rvk->tickets_to_update_head)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error moving attribute: %s\n", emsg);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Finished updatding tickets, success\n");
+ rvk->cb (rvk->cb_cls, GNUNET_OK);
+ cleanup_rvk (rvk);
+ return;
+ }
+ le = rvk->tickets_to_update_head;
+ GNUNET_CONTAINER_DLL_remove (rvk->tickets_to_update_head,
+ rvk->tickets_to_update_tail,
+ le);
+ struct GNUNET_GNSRECORD_Data rd[le->rd_count];
+ if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
+ le->data,
+ le->rd_count,
+ rd))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to deserialize ticket record(s)\n");
rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
cleanup_rvk (rvk);
return;
}
- label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
- sizeof (uint64_t));
- GNUNET_assert (NULL != label);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing attribute %s\n", label);
+ for (int i = 0; i < le->rd_count; i++)
+ {
+ if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
+ continue;
+ for (ae = rvk->attrs_head; NULL != ae; ae = ae->next)
+ {
+ if (0 != memcmp (rd[i].data, &ae->old_id, sizeof(uint64_t)))
+ continue;
+ rd[i].data = &ae->new_id;
+ }
+ }
rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
&rvk->identity,
- label,
- 0,
- NULL,
- &del_attr_finished,
+ le->label,
+ le->rd_count,
+ rd,
+ &ticket_processed,
rvk);
- GNUNET_free (label);
+ GNUNET_free (le->label);
+ GNUNET_free (le->data);
+ GNUNET_free (le);
}
+/**
+ * Done collecting tickets. Start processing.
+ *
+ * @param cls handle to the operation
+ */
static void
-rvk_move_attr_cb (void *cls,
- const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
- const char *label,
- unsigned int rd_count,
- const struct GNUNET_GNSRECORD_Data *rd)
+rvk_ticket_update_finished (void *cls)
{
struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
- struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
- struct GNUNET_GNSRECORD_Data new_rd;
- struct RevokedAttributeEntry *le;
- char *new_label;
- char *attr_data;
- rvk->ns_qe = NULL;
- if (0 == rd_count)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "The attribute %s no longer exists!\n",
- label);
- le = rvk->move_attr;
- rvk->move_attr = le->next;
- GNUNET_CONTAINER_DLL_remove (rvk->attrs_head, rvk->attrs_tail, le);
- GNUNET_free (le);
- GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
- return;
- }
- /** find a new place for this attribute **/
- rvk->move_attr->new_id =
- GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
- new_rd = *rd;
- claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Attribute to update: Name=%s, ID=%" PRIu64 "\n",
- claim->name,
- claim->id);
- claim->id = rvk->move_attr->new_id;
- new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
- attr_data = GNUNET_malloc (rd->data_size);
- new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
- new_rd.data = attr_data;
- new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
- sizeof (uint64_t));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
- rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
- &rvk->identity,
- new_label,
- 1,
- &new_rd,
- &move_attr_finished,
- rvk);
- GNUNET_free (new_label);
- GNUNET_free (claim);
- GNUNET_free (attr_data);
+
+ rvk->ns_it = NULL;
+ GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
}
+/**
+ * We need to update all other tickets with the new attribute IDs.
+ * We first collect them all. Processing after.
+ *
+ * @param cls handle to the operation
+ * @param zone ticket issuer private key
+ * @param label ticket rnd
+ * @param rd_cound size of record set
+ * @param rd record set
+ */
static void
rvk_ticket_update (void *cls,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
continue;
for (ae = rvk->attrs_head; NULL != ae; ae = ae->next)
{
- if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
+ if (0 != memcmp (rd[i].data, &ae->old_id, sizeof(uint64_t)))
continue;
has_changed = GNUNET_YES;
break;
}
+/**
+ * Error iterating namestore. Abort.
+ *
+ * @param cls handle to the operation
+ */
static void
-process_tickets (void *cls);
+rvk_ns_iter_err (void *cls)
+{
+ struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
+ rvk->ns_it = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Namestore error on revocation (id=%" PRIu64 "\n",
+ rvk->move_attr->old_id);
+ rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
+ cleanup_rvk (rvk);
+}
+
+/**
+ * Error storing new attribute in namestore. Abort
+ *
+ * @param cls handle to the operation
+ */
static void
-ticket_processed (void *cls, int32_t success, const char *emsg)
+rvk_ns_err (void *cls)
{
struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
+
rvk->ns_qe = NULL;
- GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Namestore error on revocation (id=%" PRIu64 "\n",
+ rvk->move_attr->old_id);
+ rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
+ cleanup_rvk (rvk);
}
+
+/**
+ * We change every attribute ID of the ticket attributes we
+ * want to revoke.
+ * When we are done, we need to update any other ticket which
+ * included references to any of the changed attributes.
+ * (Implementation further below)
+ *
+ * @param rvk handle to the operation
+ */
static void
-process_tickets (void *cls)
+move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rh);
+
+
+/**
+ * Delayed continuation for move_attrs
+ *
+ * @param cls handle to the operation.
+ */
+static void
+move_attrs_cont (void *cls)
+{
+ move_attrs ((struct RECLAIM_TICKETS_RevokeHandle *) cls);
+}
+
+
+/**
+ * Done deleting the old record. Abort on error.
+ * Else, continue updating attribute IDs.
+ *
+ * @param cls handle to the operation
+ * @param success result of the namestore operation
+ * @param emsg error message (NULL on success)
+ */
+static void
+del_attr_finished (void *cls, int32_t success, const char *emsg)
{
struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
- struct TicketRecordsEntry *le;
- struct RevokedAttributeEntry *ae;
- if (NULL == rvk->tickets_to_update_head)
+
+ rvk->ns_qe = NULL;
+ if (GNUNET_SYSERR == success)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Finished updatding tickets, success\n");
- rvk->cb (rvk->cb_cls, GNUNET_OK);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Error removing attribute: %s\n",
+ emsg);
+ rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
cleanup_rvk (rvk);
return;
}
- le = rvk->tickets_to_update_head;
- GNUNET_CONTAINER_DLL_remove (rvk->tickets_to_update_head,
- rvk->tickets_to_update_tail,
- le);
- struct GNUNET_GNSRECORD_Data rd[le->rd_count];
- if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (le->data_size,
- le->data,
- le->rd_count,
- rd))
+ rvk->move_attr = rvk->move_attr->next;
+ GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
+}
+
+
+/**
+ * Updated an attribute ID.
+ * Abort on error if namestore operation failed.
+ * Else, we have to delete the old record.
+ *
+ * @param cls handle to the operation
+ * @param success result of the store operation
+ * @param emsg error message (NULL on success)
+ */
+static void
+move_attr_finished (void *cls, int32_t success, const char *emsg)
+{
+ struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
+ char *label;
+
+ rvk->ns_qe = NULL;
+ if (GNUNET_SYSERR == success)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Unable to deserialize ticket record(s)\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error moving attribute: %s\n", emsg);
rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
cleanup_rvk (rvk);
return;
}
- for (int i = 0; i < le->rd_count; i++)
- {
- if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
- continue;
- for (ae = rvk->attrs_head; NULL != ae; ae = ae->next)
- {
- if (0 != memcmp (rd[i].data, &ae->old_id, sizeof (uint64_t)))
- continue;
- rd[i].data = &ae->new_id;
- }
- }
+ label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
+ sizeof(uint64_t));
+ GNUNET_assert (NULL != label);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing attribute %s\n", label);
rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
&rvk->identity,
- le->label,
- le->rd_count,
- rd,
- &ticket_processed,
+ label,
+ 0,
+ NULL,
+ &del_attr_finished,
rvk);
- GNUNET_free (le->label);
- GNUNET_free (le->data);
- GNUNET_free (le);
-}
-
-static void
-rvk_ticket_update_finished (void *cls)
-{
- struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
- rvk->ns_it = NULL;
- GNUNET_SCHEDULER_add_now (&process_tickets, rvk);
+ GNUNET_free (label);
}
+/**
+ * Got the referenced attribute. Updating the ID
+ *
+ * @param cls handle to the operation
+ * @param zone issuer identity
+ * @param label attribute ID
+ * @param rd_count size of record set (should be 1)
+ * @param rd record set (the attribute)
+ */
static void
-rvk_ns_iter_err (void *cls)
+rvk_move_attr_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_RevokeHandle *rvk = cls;
- rvk->ns_it = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Namestore error on revocation (id=%" PRIu64 "\n",
- rvk->move_attr->old_id);
- rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
- cleanup_rvk (rvk);
-}
-
+ struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
+ struct GNUNET_GNSRECORD_Data new_rd;
+ struct RevokedAttributeEntry *le;
+ char *new_label;
+ char *attr_data;
-static void
-rvk_ns_err (void *cls)
-{
- struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
rvk->ns_qe = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Namestore error on revocation (id=%" PRIu64 "\n",
- rvk->move_attr->old_id);
- rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
- cleanup_rvk (rvk);
+ if (0 == rd_count)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "The attribute %s no longer exists!\n",
+ label);
+ le = rvk->move_attr;
+ rvk->move_attr = le->next;
+ GNUNET_CONTAINER_DLL_remove (rvk->attrs_head, rvk->attrs_tail, le);
+ GNUNET_free (le);
+ GNUNET_SCHEDULER_add_now (&move_attrs_cont, rvk);
+ return;
+ }
+ /** find a new place for this attribute **/
+ rvk->move_attr->new_id =
+ GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
+ new_rd = *rd;
+ claim = GNUNET_RECLAIM_ATTRIBUTE_deserialize (rd->data, rd->data_size);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Attribute to update: Name=%s, ID=%" PRIu64 "\n",
+ claim->name,
+ claim->id);
+ claim->id = rvk->move_attr->new_id;
+ new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize_get_size (claim);
+ attr_data = GNUNET_malloc (rd->data_size);
+ new_rd.data_size = GNUNET_RECLAIM_ATTRIBUTE_serialize (claim, attr_data);
+ new_rd.data = attr_data;
+ new_label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->new_id,
+ sizeof(uint64_t));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute %s\n", new_label);
+ rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
+ &rvk->identity,
+ new_label,
+ 1,
+ &new_rd,
+ &move_attr_finished,
+ rvk);
+ GNUNET_free (new_label);
+ GNUNET_free (claim);
+ GNUNET_free (attr_data);
}
+/**
+ * We change every attribute ID of the ticket attributes we
+ * want to revoke.
+ * When we are done, we need to update any other ticket which
+ * included references to any of the changed attributes.
+ *
+ * @param rvk handle to the operation
+ */
static void
move_attrs (struct RECLAIM_TICKETS_RevokeHandle *rvk)
{
return;
}
label = GNUNET_STRINGS_data_to_string_alloc (&rvk->move_attr->old_id,
- sizeof (uint64_t));
+ sizeof(uint64_t));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Moving attribute %s\n", label);
rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
}
+/**
+ * Finished deleting ticket and attribute references.
+ * Abort on failure.
+ * Else, we start changing every attribute ID in the
+ * found attribute references so that access is no longer
+ * possible.
+ *
+ * @param cls handle to the operation
+ * @param success Namestore operation return value
+ * @param emsg error message (NULL on success)
+ */
static void
remove_ticket_cont (void *cls, int32_t success, const char *emsg)
{
struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
+
rvk->ns_qe = NULL;
if (GNUNET_SYSERR == success)
{
}
+/**
+ * We found the attribute references.
+ * Store them for later and remove the record set.
+ *
+ * @param cls handle to the operation
+ * @param zone the issuer key
+ * @param label ticket rnd
+ * @param rd_cound size of record set
+ * @param rd record set
+ */
static void
revoke_attrs_cb (void *cls,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
{
struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
struct RevokedAttributeEntry *le;
+
rvk->ns_qe = NULL;
+ /**
+ * Temporarily store attribute references.
+ * We need it later.
+ */
for (int i = 0; i < rd_count; i++)
{
if (GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF != rd[i].record_type)
rvk->ticket_attrs++;
}
- /** Now, remove ticket **/
+ /** Remove attribute references **/
rvk->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
&rvk->identity,
label,
}
+/**
+ * Failed to query namestore. Abort operation
+ *
+ * @param cls handle to the operation
+ */
static void
rvk_attrs_err_cb (void *cls)
{
struct RECLAIM_TICKETS_RevokeHandle *rvk = cls;
+
rvk->cb (rvk->cb_cls, GNUNET_SYSERR);
cleanup_rvk (rvk);
}
+/**
+ * Revoke a ticket.
+ * We start by looking up attribute references in order
+ * to change attribute IDs.
+ *
+ * @param ticket ticket to revoke
+ * @param identity private key of issuer
+ * @param cb revocation status callback
+ * @param cb_cls callback closure
+ * @return handle to the operation
+ */
struct RECLAIM_TICKETS_RevokeHandle *
RECLAIM_TICKETS_revoke (const struct GNUNET_RECLAIM_Ticket *ticket,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
rvk->ticket = *ticket;
GNUNET_CRYPTO_ecdsa_key_get_public (&rvk->identity, &rvk->ticket.identity);
/** Get shared attributes **/
- label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof (uint64_t));
+ label = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, sizeof(uint64_t));
GNUNET_assert (NULL != label);
rvk->ns_qe = GNUNET_NAMESTORE_records_lookup (nsh,
identity,
}
+/**
+ * Cancel a revocation.
+ *
+ * @param rh handle to the operation
+ */
void
RECLAIM_TICKETS_revoke_cancel (struct RECLAIM_TICKETS_RevokeHandle *rh)
{
+ GNUNET_assert (NULL != rh);
cleanup_rvk (rh);
}
+
+
/*******************************
- * Ticket consume
- *******************************/
+* Ticket consume
+*******************************/
/**
* Cleanup ticket consume handle
+ *
* @param cth the handle to clean up
*/
static void
cleanup_cth (struct RECLAIM_TICKETS_ConsumeHandle *cth)
{
struct ParallelLookup *lu;
+
if (NULL != cth->lookup_request)
GNUNET_GNS_lookup_cancel (cth->lookup_request);
if (NULL != cth->kill_task)
}
+/**
+ * We found an attribute record.
+ *
+ * @param cls handle to the operation
+ * @param rd_cound size of record set
+ * @param rd record set
+ */
static void
process_parallel_lookup_result (void *cls,
uint32_t rd_count,
struct ParallelLookup *parallel_lookup = cls;
struct RECLAIM_TICKETS_ConsumeHandle *cth = parallel_lookup->handle;
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *attr_le;
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Parallel lookup finished (count=%u)\n",
rd_count);
"attribute_lookup_time_total",
GNUNET_TIME_absolute_get_duration (
parallel_lookup->lookup_start_time)
- .rel_value_us,
+ .rel_value_us,
GNUNET_YES);
GNUNET_STATISTICS_update (stats, "attribute_lookups_count", 1, GNUNET_YES);
GNUNET_free (parallel_lookup);
if (1 != rd_count)
- GNUNET_break (0); // TODO
+ GNUNET_break (0); // FIXME: We should never find this.
if (rd->record_type == GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR)
{
attr_le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
cth->attrs->list_tail,
attr_le);
}
+
if (NULL != cth->parallel_lookups_head)
return; // Wait for more
- /* Else we are done */
+ /* Else we are done */
cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
cleanup_cth (cth);
}
+/**
+ * Cancel the lookups for attribute records
+ *
+ * @param cls handle to the operation
+ */
static void
abort_parallel_lookups (void *cls)
{
}
+/**
+ * GNS result with attribute references.
+ * For each result, we start a (parallel) lookup of the actual
+ * attribute record under the referenced label.
+ *
+ * @param cls handle to the operation
+ * @param rd_cound size of the record set
+ * @param rd record set
+ */
static void
lookup_authz_cb (void *cls,
uint32_t rd_count,
"reclaim_authz_lookup_time_total",
GNUNET_TIME_absolute_get_duration (
cth->lookup_start_time)
- .rel_value_us,
+ .rel_value_us,
GNUNET_YES);
GNUNET_STATISTICS_update (stats,
"reclaim_authz_lookups_count",
cth->parallel_lookups_tail,
parallel_lookup);
}
+ /**
+ * We started lookups. Add a timeout task.
+ * FIXME: Really needed here?
+ */
if (NULL != cth->parallel_lookups_head)
{
cth->kill_task = GNUNET_SCHEDULER_add_delayed (
cth);
return;
}
+ /**
+ * No references found, return empty attribute list
+ */
cth->cb (cth->cb_cls, &cth->ticket.identity, cth->attrs, GNUNET_OK, NULL);
cleanup_cth (cth);
}
+/**
+ * Consume a ticket.
+ * We first looking attribute references under the label
+ * ticket.rnd in GNS.
+ *
+ * @param id the audience of the ticket
+ * @param ticket the ticket to consume
+ * @param cb callback to call with attributes of ticket
+ * @param cb_cls callback closure
+ * @return handle to the operation
+ */
struct RECLAIM_TICKETS_ConsumeHandle *
RECLAIM_TICKETS_consume (const struct GNUNET_CRYPTO_EcdsaPrivateKey *id,
const struct GNUNET_RECLAIM_Ticket *ticket,
{
struct RECLAIM_TICKETS_ConsumeHandle *cth;
char *label;
+
cth = GNUNET_new (struct RECLAIM_TICKETS_ConsumeHandle);
cth->identity = *id;
cth->cb = cb;
cth->cb_cls = cb_cls;
label =
- GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof (uint64_t));
+ GNUNET_STRINGS_data_to_string_alloc (&cth->ticket.rnd, sizeof(uint64_t));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Looking for AuthZ info under %s\n",
label);
return cth;
}
+
+/**
+ * Cancel a consume operation
+ *
+ * @param cth the operation to cancel
+ */
void
RECLAIM_TICKETS_consume_cancel (struct RECLAIM_TICKETS_ConsumeHandle *cth)
{
/*******************************
- * Ticket issue
- *******************************/
+* Ticket issue
+*******************************/
/**
* Cleanup ticket consume handle
}
+/**
+ * Store finished, abort on error.
+ * Else, return new ticket to caller.
+ *
+ * @param cls handle to the operation
+ * @param success store operation result
+ * @param emsg error message (or NULL on success)
+ */
static void
store_ticket_issue_cont (void *cls, int32_t success, const char *emsg)
{
}
+/**
+ * Issue a new ticket.
+ * We store references to attribute record labels and the ticket itself
+ * under the label base64(ticket.rnd).
+ *
+ * @param ih handle to the operation containing relevant metadata
+ */
static void
issue_ticket (struct TicketIssueHandle *ih)
{
list_len++;
attrs_record =
- GNUNET_malloc (list_len * sizeof (struct GNUNET_GNSRECORD_Data));
+ GNUNET_malloc (list_len * sizeof(struct GNUNET_GNSRECORD_Data));
i = 0;
for (le = ih->attrs->list_head; NULL != le; le = le->next)
{
attrs_record[i].data = &le->claim->id;
- attrs_record[i].data_size = sizeof (le->claim->id);
- //FIXME: Should this be the attribute expiration time or ticket refresh intv
+ attrs_record[i].data_size = sizeof(le->claim->id);
+ /**
+ * FIXME: Should this be the attribute expiration time or ticket
+ * refresh interval? Probably min(attrs.expiration)
+ */
attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us;
attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_ATTR_REF;
attrs_record[i].flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
i++;
}
attrs_record[i].data = &ih->ticket;
- attrs_record[i].data_size = sizeof (struct GNUNET_RECLAIM_Ticket);
+ attrs_record[i].data_size = sizeof(struct GNUNET_RECLAIM_Ticket);
attrs_record[i].expiration_time = ticket_refresh_interval.rel_value_us;
attrs_record[i].record_type = GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET;
attrs_record[i].flags =
GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION | GNUNET_GNSRECORD_RF_PRIVATE;
label =
- GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof (uint64_t));
+ GNUNET_STRINGS_data_to_string_alloc (&ih->ticket.rnd, sizeof(uint64_t));
// Publish record
ih->ns_qe = GNUNET_NAMESTORE_records_store (nsh,
&ih->identity,
}
/*************************************************
- * Ticket iteration (finding a specific ticket)
- *************************************************/
+* Ticket iteration (finding a specific ticket)
+*************************************************/
+
+/**
+ * Namestore error on issue. Abort.
+ *
+ * @param cls handle to the operation
+ */
static void
filter_tickets_error_cb (void *cls)
{
struct TicketIssueHandle *tih = cls;
+
tih->ns_it = NULL;
tih->cb (tih->cb_cls,
&tih->ticket,
cleanup_issue_handle (tih);
}
+
+/**
+ * Iterator over records.
+ * Check if any previously issued ticket already
+ * matches what we need to prevent duplicates and
+ * improve resolution synergy.
+ *
+ * @param cls handle to the operation
+ * @param zone issuer identity
+ * @param label ticket rnd
+ * @param rd_count size of record set
+ * @param rd record set
+ */
static void
filter_tickets_cb (void *cls,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
// figure out the number of requested attributes
struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
unsigned int attr_cnt = 0;
+
for (le = tih->attrs->list_head; NULL != le; le = le->next)
attr_cnt++;
// cmp audience
if (0 == memcmp (&tih->ticket.audience,
&ticket->audience,
- sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
+ sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
{
tih->ticket = *ticket;
continue;
le->claim->id);
- if (0 == memcmp (rd[i].data, &le->claim->id, sizeof (uint64_t)))
+ if (0 == memcmp (rd[i].data, &le->claim->id, sizeof(uint64_t)))
found_attrs_cnt++;
}
}
- if (attr_cnt == found_attrs_cnt && NULL != ticket)
+ /**
+ * If we found a matching ticket, return that to the caller and
+ * we are done.
+ */
+ if ((attr_cnt == found_attrs_cnt)&&(NULL != ticket))
{
GNUNET_NAMESTORE_zone_iteration_stop (tih->ns_it);
tih->cb (tih->cb_cls, &tih->ticket, GNUNET_OK, NULL);
return;
}
- // ticket not found in current record
+ // ticket not found in current record, checking next record set
GNUNET_NAMESTORE_zone_iterator_next (tih->ns_it, 1);
}
+/**
+ * Done iterating over tickets and we apparently did
+ * not find an existing, matching ticket.
+ * Continue by issuing a new ticket.
+ *
+ * @param cls handle to the operation
+ */
static void
filter_tickets_finished_cb (void *cls)
{
struct TicketIssueHandle *tih = cls;
+
GNUNET_CRYPTO_ecdsa_key_get_public (&tih->identity, &tih->ticket.identity);
tih->ticket.rnd =
GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, UINT64_MAX);
issue_ticket (tih);
}
+
+/**
+ * Issue a new reclaim ticket, thereby authorizing
+ * the audience to access the set of provided attributes.
+ *
+ * @param identity the issuer
+ * @param attrs the attributes to share
+ * @param audience the audience to share the attributes with
+ * @param cb the callback to call with the ticket result
+ * @param cb_cls the callback closure
+ * FIXME: Return handle??
+ */
void
RECLAIM_TICKETS_issue (const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
const struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attrs,
void *cb_cls)
{
struct TicketIssueHandle *tih;
+
tih = GNUNET_new (struct TicketIssueHandle);
tih->cb = cb;
tih->cb_cls = cb_cls;
tih->identity = *identity;
tih->ticket.audience = *audience;
- // check whether the ticket has already been issued
+ // First check whether the ticket has already been issued
tih->ns_it =
GNUNET_NAMESTORE_zone_iteration_start (nsh,
&tih->identity,
tih);
}
+
/************************************
- * Ticket iteration
- ************************************/
+* Ticket iteration
+************************************/
+/**
+ * Cleanup ticket iterator
+ *
+ * @param iter handle to the iteration
+ */
static void
cleanup_iter (struct RECLAIM_TICKETS_Iterator *iter)
{
}
+/**
+ * Return each record of type @GNUNET_GNSRECORD_TYPE_RECLAIM_TICKET
+ * to the caller and proceed with the iteration.
+ * FIXME: Should we _not_ proceed automatically here?
+ *
+ * @param cls handle to the iteration
+ * @param zone the ticket issuer
+ * @param label the ticket rnd
+ * @param rd_count number of records in record set
+ * @param rd record set containing a ticket
+ */
static void
collect_tickets_cb (void *cls,
const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
}
+/**
+ * Signal ticket iteration has finished
+ *
+ * @param cls handle to the iteration
+ */
static void
collect_tickets_finished_cb (void *cls)
{
struct RECLAIM_TICKETS_Iterator *iter = cls;
+
iter->ns_it = NULL;
iter->cb (iter->cb_cls, NULL);
cleanup_iter (iter);
}
+/**
+ * Cancel ticket iteration on namestore error
+ *
+ * @param cls the iteration handle
+ */
static void
collect_tickets_error_cb (void *cls)
{
struct RECLAIM_TICKETS_Iterator *iter = cls;
+
iter->ns_it = NULL;
iter->cb (iter->cb_cls, NULL);
cleanup_iter (iter);
}
+/**
+ * Continue ticket iteration
+ *
+ * @param iter the iteration to continue
+ */
void
RECLAIM_TICKETS_iteration_next (struct RECLAIM_TICKETS_Iterator *iter)
{
}
+/**
+ * Stop a running ticket iteration
+ *
+ * @param iter iteration to cancel
+ */
void
RECLAIM_TICKETS_iteration_stop (struct RECLAIM_TICKETS_Iterator *iter)
{
}
+/**
+ * Iterate over all tickets issued by an identity
+ *
+ * @param identity the issuing identity
+ * @param cb ticket callback function
+ * @param cb_cls callback closure
+ * @return a handle to the iteration
+ */
struct RECLAIM_TICKETS_Iterator *
RECLAIM_TICKETS_iteration_start (
const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
}
+/**
+ * Initialize tickets component
+ *
+ * @param c the configuration
+ * @return GNUNET_SYSERR on error
+ */
int
RECLAIM_TICKETS_init (const struct GNUNET_CONFIGURATION_Handle *c)
{
return GNUNET_OK;
}
+
+/**
+ * Close handles and clean up.
+ * FIXME: cancel all pending operations (gns, ns etc)
+ */
void
RECLAIM_TICKETS_deinit (void)
{