gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] branch master updated: GNS: Add tombstone string processing; a


From: gnunet
Subject: [gnunet] branch master updated: GNS: Add tombstone string processing; also handle tombstones in monitor properly
Date: Sat, 05 Feb 2022 17:17:43 +0100

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository gnunet.

The following commit(s) were added to refs/heads/master by this push:
     new aa85ac347 GNS: Add tombstone string processing; also handle tombstones 
in monitor properly
aa85ac347 is described below

commit aa85ac347e31b22bcd86c6fbe9875dc4ffa93229
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Sat Feb 5 17:17:37 2022 +0100

    GNS: Add tombstone string processing; also handle tombstones in monitor 
properly
---
 src/gns/plugin_gnsrecord_gns.c                     |  23 ++-
 src/zonemaster/gnunet-service-zonemaster-monitor.c | 166 ++++++++++++++++++++-
 2 files changed, 181 insertions(+), 8 deletions(-)

diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c
index e74ec96ad..694dc6351 100644
--- a/src/gns/plugin_gnsrecord_gns.c
+++ b/src/gns/plugin_gnsrecord_gns.c
@@ -132,7 +132,12 @@ gns_value_to_string (void *cls,
       GNUNET_free (ival);
       return box_str;
     }
-
+  case GNUNET_GNSRECORD_TYPE_TOMBSTONE: {
+    const struct GNUNET_GNSRECORD_TombstoneRecord *ts = data;
+    struct GNUNET_TIME_Absolute tod;
+    tod = GNUNET_TIME_absolute_ntoh (ts->time_of_death);
+    return GNUNET_strdup (GNUNET_STRINGS_absolute_time_to_string (tod));
+  }
   default:
     return NULL;
   }
@@ -183,7 +188,7 @@ gns_string_to_value (void *cls,
     if (record_type != type)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _("Record type does not match parsed record type\n"));
+                  _ ("Record type does not match parsed record type\n"));
       return GNUNET_SYSERR;
     }
     return GNUNET_OK;
@@ -297,6 +302,19 @@ gns_string_to_value (void *cls,
       GNUNET_free (bval);
       return GNUNET_OK;
     }
+  case GNUNET_GNSRECORD_TYPE_TOMBSTONE: {
+      struct GNUNET_TIME_Absolute tod;
+      struct GNUNET_TIME_AbsoluteNBO *tod_nbo;
+      if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_absolute (s,
+                                                              &tod))
+        return GNUNET_SYSERR;
+      tod_nbo = GNUNET_new (struct GNUNET_TIME_AbsoluteNBO);
+      *tod_nbo = GNUNET_TIME_absolute_hton (tod);
+      *data_size = sizeof (*tod_nbo);
+      *data = tod_nbo;
+      return GNUNET_OK;
+    }
+
 
   default:
     return GNUNET_SYSERR;
@@ -320,6 +338,7 @@ static struct
                      { "GNS2DNS", GNUNET_GNSRECORD_TYPE_GNS2DNS },
                      { "BOX", GNUNET_GNSRECORD_TYPE_BOX },
                      { "REDIRECT", GNUNET_GNSRECORD_TYPE_REDIRECT },
+                     { "TOMBSTONE", GNUNET_GNSRECORD_TYPE_TOMBSTONE },
                      { NULL, UINT32_MAX } };
 
 
diff --git a/src/zonemaster/gnunet-service-zonemaster-monitor.c 
b/src/zonemaster/gnunet-service-zonemaster-monitor.c
index 3392a19d7..081398f0e 100644
--- a/src/zonemaster/gnunet-service-zonemaster-monitor.c
+++ b/src/zonemaster/gnunet-service-zonemaster-monitor.c
@@ -58,6 +58,29 @@
  */
 #define DHT_GNS_REPLICATION_LEVEL 5
 
+/**
+ * Handle for tombston updates which are executed for each published
+ * record set.
+ */
+struct TombstoneActivity
+{
+  /**
+   * Kept in a DLL.
+   */
+  struct TombstoneActivity *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct TombstoneActivity *prev;
+
+  /**
+   * Handle for the store operation.
+   */
+  struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
+
+};
+
 
 /**
  * Handle for DHT PUT activity triggered from the namestore monitor.
@@ -106,6 +129,17 @@ static struct GNUNET_NAMESTORE_Handle *namestore_handle;
  */
 static struct GNUNET_NAMESTORE_ZoneMonitor *zmon;
 
+/**
+ * Head of the tombstone operations
+ */
+static struct TombstoneActivity *ta_head;
+
+/**
+ * Tail of the tombstone operations
+ */
+static struct TombstoneActivity *ta_tail;
+
+
 /**
  * Head of monitor activities; kept in a DLL.
  */
@@ -138,6 +172,7 @@ static void
 shutdown_task (void *cls)
 {
   struct DhtPutActivity *ma;
+  struct TombstoneActivity *ta;
 
   (void) cls;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -151,6 +186,14 @@ shutdown_task (void *cls)
                                  ma);
     GNUNET_free (ma);
   }
+  while (NULL != (ta = ta_head))
+  {
+    GNUNET_NAMESTORE_cancel (ta->ns_qe);
+    GNUNET_CONTAINER_DLL_remove (ta_head,
+                                 ta_tail,
+                                 ta);
+    GNUNET_free (ta);
+  }
   if (NULL != statistics)
   {
     GNUNET_STATISTICS_destroy (statistics,
@@ -209,22 +252,51 @@ dht_put_monitor_continuation (void *cls)
 static unsigned int
 convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd,
                             unsigned int rd_count,
-                            struct GNUNET_GNSRECORD_Data *rd_public)
+                            struct GNUNET_GNSRECORD_Data *rd_public,
+                            struct GNUNET_TIME_Absolute *expiry)
 {
+  const struct GNUNET_GNSRECORD_TombstoneRecord *tombstone;
+  struct GNUNET_TIME_Absolute expiry_tombstone;
   struct GNUNET_TIME_Absolute now;
   unsigned int rd_public_count;
 
   rd_public_count = 0;
+  tombstone = NULL;
   now = GNUNET_TIME_absolute_get ();
   for (unsigned int i = 0; i < rd_count; i++)
   {
     if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))
       continue;
+    if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
+    {
+      tombstone = rd[i].data;
+      continue;
+    }
     if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) &&
         (rd[i].expiration_time < now.abs_value_us))
       continue;   /* record already expired, skip it */
-    rd_public[rd_public_count++] = rd[i];
+    rd_public[rd_public_count] = rd[i];
+    /* Make sure critical record types are published as such */
+    if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type))
+      rd_public[rd_public_count].flags |= GNUNET_GNSRECORD_RF_CRITICAL;
+    rd_public_count++;
+  }
+
+  *expiry = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count,
+                                                         rd_public);
+
+  /* We need to check if the tombstone has an expiration in the fututre
+   * which would mean there was a block published under this label
+   * previously that is still valid. In this case we MUST NOT publish this
+   * block
+   */
+  if (NULL != tombstone)
+  {
+    expiry_tombstone = GNUNET_TIME_absolute_ntoh (tombstone->time_of_death);
+    if (GNUNET_TIME_absolute_cmp (*expiry,<=,expiry_tombstone))
+      return 0;
   }
+
   return rd_public_count;
 }
 
@@ -244,16 +316,14 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey 
*key,
                  const char *label,
                  const struct GNUNET_GNSRECORD_Data *rd_public,
                  unsigned int rd_public_count,
+                 struct GNUNET_TIME_Absolute expire,
                  struct DhtPutActivity *ma)
 {
   struct GNUNET_GNSRECORD_Block *block;
   struct GNUNET_HashCode query;
-  struct GNUNET_TIME_Absolute expire;
   size_t block_size;
   struct GNUNET_DHT_PutHandle *ret;
 
-  expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count,
-                                                        rd_public);
   if (cache_keys)
     GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key,
                                                                 expire,
@@ -301,6 +371,76 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey 
*key,
   return ret;
 }
 
+static void
+ts_store_cont (void *cls, int32_t success, const char *emsg)
+{
+  struct TombstoneActivity *ta = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Tombstone update complete\n");
+  GNUNET_CONTAINER_DLL_remove (ta_head,
+                               ta_tail,
+                               ta);
+  GNUNET_free (ta);
+
+}
+
+
+/**
+ * Update tombstone records.
+ *
+ * @param key key of the zone
+ * @param label label to store under
+ * @param rd_public public record data
+ * @param rd_public_count number of records in @a rd_public
+ * @param expire the expiration time for the tombstone
+ * @param ta handle for the put operation
+ * @return Namestore queue entry, NULL on error
+ */
+static struct GNUNET_NAMESTORE_QueueEntry *
+touch_tombstone (const struct GNUNET_IDENTITY_PrivateKey *key,
+                 const char *label,
+                 const struct GNUNET_GNSRECORD_Data *rd_original,
+                 unsigned int rd_count_original,
+                 const struct GNUNET_TIME_Absolute expire,
+                 struct TombstoneActivity *ta)
+{
+  struct GNUNET_TIME_AbsoluteNBO exp_nbo;
+  struct GNUNET_GNSRECORD_Data rd[rd_count_original + 1];
+  int tombstone_exists = GNUNET_NO;
+  unsigned int rd_count;
+
+  exp_nbo = GNUNET_TIME_absolute_hton (expire);
+  for (rd_count = 0; rd_count < rd_count_original; rd_count++)
+  {
+    memcpy (&rd[rd_count], &rd_original[rd_count],
+            sizeof (struct GNUNET_GNSRECORD_Data));
+    if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[rd_count].record_type)
+    {
+      rd[rd_count].data = &exp_nbo;
+      tombstone_exists = GNUNET_YES;
+    }
+  }
+  if (GNUNET_NO == tombstone_exists)
+  {
+    rd[rd_count].data = &exp_nbo;
+    rd[rd_count].data_size = sizeof (exp_nbo);
+    rd[rd_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
+    rd[rd_count].flags = GNUNET_GNSRECORD_RF_PRIVATE;
+    rd[rd_count].expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
+    rd_count++;
+  }
+  return GNUNET_NAMESTORE_records_store_ (namestore_handle,
+                                                key,
+                                                label,
+                                                rd_count,
+                                                rd,
+                                                GNUNET_YES,
+                                                &ts_store_cont,
+                                                ta);
+}
+
+
 
 /**
  * Process a record that was stored in the namestore
@@ -322,6 +462,8 @@ handle_monitor_event (void *cls,
   struct GNUNET_GNSRECORD_Data rd_public[rd_count];
   unsigned int rd_public_count;
   struct DhtPutActivity *ma;
+  struct TombstoneActivity *ta;
+  struct GNUNET_TIME_Absolute expire;
 
   (void) cls;
   GNUNET_STATISTICS_update (statistics,
@@ -336,7 +478,8 @@ handle_monitor_event (void *cls,
      absolute expiration time. */
   rd_public_count = convert_records_for_export (rd,
                                                 rd_count,
-                                                rd_public);
+                                                rd_public,
+                                                &expire);
   if (0 == rd_public_count)
   {
     GNUNET_NAMESTORE_zone_monitor_next (zmon,
@@ -349,7 +492,18 @@ handle_monitor_event (void *cls,
                             label,
                             rd,
                             rd_count,
+                            expire,
                             ma);
+  ta = GNUNET_new (struct TombstoneActivity);
+  ta->ns_qe = touch_tombstone (zone,
+                               label,
+                               rd,
+                               rd_count,
+                               expire,
+                               ta);
+  GNUNET_CONTAINER_DLL_insert_tail (ta_head,
+                                    ta_tail,
+                                    ta);
   if (NULL == ma->ph)
   {
     /* PUT failed, do not remember operation */

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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