gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r36676 - gnunet/src/identity-token


From: gnunet
Subject: [GNUnet-SVN] r36676 - gnunet/src/identity-token
Date: Fri, 20 Nov 2015 14:59:10 +0100

Author: schanzen
Date: 2015-11-20 14:59:10 +0100 (Fri, 20 Nov 2015)
New Revision: 36676

Modified:
   gnunet/src/identity-token/gnunet-service-identity-token.c
Log:
- update; add attribute updates

Modified: gnunet/src/identity-token/gnunet-service-identity-token.c
===================================================================
--- gnunet/src/identity-token/gnunet-service-identity-token.c   2015-11-19 
15:41:32 UTC (rev 36675)
+++ gnunet/src/identity-token/gnunet-service-identity-token.c   2015-11-20 
13:59:10 UTC (rev 36676)
@@ -31,41 +31,113 @@
 #include <jansson.h>
 #include "gnunet_signatures.h"
 
+/**
+ * First pass state
+ */
 #define STATE_INIT 0
 
+/**
+ * Normal operation state
+ */
 #define STATE_POST_INIT 1
 
+/**
+ * Minimum interval between updates
+ */
 #define MIN_WAIT_TIME GNUNET_TIME_UNIT_MINUTES
 
+/**
+ * Service state (to detect initial update pass)
+ */
 static int state;
 
+/**
+ * Head of ego entry DLL
+ */
 static struct EgoEntry *ego_head;
 
+/**
+ * Tail of ego entry DLL
+ */
 static struct EgoEntry *ego_tail;
 
+/**
+ * Identity handle
+ */
 static struct GNUNET_IDENTITY_Handle *identity_handle;
 
+/**
+ * Namestore handle
+ */
 static struct GNUNET_NAMESTORE_Handle *ns_handle;
 
+/**
+ * Namestore qe
+ */
 static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
 
+/**
+ * Namestore iterator
+ */
 static struct GNUNET_NAMESTORE_ZoneIterator *ns_it;
 
+/**
+ * Timeout task
+ */
 static struct GNUNET_SCHEDULER_Task * timeout_task;
 
+
+/**
+ * Update task
+ */
 static struct GNUNET_SCHEDULER_Task * update_task;
 
+/**
+ * Timeout for next update pass
+ */
 static struct GNUNET_TIME_Relative min_rel_exp;
 
+
+/**
+ * Currently processed token
+ */
 static char* token;
 
+/**
+ * Label for currently processed token
+ */
 static char* label;
 
+/**
+ * DLL for ego handles to egos containing the ID_ATTRS in a map in json_t 
format
+ *
+ */
 struct EgoEntry
 {
+  /**
+   * DLL
+   */
   struct EgoEntry *next;
+
+  /**
+   * DLL
+   */
   struct EgoEntry *prev;
+
+  /**
+   * Ego handle
+   */
   struct GNUNET_IDENTITY_Ego *ego;
+
+  /**
+   * Attribute map. Contains the attributes as json_t
+   */
+  struct GNUNET_CONTAINER_MultiHashMap *attr_map;
+
+  /**
+   * Attributes are old and should be updated if GNUNET_YES
+   */
+  int attributes_dirty;
 };
 
 /**
@@ -73,6 +145,14 @@
  */
 static const struct GNUNET_CONFIGURATION_Handle *cfg;
 
+
+/**
+ * Continuation for token store call
+ *
+ * @param cls NULL
+ * @param success error code
+ * @param emsg error message
+ */
 static void
 store_token_cont (void *cls,
                   int32_t success,
@@ -86,10 +166,17 @@
                 emsg);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, ">>> Next token\n");
   GNUNET_NAMESTORE_zone_iterator_next (ns_it);
 }
 
+
+/**
+ * This function updates the old token with new attributes,
+ * removes deleted attributes and expiration times.
+ *
+ * @param cls the ego entry
+ * @param tc task context
+ */
 static void
 handle_token_update (void *cls,
                      const struct GNUNET_SCHEDULER_TaskContext *tc)
@@ -108,6 +195,7 @@
   struct GNUNET_GNSRECORD_Data token_record;
   struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
   struct GNUNET_CRYPTO_EcdsaSignature sig;
+  struct GNUNET_HashCode key_hash;
   struct GNUNET_TIME_Relative token_rel_exp;
   struct GNUNET_TIME_Relative token_ttl;
   struct GNUNET_TIME_Absolute token_exp;
@@ -117,6 +205,7 @@
   struct GNUNET_TIME_Absolute new_nbf;
   json_t *payload_json;
   json_t *value;
+  json_t *cur_value;
   json_t *new_payload_json;
   json_t *token_nbf_json;
   json_t *token_exp_json;
@@ -141,8 +230,6 @@
                                 strlen (token_payload),
                                 &token_payload_json);
 
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Payload: %s\n",
-              token_payload_json);
   payload_json = json_loads (token_payload_json, JSON_DECODE_ANY, &json_err);
   GNUNET_free (token_payload_json);
 
@@ -168,7 +255,7 @@
     GNUNET_NAMESTORE_zone_iterator_next (ns_it);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Token is expired. Create a new one\n");
   new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp);
   new_nbf = GNUNET_TIME_absolute_get ();
@@ -187,9 +274,26 @@
     {
       json_object_set_new (new_payload_json, key, json_integer 
(new_iat.abs_value_us));
     }
-    else {
+    else if ((0 == strcmp (key, "iss"))
+             || (0 == strcmp (key, "aud"))
+             || (0 == strcmp (key, "sub"))
+             || (0 == strcmp (key, "rnl")))
+    {
       json_object_set (new_payload_json, key, value);
     }
+    else {
+      GNUNET_CRYPTO_hash (key,
+                          strlen (key),
+                          &key_hash);
+      //Check if attr still exists. omit of not
+      if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains 
(ego_entry->attr_map,
+                                                               &key_hash))
+      {
+        cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map,
+                                                       &key_hash);
+        json_object_set (new_payload_json, key, cur_value);
+      }
+    }
   }
 
   // reassemble and set
@@ -238,7 +342,7 @@
                                           &token_record,
                                           &store_token_cont,
                                           ego_entry);
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, ">>> Updating Token w/ %s\n", 
new_token);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", 
new_token);
   GNUNET_free (new_token);
   GNUNET_free (token);
   token = NULL;
@@ -250,6 +354,39 @@
 update_identities(void *cls,
                   const struct GNUNET_SCHEDULER_TaskContext *tc);
 
+/**
+ *
+ * Cleanup attr_map
+ *
+ * @param cls NULL
+ * @param key the key
+ * @param value the json_t attribute value
+ * @return GNUNET_YES
+ */
+static int
+clear_ego_attrs (void *cls,
+                 const struct GNUNET_HashCode *key,
+                 void *value)
+{
+  json_t *attr_value = value;
+
+  json_decref (attr_value);
+
+  return GNUNET_YES;
+}
+
+
+/**
+ *
+ * Update all ID_TOKEN records for an identity and store them
+ *
+ * @param cls the identity entry
+ * @param zone the identity
+ * @param lbl the name of the record
+ * @param rd_count number of records
+ * @param rd record data
+ *
+ */
 static void
 token_collect (void *cls,
                const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
@@ -262,14 +399,17 @@
   if (NULL == lbl)
   {
     //Done
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 ">>> Updating Ego finished\n");
+    //Clear attribute map for ego
+    GNUNET_CONTAINER_multihashmap_iterate (ego_entry->attr_map,
+                                           &clear_ego_attrs,
+                                           ego_entry);
+    GNUNET_CONTAINER_multihashmap_clear (ego_entry->attr_map);
     GNUNET_SCHEDULER_add_now (&update_identities, ego_entry->next);
     return;
   }
 
-  //TODO autopurge expired tokens here if set in config
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, ">>> Found record\n");
   //There should be only a single record for a token under a label
   if ((1 != rd_count)
       || (rd->record_type != GNUNET_GNSRECORD_TYPE_ID_TOKEN)
@@ -282,13 +422,102 @@
                                             rd->data,
                                             rd->data_size);
   label = GNUNET_strdup (lbl); 
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got token: %s\n", token);
 
   GNUNET_SCHEDULER_add_now (&handle_token_update, ego_entry);
 }
 
 
+/**
+ *
+ * Collect all ID_ATTR records for an identity and store them
+ *
+ * @param cls the identity entry
+ * @param zone the identity
+ * @param lbl the name of the record
+ * @param rd_count number of records
+ * @param rd record data
+ *
+ */
+static void
+attribute_collect (void *cls,
+                   const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+                   const char *lbl,
+                   unsigned int rd_count,
+                   const struct GNUNET_GNSRECORD_Data *rd)
+{
+  struct EgoEntry *ego_entry = cls;
+  json_t *attr_value;
+  struct GNUNET_HashCode key;
+  char* attr;
+  int i;
 
+  if (NULL == lbl)
+  {
+    //Done
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                ">>> Updating Attributes finished\n");
+    ego_entry->attributes_dirty = GNUNET_NO;
+    GNUNET_SCHEDULER_add_now (&update_identities, ego_entry);
+    return;
+  }
+
+  if (0 == rd_count)
+  {
+    GNUNET_NAMESTORE_zone_iterator_next (ns_it);
+    return;
+  }
+  GNUNET_CRYPTO_hash (lbl,
+                      strlen (lbl),
+                      &key);
+  if (1 == rd_count)
+  {
+    if (rd->record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
+    {
+      attr = GNUNET_GNSRECORD_value_to_string (rd->record_type,
+                                               rd->data,
+                                               rd->data_size);
+      attr_value = json_string (attr);
+      GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map,
+                                         &key,
+                                         attr_value,
+                                         
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+      GNUNET_free (attr);
+    }
+
+    GNUNET_NAMESTORE_zone_iterator_next (ns_it);
+    return;
+  }
+
+  attr_value = json_array();
+  for (i = 0; i < rd_count; i++)
+  {
+    if (rd[i].record_type == GNUNET_GNSRECORD_TYPE_ID_ATTR)
+    {
+      attr = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
+                                               rd[i].data,
+                                               rd[i].data_size);
+      json_array_append_new (attr_value, json_string (attr));
+      GNUNET_free (attr);
+    }
+
+  }
+  GNUNET_CONTAINER_multihashmap_put (ego_entry->attr_map,
+                                     &key,
+                                     attr_value,
+                                     
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+  GNUNET_NAMESTORE_zone_iterator_next (ns_it);
+  return;
+}
+
+/**
+ *
+ * Update identity information for ego. If attribute map is
+ * dirty, first update the attributes.
+ *
+ * @param cls the ego to update
+ * param tc task context
+ *
+ */
 static void
 update_identities(void *cls,
                   const struct GNUNET_SCHEDULER_TaskContext *tc)
@@ -299,33 +528,59 @@
   {
     if (min_rel_exp.rel_value_us < MIN_WAIT_TIME.rel_value_us)
       min_rel_exp = MIN_WAIT_TIME;
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, ">>> Finished. Rescheduling in %d\n", 
min_rel_exp.rel_value_us);
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                ">>> Finished. Rescheduling in %d\n",
+                min_rel_exp.rel_value_us);
     ns_it = NULL;
     //finished -> TODO reschedule
     update_task = GNUNET_SCHEDULER_add_delayed (min_rel_exp,
-                                  &update_identities,
-                                  ego_head);
+                                                &update_identities,
+                                                ego_head);
+    min_rel_exp.rel_value_us = 0;
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, ">>> Updating Ego\n");
   priv_key = GNUNET_IDENTITY_ego_get_private_key (next_ego->ego);
-  ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
-                                                 priv_key,
-                                                 &token_collect,
-                                                 next_ego);
+  if (GNUNET_YES == next_ego->attributes_dirty)
+  {
+    //Starting over. We must update the Attributes for they might have changed.
+    ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
+                                                   priv_key,
+                                                   &attribute_collect,
+                                                   next_ego);
+
+  }
+  else
+  {
+    //Ego will be dirty next time
+    next_ego->attributes_dirty = GNUNET_YES;
+    ns_it = GNUNET_NAMESTORE_zone_iteration_start (ns_handle,
+                                                   priv_key,
+                                                   &token_collect,
+                                                   next_ego);
+  }
 }
 
 
-/* ************************* Global helpers ********************* */
 
+/**
+ * Function called initially to start update task
+ */
 static void
 init_cont ()
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, ">>> Starting Service\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, ">>> Starting Service\n");
   //Initially iterate all itenties and refresh all tokens
   update_task = GNUNET_SCHEDULER_add_now (&update_identities, ego_head);
 }
 
+/**
+ * Initial ego collection function.
+ *
+ * @param cls NULL
+ * @param ego ego
+ * @param ctx context
+ * @param identifier ego name
+ */
 static void
 list_ego (void *cls,
           struct GNUNET_IDENTITY_Ego *ego,
@@ -342,10 +597,16 @@
   if (STATE_INIT == state) {
     new_entry = GNUNET_malloc (sizeof (struct EgoEntry));
     new_entry->ego = ego;
+    new_entry->attr_map = GNUNET_CONTAINER_multihashmap_create (5,
+                                                                GNUNET_NO);
+    new_entry->attributes_dirty = GNUNET_YES;
     GNUNET_CONTAINER_DLL_insert_tail(ego_head, ego_tail, new_entry);
   }
 }
 
+/**
+ * Cleanup task
+ */
 static void
 cleanup()
 {
@@ -375,11 +636,25 @@
        NULL != ego_entry;)
   {
     ego_tmp = ego_entry;
+    if (0 != GNUNET_CONTAINER_multihashmap_size (ego_tmp->attr_map))
+    {
+      GNUNET_CONTAINER_multihashmap_iterate (ego_tmp->attr_map,
+                                             &clear_ego_attrs,
+                                             ego_tmp);
+
+    }
+    GNUNET_CONTAINER_multihashmap_destroy (ego_tmp->attr_map);
     ego_entry = ego_entry->next;
     GNUNET_free (ego_tmp);
   }
 }
 
+/**
+ * Shutdown task
+ *
+ * @param cls NULL
+ * @param tc task context
+ */
 static void
 do_shutdown (void *cls,
              const struct GNUNET_SCHEDULER_TaskContext *tc)
@@ -410,7 +685,7 @@
   ns_handle = GNUNET_NAMESTORE_connect (cfg);
   if (NULL == ns_handle)
   {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connectin to 
namestore");
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "error connecting to 
namestore");
   }
 
   identity_handle = GNUNET_IDENTITY_connect (cfg,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]