gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r20781 - gnunet/src/namestore


From: gnunet
Subject: [GNUnet-SVN] r20781 - gnunet/src/namestore
Date: Tue, 27 Mar 2012 14:46:13 +0200

Author: wachs
Date: 2012-03-27 14:46:13 +0200 (Tue, 27 Mar 2012)
New Revision: 20781

Modified:
   gnunet/src/namestore/gnunet-namestore.c
   gnunet/src/namestore/gnunet-service-namestore.c
Log:
- rewritten zone iteration code for code deduplication and improved flag 
handling
- added mode for gnunet-namestore to list public records and to set record to 
public during creation
  default: list all records, create private record


Modified: gnunet/src/namestore/gnunet-namestore.c
===================================================================
--- gnunet/src/namestore/gnunet-namestore.c     2012-03-27 06:15:16 UTC (rev 
20780)
+++ gnunet/src/namestore/gnunet-namestore.c     2012-03-27 12:46:13 UTC (rev 
20781)
@@ -79,6 +79,16 @@
 static int del;
 
 /**
+ * Is record public
+ */
+static int public;
+
+/**
+ * Is record authority
+ */
+static int nonauthority;
+
+/**
  * Queue entry for the 'del' operation.
  */
 static struct GNUNET_NAMESTORE_QueueEntry *del_qe;
@@ -377,7 +387,10 @@
     rd.data_size = data_size;
     rd.record_type = type;
     rd.expiration = GNUNET_TIME_relative_to_absolute (etime);
-    rd.flags = GNUNET_NAMESTORE_RF_AUTHORITY;
+    if (1 != nonauthority)
+      rd.flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
+    if (1 != public)
+      rd.flags |= GNUNET_NAMESTORE_RF_PRIVATE;
     add_qe = GNUNET_NAMESTORE_record_create (ns,
                                             zone_pkey,
                                             name,
@@ -409,9 +422,18 @@
   }
   if (list)
   {
+    uint32_t must_not_flags = 0;
+
+    if (1 == nonauthority) /* List non-authority records */
+      must_not_flags |= GNUNET_NAMESTORE_RF_AUTHORITY;
+
+    if (1 == public)
+      must_not_flags |= GNUNET_NAMESTORE_RF_PRIVATE;
+
     list_it = GNUNET_NAMESTORE_zone_iteration_start (ns,
                                                     &zone,
-                                                    0, 0,
+                                                    0,
+                                                    must_not_flags,
                                                     &display_record,
                                                     NULL);
   }
@@ -429,6 +451,9 @@
 int
 main (int argc, char *const *argv)
 {
+  nonauthority = -1;
+  public = -1;
+
   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
     {'a', "add", NULL,
      gettext_noop ("add record"), 0,
@@ -451,6 +476,12 @@
     {'V', "value", "VALUE",
      gettext_noop ("value of the record to add/delete"), 1,
      &GNUNET_GETOPT_set_string, &value},   
+    {'p', "public", NULL,
+     gettext_noop ("create or list public record"), 0,
+     &GNUNET_GETOPT_set_one, &public},
+    {'N', "non-authority", NULL,
+     gettext_noop ("create or list non-authority record"), 0,
+     &GNUNET_GETOPT_set_one, &nonauthority},
     {'z', "zonekey", "FILENAME",
      gettext_noop ("filename with the zone key"), 1,
      &GNUNET_GETOPT_set_string, &keyfile},   

Modified: gnunet/src/namestore/gnunet-service-namestore.c
===================================================================
--- gnunet/src/namestore/gnunet-service-namestore.c     2012-03-27 06:15:16 UTC 
(rev 20780)
+++ gnunet/src/namestore/gnunet-service-namestore.c     2012-03-27 12:46:13 UTC 
(rev 20781)
@@ -50,8 +50,15 @@
   uint64_t request_id;
   uint32_t offset;
 
+  /**
+   * Which flags must be included
+   */
+  uint16_t must_have_flags;
 
-
+  /**
+   * Which flags must not be included
+   */
+  uint16_t must_not_have_flags;
 };
 
 
@@ -835,7 +842,6 @@
       break;
     case GNUNET_NO:
         /* identical entry existed, so we did nothing */
-      GNUNET_break(0);
         crc->res = GNUNET_NO;
       break;
     default:
@@ -1422,24 +1428,37 @@
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
+
+/**
+ * Copy record, data has to be free separetely
+ */
+void
+copy_record (const struct GNUNET_NAMESTORE_RecordData *src, struct 
GNUNET_NAMESTORE_RecordData *dest)
+{
+
+  memcpy (dest, src, sizeof (struct GNUNET_NAMESTORE_RecordData));
+  dest->data = GNUNET_malloc (src->data_size);
+  memcpy ((void *) dest->data, src->data, src->data_size);
+}
+
 struct ZoneIterationProcResult
 {
-  int have_zone_key;
+  struct GNUNET_NAMESTORE_ZoneIteration *zi;
+
+  int res_iteration_finished;
+  int records_included;
+  int has_signature;
+
+  char *name;
+  struct GNUNET_CRYPTO_ShortHashCode zone_hash;
+  struct GNUNET_NAMESTORE_RecordData *rd;
   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key;
-
-  int have_signature;
   struct GNUNET_CRYPTO_RsaSignature signature;
   struct GNUNET_TIME_Absolute expire;
-
-  int have_name;
-  char name[256];
-
-  size_t rd_ser_len;
-  char *rd_ser;
 };
 
 
-void zone_iteration_proc (void *cls,
+void zone_iteraterate_proc (void *cls,
                          const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded 
*zone_key,
                          struct GNUNET_TIME_Absolute expire,
                          const char *name,
@@ -1447,19 +1466,143 @@
                          const struct GNUNET_NAMESTORE_RecordData *rd,
                          const struct GNUNET_CRYPTO_RsaSignature *signature)
 {
-  struct GNUNET_NAMESTORE_ZoneIteration *zi = cls;
-  struct GNUNET_NAMESTORE_Client *nc = zi->client;
-  struct GNUNET_NAMESTORE_CryptoContainer * cc;
-  struct GNUNET_CRYPTO_RsaSignature *signature_new = NULL;
+  struct ZoneIterationProcResult *proc = cls;
+  struct GNUNET_NAMESTORE_RecordData *rd_filtered;
+  struct GNUNET_CRYPTO_RsaSignature * new_signature;
+  struct GNUNET_NAMESTORE_CryptoContainer *cc;
+  struct GNUNET_CRYPTO_ShortHashCode hash;
+  GNUNET_HashCode long_hash;
   struct GNUNET_TIME_Absolute e;
-  struct GNUNET_CRYPTO_ShortHashCode zone_key_hash;
-  GNUNET_HashCode long_hash;
-  int authoritative = GNUNET_NO;
+  unsigned int rd_count_filtered  = 0;
+  int include;
+  int c;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ZONE RESULT `%s'\n", name);
+  proc->res_iteration_finished = GNUNET_NO;
+  proc->records_included = 0;
 
   if ((zone_key == NULL) && (name == NULL))
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
+    proc->res_iteration_finished = GNUNET_YES;
+    proc->rd = NULL;
+    proc->name = NULL;
+  }
+  else
+  {
+    rd_filtered = GNUNET_malloc (rd_count * sizeof (struct 
GNUNET_NAMESTORE_RecordData));
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received result for zone iteration: 
`%s'\n", name);
+    for (c = 0; c < rd_count; c++)
+    {
+      include = GNUNET_YES;
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: 0x%x must 
have 0x%x \n",
+          c, rd[c].flags, proc->zi->must_have_flags);
+      /* Checking must have flags */
+      if ((rd[c].flags & proc->zi->must_have_flags) == 
proc->zi->must_have_flags)
+      {
+        /* Include */
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Include 
\n", c);
+      }
+      else
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Not include 
\n", c);
+        include = GNUNET_NO;
+      }
+
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: 0x%x must not 
have 0x%x\n",
+          c, rd[c].flags, proc->zi->must_not_have_flags);
+      if ((rd[c].flags & proc->zi->must_not_have_flags) != 0)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Not include 
\n", c);
+        include = GNUNET_NO;
+      }
+      else
+      {
+        /* Include */
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Record %i has flags: Include 
\n", c);
+      }
+      if (GNUNET_YES == include)
+      {
+        copy_record (&rd[c], &rd_filtered[rd_count_filtered]);
+        rd_count_filtered++;
+      }
+
+    }
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Included %i of %i records \n", 
rd_count_filtered, rd_count);
+
+    proc->records_included = rd_count_filtered;
+    if (0 == rd_count_filtered)
+    {
+      GNUNET_free (rd_filtered);
+      rd_filtered = NULL;
+    }
+    proc->rd = rd_filtered;
+    proc->name = strdup(name);
+    memcpy (&proc->zone_key, zone_key, sizeof (proc->zone_key));
+
+    /* Signature */
+    proc->has_signature = GNUNET_NO;
+    GNUNET_CRYPTO_short_hash (zone_key, sizeof (struct 
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &hash);
+    GNUNET_CRYPTO_short_hash_double(&hash, &long_hash);
+    proc->zone_hash = hash;
+
+    if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
+    {
+      cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash);
+      e = get_block_expiration_time(rd_count_filtered, rd_filtered);
+      proc->expire = e;
+      new_signature = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, 
rd_filtered, rd_count_filtered);
+      GNUNET_assert (signature != NULL);
+      proc->signature = (*new_signature);
+      GNUNET_free (new_signature);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for `%s' in 
zone `%s' with %u records and expiration %llu\n",
+          name, GNUNET_short_h2s(&hash), rd_count_filtered, e.abs_value);
+      proc->has_signature = GNUNET_YES;
+    }
+    else if (rd_count_filtered == rd_count)
+    {
+      proc->expire = expire;
+      if (NULL != signature)
+      {
+        proc->signature = (*signature);
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using provided signature for 
`%s' in zone `%s' with %u records and expiration %llu\n",
+            name, GNUNET_short_h2s(&hash), rd_count_filtered, 
expire.abs_value);
+        proc->has_signature = GNUNET_YES;
+      }
+      else
+      {
+        memset (&proc->signature, '\0', sizeof (proc->signature));
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No signature provided for 
`%s'\n", name);
+      }
+    }
+  }
+
+}
+
+void find_next_zone_iteration_result (struct ZoneIterationProcResult *proc)
+{
+
+  struct GNUNET_CRYPTO_ShortHashCode *zone;
+
+  if (GNUNET_YES == proc->zi->has_zone)
+    zone = &proc->zi->zone;
+  else
+    zone = NULL;
+
+  do
+  {
+    proc->zi->offset++;
+    GSN_database->iterate_records (GSN_database->cls, NULL , NULL, 
proc->zi->offset, &zone_iteraterate_proc, proc);
+  }
+  while ((proc->records_included == 0) && (GNUNET_NO == 
proc->res_iteration_finished));
+}
+
+
+void send_zone_iteration_result (struct ZoneIterationProcResult *proc)
+{
+  struct GNUNET_NAMESTORE_ZoneIteration *zi = proc->zi;
+
+  if (GNUNET_YES == proc->res_iteration_finished)
+  {
     struct ZoneIterationResponseMessage zir_msg;
     if (zi->has_zone == GNUNET_YES)
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No more results for zone `%s'\n", 
GNUNET_short_h2s(&zi->zone));
@@ -1477,79 +1620,73 @@
     zir_msg.rd_len = htons (0);
     memset (&zir_msg.public_key, '\0', sizeof (zir_msg.public_key));
     memset (&zir_msg.signature, '\0', sizeof (zir_msg.signature));
-    GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct 
GNUNET_MessageHeader *) &zir_msg, GNUNET_NO);
+    GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, 
(const struct GNUNET_MessageHeader *) &zir_msg, GNUNET_NO);
 
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Removing zone iterator\n");
-    GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, zi);
+    GNUNET_CONTAINER_DLL_remove (zi->client->op_head, zi->client->op_tail, zi);
     GNUNET_free (zi);
     return;
   }
   else
   {
+    GNUNET_assert (proc->records_included > 0);
+
     struct ZoneIterationResponseMessage *zir_msg;
     if (zi->has_zone == GNUNET_YES)
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration 
over zone `%s'\n",
-          name, GNUNET_short_h2s(&zi->zone));
+          proc->name, GNUNET_short_h2s(&zi->zone));
     if (zi->has_zone == GNUNET_NO)
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending name `%s' for iteration 
over all zones\n",
-          name);
+          proc->name);
 
     size_t name_len;
     size_t rd_ser_len;
     size_t msg_size;
     char *name_tmp;
     char *rd_tmp;
-    name_len = strlen (name) +1;
+    name_len = strlen (proc->name) +1;
 
-    rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd);
+    rd_ser_len = GNUNET_NAMESTORE_records_get_size(proc->records_included, 
proc->rd);
     char rd_ser[rd_ser_len];
-    GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);
+    GNUNET_NAMESTORE_records_serialize(proc->records_included, proc->rd, 
rd_ser_len, rd_ser);
     msg_size = sizeof (struct ZoneIterationResponseMessage) + name_len + 
rd_ser_len;
     zir_msg = GNUNET_malloc(msg_size);
 
     name_tmp = (char *) &zir_msg[1];
     rd_tmp = &name_tmp[name_len];
 
-    GNUNET_CRYPTO_short_hash(zone_key, sizeof (struct 
GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_key_hash);
-    GNUNET_CRYPTO_short_hash_double(&zone_key_hash, &long_hash);
-    if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &long_hash))
-    {
-      cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &long_hash);
-      e = get_block_expiration_time(rd_count, rd);
-      expire = e;
-      signature_new = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, 
rd, rd_count);
-      GNUNET_assert (signature_new != NULL);
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for `%s' in 
zone `%s' with %u records  and expiration %llu\n", name, 
GNUNET_short_h2s(&zone_key_hash), rd_count, e.abs_value);
-      authoritative = GNUNET_YES;
-    }
-
     zir_msg->gns_header.header.type = htons 
(GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
     zir_msg->gns_header.header.size = htons (msg_size);
     zir_msg->gns_header.r_id = htonl(zi->request_id);
-    zir_msg->expire = GNUNET_TIME_absolute_hton(expire);
+    zir_msg->expire = GNUNET_TIME_absolute_hton(proc->expire);
     zir_msg->reserved = htons (0);
     zir_msg->name_len = htons (name_len);
-    zir_msg->rd_count = htons (rd_count);
+    zir_msg->rd_count = htons (proc->records_included);
     zir_msg->rd_len = htons (rd_ser_len);
-    if ((GNUNET_YES == authoritative) && (NULL != signature_new))
-    {
-      zir_msg->signature = *signature_new;
-      GNUNET_free (signature_new);
-    }
-    else
-      zir_msg->signature = *signature;
-    GNUNET_assert (NULL != zone_key);
-    if (zone_key != NULL)
-      zir_msg->public_key = *zone_key;
-    memcpy (name_tmp, name, name_len);
+    zir_msg->signature = proc->signature;
+    zir_msg->public_key = proc->zone_key;
+    memcpy (name_tmp, proc->name, name_len);
     memcpy (rd_tmp, rd_ser, rd_ser_len);
 
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with size 
%u\n", "ZONE_ITERATION_RESPONSE", msg_size);
-    GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct 
GNUNET_MessageHeader *) zir_msg, GNUNET_NO);
+    GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, 
(const struct GNUNET_MessageHeader *) zir_msg, GNUNET_NO);
     GNUNET_free (zir_msg);
   }
 }
 
+void clean_up_zone_iteration_result (struct ZoneIterationProcResult *proc)
+{
+  int c;
+  GNUNET_free_non_null (proc->name);
+  for (c = 0; c < proc->records_included; c++)
+  {
+    GNUNET_free ((void *) proc->rd[c].data);
+  }
+  GNUNET_free_non_null (proc->rd);
+  proc->name = NULL;
+  proc->rd = NULL;
+}
+
 static void handle_iteration_start (void *cls,
                           struct GNUNET_SERVER_Client * client,
                           const struct GNUNET_MessageHeader * message)
@@ -1573,6 +1710,8 @@
   zi->offset = 0;
   zi->client = nc;
   zi->zone = zis_msg->zone;
+  zi->must_have_flags = ntohs (zis_msg->must_have_flags);
+  zi->must_not_have_flags = ntohs (zis_msg->must_not_have_flags);
 
   struct GNUNET_CRYPTO_ShortHashCode dummy;
   struct GNUNET_CRYPTO_ShortHashCode *zone_tmp;
@@ -1592,7 +1731,21 @@
 
   GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
 
-  GSN_database->iterate_records (GSN_database->cls, zone_tmp , NULL, 
zi->offset , &zone_iteration_proc, zi);
+  struct ZoneIterationProcResult proc;
+  proc.zi = zi;
+
+  find_next_zone_iteration_result (&proc);
+  if (GNUNET_YES == proc.res_iteration_finished)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration done\n");
+  }
+  else if (proc.records_included != 0)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration return %u records\n", 
proc.records_included);
+  }
+  send_zone_iteration_result (&proc);
+  clean_up_zone_iteration_result (&proc);
+
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
@@ -1676,8 +1829,22 @@
   else
     zone_tmp = NULL;
 
-  zi->offset++;
-  GSN_database->iterate_records (GSN_database->cls, zone_tmp, NULL, zi->offset 
, &zone_iteration_proc, zi);
+
+  struct ZoneIterationProcResult proc;
+  proc.zi = zi;
+
+  find_next_zone_iteration_result (&proc);
+  if (GNUNET_YES == proc.res_iteration_finished)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration done\n");
+  }
+  else if (proc.records_included != 0)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Zone iteration return %u records\n", 
proc.records_included);
+  }
+  send_zone_iteration_result (&proc);
+  clean_up_zone_iteration_result (&proc);
+
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 




reply via email to

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