gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] branch master updated: NAMESTORE: Allow service-side record set


From: gnunet
Subject: [gnunet] branch master updated: NAMESTORE: Allow service-side record set filtering. Fixes #7193
Date: Wed, 28 Sep 2022 07:06:20 +0200

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 3ec2b451f NAMESTORE: Allow service-side record set filtering. Fixes 
#7193
3ec2b451f is described below

commit 3ec2b451f938398eb4d2f92603f0659c26f6675c
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Wed Sep 28 14:05:01 2022 +0900

    NAMESTORE: Allow service-side record set filtering. Fixes #7193
    
    This commit enables zone iteration APIs which allow you to set a record
    set filter to determine which records should be returned or not.
    In particular filtering of private records and maintenance records
    (TOMBSTONE) for zonemaster.
---
 src/gnsrecord/gnsrecord_misc.c                     |  27 +---
 src/include/gnunet_gnsrecord_lib.h                 |  57 ++++----
 src/include/gnunet_namestore_service.h             | 112 +++++++++++++++-
 src/namestore/gnunet-service-namestore.c           | 144 +++++++++++++++------
 src/namestore/namestore.h                          |  28 ++++
 src/namestore/namestore_api.c                      |  83 ++++++++----
 src/namestore/namestore_api_monitor.c              |  76 +++++++----
 src/zonemaster/gnunet-service-zonemaster-monitor.c |  50 +++----
 src/zonemaster/gnunet-service-zonemaster.c         |  51 +++-----
 9 files changed, 416 insertions(+), 212 deletions(-)

diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c
index 5e3bbdb8c..880fc68c6 100644
--- a/src/gnsrecord/gnsrecord_misc.c
+++ b/src/gnsrecord/gnsrecord_misc.c
@@ -421,7 +421,7 @@ GNUNET_GNSRECORD_normalize_record_set (const char *label,
                                        rd_public,
                                        unsigned int *rd_count_public,
                                        struct GNUNET_TIME_Absolute *expiry,
-                                       int include_private,
+                                       enum GNUNET_GNSRECORD_Filter filter,
                                        char **emsg)
 {
   struct GNUNET_TIME_Absolute now;
@@ -539,7 +539,7 @@ GNUNET_GNSRECORD_normalize_record_set (const char *label,
 
     /* Ignore private records for public record set */
 
-    if ((GNUNET_NO == include_private) &&
+    if ((0 != (filter & GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE)) &&
         (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)))
       continue;
     /* Skip expired records */
@@ -561,27 +561,4 @@ GNUNET_GNSRECORD_normalize_record_set (const char *label,
 }
 
 
-enum GNUNET_GenericReturnValue
-GNUNET_GNSRECORD_convert_records_for_export (const char *label,
-                                             const struct
-                                             GNUNET_GNSRECORD_Data *rd,
-                                             unsigned int rd_count,
-                                             struct GNUNET_GNSRECORD_Data *
-                                             rd_public,
-                                             unsigned int *rd_count_public,
-                                             struct GNUNET_TIME_Absolute 
*expiry,
-                                             char **emsg)
-{
-  return GNUNET_GNSRECORD_normalize_record_set (label,
-                                                rd,
-                                                rd_count,
-                                                rd_public,
-                                                rd_count_public,
-                                                expiry,
-                                                GNUNET_NO,
-                                                emsg);
-
-}
-
-
 /* end of gnsrecord_misc.c */
diff --git a/src/include/gnunet_gnsrecord_lib.h 
b/src/include/gnunet_gnsrecord_lib.h
index 1ff348b71..21fb610f3 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -124,6 +124,35 @@ enum GNUNET_GNSRECORD_Flags
 #define GNUNET_GNSRECORD_RF_RCMP_FLAGS 
(GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)
 };
 
+/**
+ * Filter for GNUNET_GNSRECORD_normalize_record_set().
+ */
+enum GNUNET_GNSRECORD_Filter
+{
+  /**
+   * No filter flags set.
+   * Private and public records are returned,
+   * maintenance records (TOMBSTONE etc) are not.
+   */
+  GNUNET_GNSRECORD_FILTER_NONE = 0,
+
+  /**
+   * Include maintenance records (TOMBSTONE etc).
+   */
+  GNUNET_GNSRECORD_FILTER_INCLUDE_MAINTENANCE = 1,
+
+  /**
+   * Filter private records
+   */
+  GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE = 2,
+
+  /**
+   * Filter public records.
+   * FIXME: Not implemented
+   */
+  //GNUNET_NAMESTORE_FILTER_OMIT_PUBLIC = 4,
+};
+
 
 /**
  * A GNS record.
@@ -725,7 +754,7 @@ GNUNET_GNSRECORD_is_critical (uint32_t type);
  * @param rd_public where to write the converted records
  * @param rd_public_count number of records written to @a rd_public
  * @param min_expiry the minimum expiration of this set
- * @param include_private GNUNET_YES if private records should be included.
+ * @param filter the record set filter, see GNUNET_GNSRECORD_Filter.
  * @param emsg the error message if something went wrong
  * @return GNUNET_OK if set could be normalized and is consistent
  */
@@ -736,34 +765,10 @@ GNUNET_GNSRECORD_normalize_record_set (const char *label,
                                        struct GNUNET_GNSRECORD_Data *rd_public,
                                        unsigned int *rd_count_public,
                                        struct GNUNET_TIME_Absolute *min_expiry,
-                                       int include_private,
+                                       enum GNUNET_GNSRECORD_Filter filter,
                                        char **emsg);
 
 
-/**
- * Convert namestore records from the internal format to that
- * suitable for publication (removes private records).
- *
- * @param label the label under which this set is (supposed to be) published.
- * @param rd input records
- * @param rd_count size of the @a rd and @a rd_public arrays
- * @param rd_public where to write the converted records
- * @param rd_public_count number of records written to @a rd_public
- * @param expiry the expiration of the block
- * @param emsg the error message if something went wrong
- * @return GNUNET_OK if set is consistent and can be exported
- */
-enum GNUNET_GenericReturnValue
-GNUNET_GNSRECORD_convert_records_for_export (const char *label,
-                                             const struct
-                                             GNUNET_GNSRECORD_Data *rd,
-                                             unsigned int rd_count,
-                                             struct GNUNET_GNSRECORD_Data *
-                                             rd_public,
-                                             unsigned int *rd_count_public,
-                                             struct GNUNET_TIME_Absolute 
*expiry,
-                                             char **emsg);
-
 /**
  * Check label for invalid characters.
  *
diff --git a/src/include/gnunet_namestore_service.h 
b/src/include/gnunet_namestore_service.h
index 0788bc8b4..dc6aeaa69 100644
--- a/src/include/gnunet_namestore_service.h
+++ b/src/include/gnunet_namestore_service.h
@@ -198,6 +198,27 @@ typedef void
                                    unsigned int rd_count,
                                    const struct GNUNET_GNSRECORD_Data *rd);
 
+/**
+ * Process a record set that was stored in the namestore.
+ * The record set expiration value takes existing TOMBSTONE records
+ * into account even if those are not returned.
+ *
+ * @param cls closure
+ * @param zone private key of the zone
+ * @param label label of the records
+ * @param rd_count number of entries in @a rd array, 0 if label was deleted
+ * @param rd array of records with data to store
+ * @param expiry the expiration of this record set.
+ */
+typedef void
+(*GNUNET_NAMESTORE_RecordSetMonitor) (void *cls,
+                                      const struct
+                                      GNUNET_IDENTITY_PrivateKey *zone,
+                                      const char *label,
+                                      unsigned int rd_count,
+                                      const struct GNUNET_GNSRECORD_Data *rd,
+                                      struct GNUNET_TIME_Absolute expiry);
+
 
 /**
  * Lookup an item in the namestore.
@@ -265,6 +286,9 @@ GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry 
*qe);
 
 
 /**
+ * @deprecated since 0.16.7 will be replaced in 0.18
+ * @see GNUNET_NAMESTORE_zone_iteration_start2()
+ *
  * Starts a new zone iteration (used to periodically PUT all of our
  * records into our DHT). This MUST lock the `struct GNUNET_NAMESTORE_Handle`
  * for any other calls than #GNUNET_NAMESTORE_zone_iterator_next() and
@@ -300,6 +324,44 @@ GNUNET_NAMESTORE_zone_iteration_start (struct 
GNUNET_NAMESTORE_Handle *h,
                                        GNUNET_SCHEDULER_TaskCallback finish_cb,
                                        void *finish_cb_cls);
 
+/**
+ * Starts a new zone iteration (used to periodically PUT all of our
+ * records into our DHT). This MUST lock the `struct GNUNET_NAMESTORE_Handle`
+ * for any other calls than #GNUNET_NAMESTORE_zone_iterator_next() and
+ * #GNUNET_NAMESTORE_zone_iteration_stop. @a proc will be called once
+ * immediately, and then again after
+ * #GNUNET_NAMESTORE_zone_iterator_next() is invoked.
+ *
+ * On error (disconnect), @a error_cb will be invoked.
+ * On normal completion, @a finish_cb proc will be
+ * invoked.
+ *
+ * @param h handle to the namestore
+ * @param zone zone to access, NULL for all zones
+ * @param error_cb function to call on error (i.e. disconnect),
+ *        the handle is afterwards invalid
+ * @param error_cb_cls closure for @a error_cb
+ * @param proc function to call on each name from the zone; it
+ *        will be called repeatedly with a value (if available)
+ * @param proc_cls closure for @a proc
+ * @param finish_cb function to call on completion
+ *        the handle is afterwards invalid
+ * @param finish_cb_cls closure for @a finish_cb
+ * @return an iterator handle to use for iteration
+ */
+struct GNUNET_NAMESTORE_ZoneIterator *
+GNUNET_NAMESTORE_zone_iteration_start2 (struct GNUNET_NAMESTORE_Handle *h,
+                                        const struct
+                                        GNUNET_IDENTITY_PrivateKey *zone,
+                                        GNUNET_SCHEDULER_TaskCallback error_cb,
+                                        void *error_cb_cls,
+                                        GNUNET_NAMESTORE_RecordSetMonitor proc,
+                                        void *proc_cls,
+                                        GNUNET_SCHEDULER_TaskCallback 
finish_cb,
+                                        void *finish_cb_cls,
+                                        enum GNUNET_GNSRECORD_Filter filter);
+
+
 
 /**
  * Calls the record processor specified in 
#GNUNET_NAMESTORE_zone_iteration_start
@@ -332,6 +394,9 @@ struct GNUNET_NAMESTORE_ZoneMonitor;
 
 
 /**
+ * @deprecated since 0.16.7 will be replaced in 0.18
+ * @see GNUNET_NAMESTORE_zone_monitor_start2()
+ *
  * Begin monitoring a zone for changes.  Will first call the @a
  * monitor function on all existing records in the selected zone(s) if
  * @a iterate_first is #GNUNET_YES.  In any case, we will then call @a
@@ -370,6 +435,47 @@ GNUNET_NAMESTORE_zone_monitor_start (
   GNUNET_SCHEDULER_TaskCallback sync_cb,
   void *sync_cb_cls);
 
+/**
+ * Begin monitoring a zone for changes.  Will first call the @a
+ * monitor function on all existing records in the selected zone(s) if
+ * @a iterate_first is #GNUNET_YES.  In any case, we will then call @a
+ * sync_cb, and then afterwards call the @a monitor whenever a record
+ * changes.  If the namestore disconnects, the @a error_cb function is
+ * called with a disconnect event. Once the connection is
+ * re-established, the process begins from the start (depending on @a
+ * iterate_first, we will again first do all existing records, then @a
+ * sync, then updates).
+ *
+ * @param cfg configuration to use to connect to namestore
+ * @param zone zone to monitor, NULL for all zones
+ * @param iterate_first #GNUNET_YES to first iterate over all existing records,
+ *                      #GNUNET_NO to only return changes that happen from now 
on
+ * @param error_cb function to call on error (i.e. disconnect); note that
+ *         unlike the other error callbacks in this API, a call to this
+ *         function does NOT destroy the monitor handle, it merely signals
+ *         that monitoring is down. You need to still explicitly call
+ *         #GNUNET_NAMESTORE_zone_monitor_stop().
+ * @param error_cb_cls closure for @a error_cb
+ * @param monitor function to call on zone changes, with an initial limit of 1
+ * @param monitor_cls closure for @a monitor
+ * @param sync_cb function called when we're in sync with the namestore
+ * @param sync_cb_cls closure for @a sync_cb
+ * @param filter the record set filter to use
+ * @return handle to stop monitoring
+ */
+struct GNUNET_NAMESTORE_ZoneMonitor *
+GNUNET_NAMESTORE_zone_monitor_start2 (
+  const struct GNUNET_CONFIGURATION_Handle *cfg,
+  const struct GNUNET_IDENTITY_PrivateKey *zone,
+  int iterate_first,
+  GNUNET_SCHEDULER_TaskCallback error_cb,
+  void *error_cb_cls,
+  GNUNET_NAMESTORE_RecordSetMonitor monitor,
+  void *monitor_cls,
+  GNUNET_SCHEDULER_TaskCallback sync_cb,
+  void *sync_cb_cls,
+  enum GNUNET_GNSRECORD_Filter filter);
+
 
 /**
  * Calls the monitor processor specified in 
#GNUNET_NAMESTORE_zone_monitor_start
@@ -435,9 +541,9 @@ GNUNET_NAMESTORE_transaction_begin (struct 
GNUNET_NAMESTORE_Handle *h,
  */
 struct GNUNET_NAMESTORE_QueueEntry *
 GNUNET_NAMESTORE_transaction_rollback (struct GNUNET_NAMESTORE_Handle *h,
-                                     GNUNET_NAMESTORE_ContinuationWithStatus
-                                     cont,
-                                     void *cont_cls);
+                                       GNUNET_NAMESTORE_ContinuationWithStatus
+                                       cont,
+                                       void *cont_cls);
 /**
  * Commit a namestore transaction.
  * Saves all actions performed since #GNUNET_NAMESTORE_transaction_begin
diff --git a/src/namestore/gnunet-service-namestore.c 
b/src/namestore/gnunet-service-namestore.c
index 1bfcec76b..0a3dfea25 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -84,6 +84,11 @@ struct ZoneIteration
    */
   struct GNUNET_IDENTITY_PrivateKey zone;
 
+  /**
+   * The record set filter
+   */
+  enum GNUNET_GNSRECORD_Filter filter;
+
   /**
    * Last sequence number in the zone iteration used to address next
    * result of the zone iteration in the store
@@ -180,6 +185,11 @@ struct ZoneMonitor
    */
   struct GNUNET_IDENTITY_PrivateKey zone;
 
+  /**
+   * The record set filter
+   */
+  enum GNUNET_GNSRECORD_Filter filter;
+
   /**
    * Task active during initial iteration.
    */
@@ -717,38 +727,63 @@ merge_with_nick_records (const struct 
GNUNET_GNSRECORD_Data *nick_rd,
  * @param name name
  * @param rd_count number of records in @a rd
  * @param rd array of records
+ * @param filter record set filter
  */
 static void
-send_lookup_response (struct NamestoreClient *nc,
-                      uint32_t request_id,
-                      const struct GNUNET_IDENTITY_PrivateKey *zone_key,
-                      const char *name,
-                      unsigned int rd_count,
-                      const struct GNUNET_GNSRECORD_Data *rd)
+send_lookup_response_with_filter (struct NamestoreClient *nc,
+                                  uint32_t request_id,
+                                  const struct
+                                  GNUNET_IDENTITY_PrivateKey *zone_key,
+                                  const char *name,
+                                  unsigned int rd_count,
+                                  const struct GNUNET_GNSRECORD_Data *rd,
+                                  enum GNUNET_GNSRECORD_Filter filter)
 {
   struct GNUNET_MQ_Envelope *env;
   struct RecordResultMessage *zir_msg;
   struct GNUNET_GNSRECORD_Data *nick;
   struct GNUNET_GNSRECORD_Data *res;
+  struct GNUNET_GNSRECORD_Data rd_nf[rd_count];
+  struct GNUNET_TIME_Absolute block_exp = GNUNET_TIME_UNIT_ZERO_ABS;;
   unsigned int res_count;
+  unsigned int rd_nf_count;
   size_t name_len;
   ssize_t rd_ser_len;
   char *name_tmp;
   char *rd_ser;
+  char *emsg;
 
   nick = get_nick_record (nc, zone_key);
   GNUNET_assert (-1 != GNUNET_GNSRECORD_records_get_size (rd_count, rd));
 
+  if (GNUNET_OK != GNUNET_GNSRECORD_normalize_record_set (name,
+                                                          rd,
+                                                          rd_count,
+                                                          rd_nf,
+                                                          &rd_nf_count,
+                                                          &block_exp,
+                                                          filter,
+                                                          &emsg))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
+    GNUNET_free (emsg);
+    GNUNET_assert (0);
+  }
+
+  /**
+   * FIXME if we ever support GNUNET_NAMESTORE_OMIT_PUBLIC,
+   * we need to omit adding this public record here
+   */
   if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
   {
     nick->flags =
       (nick->flags | GNUNET_GNSRECORD_RF_PRIVATE) ^ 
GNUNET_GNSRECORD_RF_PRIVATE;
-    merge_with_nick_records (nick, rd_count, rd, &res_count, &res);
+    merge_with_nick_records (nick, rd_nf_count, rd_nf, &res_count, &res);
   }
   else
   {
-    res_count = rd_count;
-    res = (struct GNUNET_GNSRECORD_Data *) rd;
+    res_count = rd_nf_count;
+    res = (struct GNUNET_GNSRECORD_Data *) rd_nf;
   }
   if (NULL != nick)
     GNUNET_free (nick);
@@ -782,6 +817,7 @@ send_lookup_response (struct NamestoreClient *nc,
   zir_msg->rd_count = htons (res_count);
   zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
   zir_msg->private_key = *zone_key;
+  zir_msg->expire = GNUNET_TIME_absolute_hton (block_exp);
   name_tmp = (char *) &zir_msg[1];
   GNUNET_memcpy (name_tmp, name, name_len);
   rd_ser = &name_tmp[name_len];
@@ -796,10 +832,33 @@ send_lookup_response (struct NamestoreClient *nc,
                             1,
                             GNUNET_NO);
   GNUNET_MQ_send (nc->mq, env);
-  if (rd != res)
+  if (rd_nf != res)
     GNUNET_free (res);
 }
 
+/**
+ * Generate a `struct LookupNameResponseMessage` and send it to the
+ * given client using the given notification context.
+ *
+ * @param nc client to unicast to
+ * @param request_id request ID to use
+ * @param zone_key zone key of the zone
+ * @param name name
+ * @param rd_count number of records in @a rd
+ * @param rd array of records
+ */
+static void
+send_lookup_response (struct NamestoreClient *nc,
+                      uint32_t request_id,
+                      const struct
+                      GNUNET_IDENTITY_PrivateKey *zone_key,
+                      const char *name,
+                      unsigned int rd_count,
+                      const struct GNUNET_GNSRECORD_Data *rd)
+{
+  send_lookup_response_with_filter (nc, request_id, zone_key, name,
+                                    rd_count, rd, 
GNUNET_GNSRECORD_FILTER_NONE);
+}
 
 /**
  * Send response to the store request to the client.
@@ -995,7 +1054,7 @@ refresh_block (struct NamestoreClient *nc,
   cop->nc = nc;
   cop->zi = zi;
   if (NULL != zi)
-    zi->cache_ops ++;
+    zi->cache_ops++;
   cop->rid = rid;
   GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop);
   cop->qe = GNUNET_NAMECACHE_block_cache (namecache,
@@ -1081,12 +1140,13 @@ continue_store_activity (struct StoreActivity *sa)
                   "Notifying monitor about changes under label `%s'\n",
                   sa->conv_name);
       zm->limit--;
-      send_lookup_response (zm->nc,
-                            0,
-                            &rp_msg->private_key,
-                            sa->conv_name,
-                            rd_count,
-                            rd);
+      send_lookup_response_with_filter (zm->nc,
+                                        0,
+                                        &rp_msg->private_key,
+                                        sa->conv_name,
+                                        rd_count,
+                                        rd,
+                                        zm->filter);
       sa->zm_pos = zm->next;
     }
     /* great, done with the monitors, unpack (again) for refresh_block 
operation */
@@ -1454,7 +1514,7 @@ handle_record_lookup (void *cls, const struct 
LabelLookupMessage *ll_msg)
   if (GNUNET_YES == rlc.found)
     llr_msg->found = htons (GNUNET_YES);
   else if (GNUNET_SYSERR == res)
-   llr_msg->found = htons (GNUNET_SYSERR);
+    llr_msg->found = htons (GNUNET_SYSERR);
   else
     llr_msg->found = htons (GNUNET_NO);
   GNUNET_memcpy (&llr_msg[1], conv_name, name_len);
@@ -1531,13 +1591,15 @@ get_block_exp_existing (void *cls,
   unsigned int rd_pub_count;
   char *emsg;
 
-  if (GNUNET_OK != GNUNET_GNSRECORD_convert_records_for_export (label,
-                                                                rd,
-                                                                rd_count,
-                                                                rd_pub,
-                                                                &rd_pub_count,
-                                                                exp,
-                                                                &emsg))
+  if (GNUNET_OK !=
+      GNUNET_GNSRECORD_normalize_record_set (label,
+                                             rd,
+                                             rd_count,
+                                             rd_pub,
+                                             &rd_pub_count,
+                                             exp,
+                                             
GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE,
+                                             &emsg))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "%s\n", emsg);
@@ -1673,14 +1735,15 @@ handle_record_store (void *cls, const struct 
RecordStoreMessage *rp_msg)
           have_nick = GNUNET_YES;
         }
       }
-      if (GNUNET_OK != GNUNET_GNSRECORD_normalize_record_set (conv_name,
-                                                              rd_clean,
-                                                              rd_clean_off,
-                                                              rd_nf,
-                                                              &rd_nf_count,
-                                                              &new_block_exp,
-                                                              GNUNET_YES,
-                                                              &emsg))
+      if (GNUNET_OK !=
+          GNUNET_GNSRECORD_normalize_record_set (conv_name,
+                                                 rd_clean,
+                                                 rd_clean_off,
+                                                 rd_nf,
+                                                 &rd_nf_count,
+                                                 &new_block_exp,
+                                                 GNUNET_GNSRECORD_FILTER_NONE,
+                                                 &emsg))
       {
         send_store_response (nc, GNUNET_SYSERR, emsg, rid);
         GNUNET_free (emsg);
@@ -1991,12 +2054,13 @@ zone_iterate_proc (void *cls,
   }
   proc->limit--;
   proc->zi->seq = seq;
-  send_lookup_response (proc->zi->nc,
-                        proc->zi->request_id,
-                        zone_key,
-                        name,
-                        rd_count,
-                        rd);
+  send_lookup_response_with_filter (proc->zi->nc,
+                                    proc->zi->request_id,
+                                    zone_key,
+                                    name,
+                                    rd_count,
+                                    rd,
+                                    proc->zi->filter);
 
 
   do_refresh_block = GNUNET_NO;
@@ -2077,6 +2141,7 @@ handle_iteration_start (void *cls,
               "Received ZONE_ITERATION_START message\n");
   zi = GNUNET_new (struct ZoneIteration);
   zi->request_id = ntohl (zis_msg->gns_header.r_id);
+  zi->filter = ntohs (zis_msg->filter);
   zi->offset = 0;
   zi->nc = nc;
   zi->zone = zis_msg->zone;
@@ -2281,6 +2346,7 @@ handle_monitor_start (void *cls, const struct 
ZoneMonitorStartMessage *zis_msg)
   zm->nc = nc;
   zm->zone = zis_msg->zone;
   zm->limit = 1;
+  zm->filter = ntohs (zis_msg->filter);
   zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
   GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, zm);
   GNUNET_SERVICE_client_mark_monitor (nc->client);
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h
index 8aaba180f..ad02ffb48 100644
--- a/src/namestore/namestore.h
+++ b/src/namestore/namestore.h
@@ -279,6 +279,12 @@ struct RecordResultMessage
    */
   struct GNUNET_NAMESTORE_Header gns_header;
 
+  /**
+   * Expiration time if the record result (if any).
+   * Takes TOMBSTONEs into account.
+   */
+  struct GNUNET_TIME_AbsoluteNBO expire;
+
   /**
    * Name length
    */
@@ -375,6 +381,17 @@ struct ZoneMonitorStartMessage
    */
   uint32_t iterate_first GNUNET_PACKED;
 
+  /**
+   * Record set filter control flags.
+   * See GNUNET_NAMESTORE_Filter enum.
+   */
+  uint16_t filter;
+
+  /**
+   * Reserved for alignment
+   */
+  uint16_t reserved;
+
   /**
    * Zone key.
    */
@@ -420,6 +437,17 @@ struct ZoneIterationStartMessage
    * Zone key.  All zeros for "all zones".
    */
   struct GNUNET_IDENTITY_PrivateKey zone;
+
+  /**
+   * Record set filter control flags.
+   * See GNUNET_NAMESTORE_Filter enum.
+   */
+  uint16_t filter;
+
+  /**
+   * Reserved for alignment
+   */
+  uint16_t reserved;
 };
 
 
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index 71d969022..51ee25acf 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -82,6 +82,11 @@ struct GNUNET_NAMESTORE_QueueEntry
    */
   GNUNET_NAMESTORE_RecordMonitor proc;
 
+  /**
+   * Function to call with the records we get back; or NULL.
+   */
+  GNUNET_NAMESTORE_RecordSetMonitor proc2;
+
   /**
    * Closure for @e proc.
    */
@@ -150,6 +155,11 @@ struct GNUNET_NAMESTORE_ZoneIterator
    */
   GNUNET_NAMESTORE_RecordMonitor proc;
 
+  /**
+   * The continuation to call with the results
+   */
+  GNUNET_NAMESTORE_RecordSetMonitor proc2;
+
   /**
    * Closure for @e proc.
    */
@@ -630,6 +640,9 @@ handle_record_result (void *cls, const struct 
RecordResultMessage *msg)
     {
       if (NULL != ze->proc)
         ze->proc (ze->proc_cls, &msg->private_key, name, rd_count, rd);
+      if (NULL != ze->proc2)
+        ze->proc2 (ze->proc_cls, &msg->private_key, name,
+                   rd_count, rd, GNUNET_TIME_absolute_ntoh (msg->expire));
       return;
     }
   }
@@ -1272,25 +1285,6 @@ GNUNET_NAMESTORE_zone_to_name (
 }
 
 
-/**
- * Starts a new zone iteration (used to periodically PUT all of our
- * records into our DHT). This MUST lock the struct GNUNET_NAMESTORE_Handle
- * for any other calls than #GNUNET_NAMESTORE_zone_iterator_next and
- * #GNUNET_NAMESTORE_zone_iteration_stop. @a proc will be called once
- * immediately, and then again after
- * #GNUNET_NAMESTORE_zone_iterator_next is invoked.
- *
- * @param h handle to the namestore
- * @param zone zone to access, NULL for all zones
- * @param error_cb function to call on error (i.e. disconnect)
- * @param error_cb_cls closure for @a error_cb
- * @param proc function to call on each name from the zone; it
- *        will be called repeatedly with a value (if available)
- * @param proc_cls closure for @a proc
- * @param finish_cb function to call on completion
- * @param finish_cb_cls closure for @a finish_cb
- * @return an iterator handle to use for iteration
- */
 struct GNUNET_NAMESTORE_ZoneIterator *
 GNUNET_NAMESTORE_zone_iteration_start (
   struct GNUNET_NAMESTORE_Handle *h,
@@ -1332,15 +1326,50 @@ GNUNET_NAMESTORE_zone_iteration_start (
   return it;
 }
 
+struct GNUNET_NAMESTORE_ZoneIterator *
+GNUNET_NAMESTORE_zone_iteration_start2 (
+  struct GNUNET_NAMESTORE_Handle *h,
+  const struct GNUNET_IDENTITY_PrivateKey *zone,
+  GNUNET_SCHEDULER_TaskCallback error_cb,
+  void *error_cb_cls,
+  GNUNET_NAMESTORE_RecordSetMonitor proc,
+  void *proc_cls,
+  GNUNET_SCHEDULER_TaskCallback finish_cb,
+  void *finish_cb_cls,
+  enum GNUNET_GNSRECORD_Filter filter)
+{
+  struct GNUNET_NAMESTORE_ZoneIterator *it;
+  struct GNUNET_MQ_Envelope *env;
+  struct ZoneIterationStartMessage *msg;
+  uint32_t rid;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_START message\n");
+  rid = get_op_id (h);
+  it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
+  it->h = h;
+  it->error_cb = error_cb;
+  it->error_cb_cls = error_cb_cls;
+  it->finish_cb = finish_cb;
+  it->finish_cb_cls = finish_cb_cls;
+  it->proc2 = proc;
+  it->proc_cls = proc_cls;
+  it->op_id = rid;
+  if (NULL != zone)
+    it->zone = *zone;
+  GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it);
+  env = GNUNET_MQ_msg (msg, 
GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
+  msg->gns_header.r_id = htonl (rid);
+  msg->filter = htons ((uint16_t) filter);
+  if (NULL != zone)
+    msg->zone = *zone;
+  if (NULL == h->mq)
+    it->env = env;
+  else
+    GNUNET_MQ_send (h->mq, env);
+  return it;
+}
+
 
-/**
- * Calls the record processor specified in 
#GNUNET_NAMESTORE_zone_iteration_start
- * for the next record.
- *
- * @param it the iterator
- * @param limit number of records to return to the iterator in one shot
- *         (before #GNUNET_NAMESTORE_zone_iterator_next is to be called again)
- */
 void
 GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it,
                                      uint64_t limit)
diff --git a/src/namestore/namestore_api_monitor.c 
b/src/namestore/namestore_api_monitor.c
index 6670e54ce..968d7ed58 100644
--- a/src/namestore/namestore_api_monitor.c
+++ b/src/namestore/namestore_api_monitor.c
@@ -64,6 +64,16 @@ struct GNUNET_NAMESTORE_ZoneMonitor
    */
   GNUNET_NAMESTORE_RecordMonitor monitor;
 
+  /**
+   * Function to call on events.
+   */
+  GNUNET_NAMESTORE_RecordSetMonitor monitor2;
+
+  /**
+   * Record set filter for this monitor
+   */
+  enum GNUNET_GNSRECORD_Filter filter;
+
   /**
    * Closure for @e monitor.
    */
@@ -213,7 +223,11 @@ handle_result (void *cls, const struct RecordResultMessage 
*lrm)
     GNUNET_assert (
       GNUNET_OK ==
       GNUNET_GNSRECORD_records_deserialize (rd_len, rd_ser_tmp, rd_count, rd));
-    zm->monitor (zm->monitor_cls, &lrm->private_key, name_tmp, rd_count, rd);
+    if (NULL != zm->monitor2)
+      zm->monitor2 (zm->monitor_cls, &lrm->private_key, name_tmp,
+                    rd_count, rd, GNUNET_TIME_absolute_ntoh (lrm->expire));
+    else
+      zm->monitor (zm->monitor_cls, &lrm->private_key, name_tmp, rd_count, rd);
   }
 }
 
@@ -272,33 +286,11 @@ reconnect (struct GNUNET_NAMESTORE_ZoneMonitor *zm)
   env = GNUNET_MQ_msg (sm, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START);
   sm->iterate_first = htonl (zm->iterate_first);
   sm->zone = zm->zone;
+  sm->filter = htons ((uint16_t) zm->filter);
   GNUNET_MQ_send (zm->mq, env);
 }
 
 
-/**
- * Begin monitoring a zone for changes.  If @a iterate_first is set,
- * we Will first call the @a monitor function on all existing records
- * in the selected zone(s).  In any case, we will call @a sync and
- * afterwards call @a monitor whenever a record changes.
- *
- * @param cfg configuration to use to connect to namestore
- * @param zone zone to monitor
- * @param iterate_first #GNUNET_YES to first iterate over all existing records,
- *                      #GNUNET_NO to only return changes that happen from now
- * on
- * @param error_cb function to call on error (i.e. disconnect); note that
- *         unlike the other error callbacks in this API, a call to this
- *         function does NOT destroy the monitor handle, it merely signals
- *         that monitoring is down. You need to still explicitly call
- *         #GNUNET_NAMESTORE_zone_monitor_stop().
- * @param error_cb_cls closure for @a error_cb
- * @param monitor function to call on zone changes
- * @param monitor_cls closure for @a monitor
- * @param sync_cb function called when we're in sync with the namestore
- * @param cls closure for @a sync_cb
- * @return handle to stop monitoring
- */
 struct GNUNET_NAMESTORE_ZoneMonitor *
 GNUNET_NAMESTORE_zone_monitor_start (
   const struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -333,6 +325,42 @@ GNUNET_NAMESTORE_zone_monitor_start (
   return zm;
 }
 
+struct GNUNET_NAMESTORE_ZoneMonitor *
+GNUNET_NAMESTORE_zone_monitor_start2 (
+  const struct GNUNET_CONFIGURATION_Handle *cfg,
+  const struct GNUNET_IDENTITY_PrivateKey *zone,
+  int iterate_first,
+  GNUNET_SCHEDULER_TaskCallback error_cb,
+  void *error_cb_cls,
+  GNUNET_NAMESTORE_RecordSetMonitor monitor,
+  void *monitor_cls,
+  GNUNET_SCHEDULER_TaskCallback sync_cb,
+  void *sync_cb_cls,
+  enum GNUNET_GNSRECORD_Filter filter)
+{
+  struct GNUNET_NAMESTORE_ZoneMonitor *zm;
+
+  zm = GNUNET_new (struct GNUNET_NAMESTORE_ZoneMonitor);
+  if (NULL != zone)
+    zm->zone = *zone;
+  zm->iterate_first = iterate_first;
+  zm->error_cb = error_cb;
+  zm->error_cb_cls = error_cb_cls;
+  zm->monitor2 = monitor;
+  zm->monitor_cls = monitor_cls;
+  zm->sync_cb = sync_cb;
+  zm->sync_cb_cls = sync_cb_cls;
+  zm->cfg = cfg;
+  zm->filter = filter;
+  reconnect (zm);
+  if (NULL == zm->mq)
+  {
+    GNUNET_free (zm);
+    return NULL;
+  }
+  return zm;
+}
+
 
 /**
  * Calls the monitor processor specified in 
#GNUNET_NAMESTORE_zone_monitor_start
diff --git a/src/zonemaster/gnunet-service-zonemaster-monitor.c 
b/src/zonemaster/gnunet-service-zonemaster-monitor.c
index 748a0f342..08749bede 100644
--- a/src/zonemaster/gnunet-service-zonemaster-monitor.c
+++ b/src/zonemaster/gnunet-service-zonemaster-monitor.c
@@ -273,19 +273,17 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey 
*key,
  * @param label label of the records; NULL on disconnect
  * @param rd_count number of entries in @a rd array, 0 if label was deleted
  * @param rd array of records with data to store
+ * @param expire expiration of this record set
  */
 static void
 handle_monitor_event (void *cls,
                       const struct GNUNET_IDENTITY_PrivateKey *zone,
                       const char *label,
                       unsigned int rd_count,
-                      const struct GNUNET_GNSRECORD_Data *rd)
+                      const struct GNUNET_GNSRECORD_Data *rd,
+                      struct GNUNET_TIME_Absolute expire)
 {
-  struct GNUNET_GNSRECORD_Data rd_public[rd_count];
-  unsigned int rd_public_count;
   struct DhtPutActivity *ma;
-  struct GNUNET_TIME_Absolute expire;
-  char *emsg;
 
   (void) cls;
   GNUNET_STATISTICS_update (statistics,
@@ -296,24 +294,7 @@ handle_monitor_event (void *cls,
               "Received %u records for label `%s' via namestore monitor\n",
               rd_count,
               label);
-  /* filter out records that are not public, and convert to
-     absolute expiration time. */
-  if (GNUNET_OK != GNUNET_GNSRECORD_convert_records_for_export (label,
-                                                                rd,
-                                                                rd_count,
-                                                                rd_public,
-                                                                
&rd_public_count,
-                                                                &expire,
-                                                                &emsg))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Zonemaster-monitor failed: %s\n", emsg);
-    GNUNET_free (emsg);
-    GNUNET_NAMESTORE_zone_monitor_next (zmon,
-                                        1);
-    return;   /* nothing to do */
-  }
-  if (0 == rd_public_count)
+  if (0 == rd_count)
   {
     GNUNET_NAMESTORE_zone_monitor_next (zmon,
                                         1);
@@ -323,8 +304,8 @@ handle_monitor_event (void *cls,
   ma->start_date = GNUNET_TIME_absolute_get ();
   ma->ph = perform_dht_put (zone,
                             label,
-                            rd_public,
-                            rd_public_count,
+                            rd,
+                            rd_count,
                             expire,
                             ma);
   if (NULL == ma->ph)
@@ -427,15 +408,16 @@ run (void *cls,
   /* Schedule periodic put for our records. */
   statistics = GNUNET_STATISTICS_create ("zonemaster-mon",
                                          c);
-  zmon = GNUNET_NAMESTORE_zone_monitor_start (c,
-                                              NULL,
-                                              GNUNET_NO,
-                                              &handle_monitor_error,
-                                              NULL,
-                                              &handle_monitor_event,
-                                              NULL,
-                                              NULL /* sync_cb */,
-                                              NULL);
+  zmon = GNUNET_NAMESTORE_zone_monitor_start2 (c,
+                                               NULL,
+                                               GNUNET_NO,
+                                               &handle_monitor_error,
+                                               NULL,
+                                               &handle_monitor_event,
+                                               NULL,
+                                               NULL /* sync_cb */,
+                                               NULL,
+                                               
GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE);
   GNUNET_NAMESTORE_zone_monitor_next (zmon,
                                       NAMESTORE_QUEUE_LIMIT - 1);
   GNUNET_break (NULL != zmon);
diff --git a/src/zonemaster/gnunet-service-zonemaster.c 
b/src/zonemaster/gnunet-service-zonemaster.c
index c6b86bf71..dba1b24ce 100644
--- a/src/zonemaster/gnunet-service-zonemaster.c
+++ b/src/zonemaster/gnunet-service-zonemaster.c
@@ -683,46 +683,28 @@ put_gns_record (void *cls,
                 const struct GNUNET_IDENTITY_PrivateKey *key,
                 const char *label,
                 unsigned int rd_count,
-                const struct GNUNET_GNSRECORD_Data *rd)
+                const struct GNUNET_GNSRECORD_Data *rd,
+                struct GNUNET_TIME_Absolute expire)
 {
-  struct GNUNET_GNSRECORD_Data rd_public[rd_count];
-  unsigned int rd_public_count;
   struct DhtPutActivity *ma;
-  struct GNUNET_TIME_Absolute expire;
-  char *emsg;
 
   (void) cls;
   ns_iteration_left--;
-  if (GNUNET_OK != GNUNET_GNSRECORD_convert_records_for_export (label,
-                                                                rd,
-                                                                rd_count,
-                                                                rd_public,
-                                                                
&rd_public_count,
-                                                                &expire,
-                                                                &emsg))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Record set inconsistent, moving to next record set: %s\n",
-                emsg);
-    GNUNET_free (emsg);
-    check_zone_namestore_next ();
-    return;
-  }
-  if (0 == rd_public_count)
+  if (0 == rd_count)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Record set empty, moving to next record set\n");
     check_zone_namestore_next ();
     return;
   }
-  for (unsigned int i = 0; i < rd_public_count; i++)
+  for (unsigned int i = 0; i < rd_count; i++)
   {
-    if (0 != (rd_public[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
+    if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
     {
       /* GNUNET_GNSRECORD_block_create will convert to absolute time;
          we just need to adjust our iteration frequency */
       min_relative_record_time.rel_value_us =
-        GNUNET_MIN (rd_public[i].expiration_time,
+        GNUNET_MIN (rd[i].expiration_time,
                     min_relative_record_time.rel_value_us);
     }
   }
@@ -736,8 +718,8 @@ put_gns_record (void *cls,
   ma->start_date = GNUNET_TIME_absolute_get ();
   ma->ph = perform_dht_put (key,
                             label,
-                            rd_public,
-                            rd_public_count,
+                            rd,
+                            rd_count,
                             expire,
                             ma);
   put_cnt++;
@@ -793,14 +775,15 @@ publish_zone_dht_start (void *cls)
   GNUNET_assert (NULL == namestore_iter);
   ns_iteration_left = 1;
   namestore_iter
-    = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle,
-                                             NULL, /* All zones */
-                                             &zone_iteration_error,
-                                             NULL,
-                                             &put_gns_record,
-                                             NULL,
-                                             &zone_iteration_finished,
-                                             NULL);
+    = GNUNET_NAMESTORE_zone_iteration_start2 (namestore_handle,
+                                              NULL, /* All zones */
+                                              &zone_iteration_error,
+                                              NULL,
+                                              &put_gns_record,
+                                              NULL,
+                                              &zone_iteration_finished,
+                                              NULL,
+                                              
GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE);
   GNUNET_assert (NULL != namestore_iter);
 }
 

-- 
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]