[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: NAMESTORE: Allow service-side record set filtering. Fixes #7193,
gnunet <=