Merge remote-tracking branch 'origin/master' into identity_abe
[oweals/gnunet.git] / src / credential / gnunet-service-credential.c
index 4841370b350931118a5d9fecb4be724b504d0629..be75e485ec375f65b2e573615e93fe7f1f9ad95c 100644 (file)
@@ -92,7 +92,11 @@ struct CredentialRecordEntry
    * DLL
    */
   struct CredentialRecordEntry *prev;
-
+  
+  /**
+   * Number of references in delegation chains
+   */
+  uint32_t refcount;
 
   /**
    * Payload
@@ -485,6 +489,7 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
   struct GNUNET_CREDENTIAL_Delegation dd[vrh->delegation_chain_size];
   struct GNUNET_CREDENTIAL_Credential cred[vrh->cred_chain_size];
   struct CredentialRecordEntry *cd;
+  struct CredentialRecordEntry *tmp;
   size_t size;
   int i;
 
@@ -507,6 +512,26 @@ send_lookup_response (struct VerifyRequestHandle *vrh)
     dce = dce->next;
   }
 
+  /**
+   * Remove all credentials not needed
+   */
+  for (cd = vrh->cred_chain_head; NULL != cd;)
+  {
+    if (cd->refcount > 0)
+    {
+      cd = cd->next;
+      continue;
+    }
+    tmp = cd;
+    cd = cd->next;
+    GNUNET_CONTAINER_DLL_remove (vrh->cred_chain_head,
+                                 vrh->cred_chain_tail,
+                                 tmp);
+    GNUNET_free (tmp->credential);
+    GNUNET_free (tmp);
+    vrh->cred_chain_size--;
+  }
+
   /**
    * Get serialized record data
    * Append at the end of rmsg
@@ -681,7 +706,7 @@ backward_resolution (void* cls,
 
         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                     "Found issuer\n");
-
+        cred_pointer->refcount++;
         //Backtrack
         for (tmp_set = ds_entry;
              NULL != tmp_set->parent_queue_entry;
@@ -747,7 +772,6 @@ backward_resolution (void* cls,
                                                     ds_entry->issuer_key, //issuer_key,
                                                     GNUNET_GNSRECORD_TYPE_ATTRIBUTE,
                                                     GNUNET_GNS_LO_DEFAULT,
-                                                    NULL, //shorten_key, always NULL
                                                     &backward_resolution,
                                                     ds_entry);
       GNUNET_free (lookup_attribute);
@@ -796,6 +820,7 @@ delegation_chain_resolution_start (void* cls)
       continue;
     if (0 != strcmp (cr_entry->credential->issuer_attribute, vrh->issuer_attribute))
       continue;
+    cr_entry->refcount++;
     //Found match prematurely
     send_lookup_response (vrh);
     return;
@@ -829,7 +854,6 @@ delegation_chain_resolution_start (void* cls)
                                                 &vrh->issuer_key, //issuer_key,
                                                 GNUNET_GNSRECORD_TYPE_ATTRIBUTE,
                                                 GNUNET_GNS_LO_DEFAULT,
-                                                NULL, //shorten_key, always NULL
                                                 &backward_resolution,
                                                 ds_entry);
 }
@@ -880,19 +904,22 @@ static void
 handle_verify (void *cls,
                const struct VerifyMessage *v_msg) 
 {
-  char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
-  char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
   struct VerifyRequestHandle *vrh;
   struct GNUNET_SERVICE_Client *client = cls;
+  struct CredentialRecordEntry *cr_entry;
+  uint32_t credentials_count;
+  uint32_t credential_data_size;
+  int i;
+  char attr[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
+  char issuer_attribute[GNUNET_CREDENTIAL_MAX_LENGTH + 1];
   char *attrptr = attr;
+  char *credential_data;
   const char *utf_in;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Received VERIFY message\n");
-
   utf_in = (const char *) &v_msg[1];
   GNUNET_STRINGS_utf8_tolower (utf_in, attrptr);
-
   GNUNET_memcpy (issuer_attribute, attr, ntohs (v_msg->issuer_attribute_len));
   issuer_attribute[ntohs (v_msg->issuer_attribute_len)] = '\0';
   vrh = GNUNET_new (struct VerifyRequestHandle);
@@ -913,15 +940,13 @@ handle_verify (void *cls,
    * First, collect credentials
    * TODO: cleanup!
    */
-  uint32_t credentials_count = ntohl(v_msg->c_count);
-  int i;
-  uint32_t credential_data_size = ntohs (v_msg->header.size) 
+  credentials_count = ntohl(v_msg->c_count);
+  credential_data_size = ntohs (v_msg->header.size) 
     - sizeof (struct VerifyMessage)
     - ntohs (v_msg->issuer_attribute_len)
     - 1;
   struct GNUNET_CREDENTIAL_Credential credentials[credentials_count];
-  char *credential_data = (char*)&v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1;
-  struct CredentialRecordEntry *cr_entry;
+  credential_data = (char*)&v_msg[1] + ntohs (v_msg->issuer_attribute_len) + 1;
   if (GNUNET_OK != GNUNET_CREDENTIAL_credentials_deserialize (credential_data_size,
                                                               credential_data,
                                                               credentials_count,
@@ -936,13 +961,13 @@ handle_verify (void *cls,
   for (i=0;i<credentials_count;i++) {
     cr_entry = GNUNET_new (struct CredentialRecordEntry);
     cr_entry->credential = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_Credential) +
-                                          strlen (credentials[i].issuer_attribute) + 1);
+                                          credentials[i].issuer_attribute_len);
     GNUNET_memcpy (cr_entry->credential,
                    &credentials[i],
                    sizeof (struct GNUNET_CREDENTIAL_Credential));
     GNUNET_memcpy (&cr_entry->credential[1],
                    credentials[i].issuer_attribute,
-                   strlen (credentials[i].issuer_attribute));
+                   credentials[i].issuer_attribute_len);
     cr_entry->credential->issuer_attribute = (char*)&cr_entry->credential[1];
     GNUNET_CONTAINER_DLL_insert_tail (vrh->cred_chain_head,
                                       vrh->cred_chain_tail,