aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-09-28 14:05:01 +0900
committerMartin Schanzenbach <schanzen@gnunet.org>2022-09-28 14:05:01 +0900
commit3ec2b451f938398eb4d2f92603f0659c26f6675c (patch)
tree03f34b6819b1422ad8da2e566908748e87cf9975 /src/namestore
parent64480e6f4e07743a5fd20389eef92e0e9eadc563 (diff)
downloadgnunet-3ec2b451f938398eb4d2f92603f0659c26f6675c.tar.gz
gnunet-3ec2b451f938398eb4d2f92603f0659c26f6675c.zip
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.
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/gnunet-service-namestore.c144
-rw-r--r--src/namestore/namestore.h28
-rw-r--r--src/namestore/namestore_api.c83
-rw-r--r--src/namestore/namestore_api_monitor.c76
4 files changed, 241 insertions, 90 deletions
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
@@ -85,6 +85,11 @@ struct ZoneIteration
85 struct GNUNET_IDENTITY_PrivateKey zone; 85 struct GNUNET_IDENTITY_PrivateKey zone;
86 86
87 /** 87 /**
88 * The record set filter
89 */
90 enum GNUNET_GNSRECORD_Filter filter;
91
92 /**
88 * Last sequence number in the zone iteration used to address next 93 * Last sequence number in the zone iteration used to address next
89 * result of the zone iteration in the store 94 * result of the zone iteration in the store
90 * 95 *
@@ -181,6 +186,11 @@ struct ZoneMonitor
181 struct GNUNET_IDENTITY_PrivateKey zone; 186 struct GNUNET_IDENTITY_PrivateKey zone;
182 187
183 /** 188 /**
189 * The record set filter
190 */
191 enum GNUNET_GNSRECORD_Filter filter;
192
193 /**
184 * Task active during initial iteration. 194 * Task active during initial iteration.
185 */ 195 */
186 struct GNUNET_SCHEDULER_Task *task; 196 struct GNUNET_SCHEDULER_Task *task;
@@ -717,38 +727,63 @@ merge_with_nick_records (const struct GNUNET_GNSRECORD_Data *nick_rd,
717 * @param name name 727 * @param name name
718 * @param rd_count number of records in @a rd 728 * @param rd_count number of records in @a rd
719 * @param rd array of records 729 * @param rd array of records
730 * @param filter record set filter
720 */ 731 */
721static void 732static void
722send_lookup_response (struct NamestoreClient *nc, 733send_lookup_response_with_filter (struct NamestoreClient *nc,
723 uint32_t request_id, 734 uint32_t request_id,
724 const struct GNUNET_IDENTITY_PrivateKey *zone_key, 735 const struct
725 const char *name, 736 GNUNET_IDENTITY_PrivateKey *zone_key,
726 unsigned int rd_count, 737 const char *name,
727 const struct GNUNET_GNSRECORD_Data *rd) 738 unsigned int rd_count,
739 const struct GNUNET_GNSRECORD_Data *rd,
740 enum GNUNET_GNSRECORD_Filter filter)
728{ 741{
729 struct GNUNET_MQ_Envelope *env; 742 struct GNUNET_MQ_Envelope *env;
730 struct RecordResultMessage *zir_msg; 743 struct RecordResultMessage *zir_msg;
731 struct GNUNET_GNSRECORD_Data *nick; 744 struct GNUNET_GNSRECORD_Data *nick;
732 struct GNUNET_GNSRECORD_Data *res; 745 struct GNUNET_GNSRECORD_Data *res;
746 struct GNUNET_GNSRECORD_Data rd_nf[rd_count];
747 struct GNUNET_TIME_Absolute block_exp = GNUNET_TIME_UNIT_ZERO_ABS;;
733 unsigned int res_count; 748 unsigned int res_count;
749 unsigned int rd_nf_count;
734 size_t name_len; 750 size_t name_len;
735 ssize_t rd_ser_len; 751 ssize_t rd_ser_len;
736 char *name_tmp; 752 char *name_tmp;
737 char *rd_ser; 753 char *rd_ser;
754 char *emsg;
738 755
739 nick = get_nick_record (nc, zone_key); 756 nick = get_nick_record (nc, zone_key);
740 GNUNET_assert (-1 != GNUNET_GNSRECORD_records_get_size (rd_count, rd)); 757 GNUNET_assert (-1 != GNUNET_GNSRECORD_records_get_size (rd_count, rd));
741 758
759 if (GNUNET_OK != GNUNET_GNSRECORD_normalize_record_set (name,
760 rd,
761 rd_count,
762 rd_nf,
763 &rd_nf_count,
764 &block_exp,
765 filter,
766 &emsg))
767 {
768 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
769 GNUNET_free (emsg);
770 GNUNET_assert (0);
771 }
772
773 /**
774 * FIXME if we ever support GNUNET_NAMESTORE_OMIT_PUBLIC,
775 * we need to omit adding this public record here
776 */
742 if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT))) 777 if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
743 { 778 {
744 nick->flags = 779 nick->flags =
745 (nick->flags | GNUNET_GNSRECORD_RF_PRIVATE) ^ GNUNET_GNSRECORD_RF_PRIVATE; 780 (nick->flags | GNUNET_GNSRECORD_RF_PRIVATE) ^ GNUNET_GNSRECORD_RF_PRIVATE;
746 merge_with_nick_records (nick, rd_count, rd, &res_count, &res); 781 merge_with_nick_records (nick, rd_nf_count, rd_nf, &res_count, &res);
747 } 782 }
748 else 783 else
749 { 784 {
750 res_count = rd_count; 785 res_count = rd_nf_count;
751 res = (struct GNUNET_GNSRECORD_Data *) rd; 786 res = (struct GNUNET_GNSRECORD_Data *) rd_nf;
752 } 787 }
753 if (NULL != nick) 788 if (NULL != nick)
754 GNUNET_free (nick); 789 GNUNET_free (nick);
@@ -782,6 +817,7 @@ send_lookup_response (struct NamestoreClient *nc,
782 zir_msg->rd_count = htons (res_count); 817 zir_msg->rd_count = htons (res_count);
783 zir_msg->rd_len = htons ((uint16_t) rd_ser_len); 818 zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
784 zir_msg->private_key = *zone_key; 819 zir_msg->private_key = *zone_key;
820 zir_msg->expire = GNUNET_TIME_absolute_hton (block_exp);
785 name_tmp = (char *) &zir_msg[1]; 821 name_tmp = (char *) &zir_msg[1];
786 GNUNET_memcpy (name_tmp, name, name_len); 822 GNUNET_memcpy (name_tmp, name, name_len);
787 rd_ser = &name_tmp[name_len]; 823 rd_ser = &name_tmp[name_len];
@@ -796,10 +832,33 @@ send_lookup_response (struct NamestoreClient *nc,
796 1, 832 1,
797 GNUNET_NO); 833 GNUNET_NO);
798 GNUNET_MQ_send (nc->mq, env); 834 GNUNET_MQ_send (nc->mq, env);
799 if (rd != res) 835 if (rd_nf != res)
800 GNUNET_free (res); 836 GNUNET_free (res);
801} 837}
802 838
839/**
840 * Generate a `struct LookupNameResponseMessage` and send it to the
841 * given client using the given notification context.
842 *
843 * @param nc client to unicast to
844 * @param request_id request ID to use
845 * @param zone_key zone key of the zone
846 * @param name name
847 * @param rd_count number of records in @a rd
848 * @param rd array of records
849 */
850static void
851send_lookup_response (struct NamestoreClient *nc,
852 uint32_t request_id,
853 const struct
854 GNUNET_IDENTITY_PrivateKey *zone_key,
855 const char *name,
856 unsigned int rd_count,
857 const struct GNUNET_GNSRECORD_Data *rd)
858{
859 send_lookup_response_with_filter (nc, request_id, zone_key, name,
860 rd_count, rd, GNUNET_GNSRECORD_FILTER_NONE);
861}
803 862
804/** 863/**
805 * Send response to the store request to the client. 864 * Send response to the store request to the client.
@@ -995,7 +1054,7 @@ refresh_block (struct NamestoreClient *nc,
995 cop->nc = nc; 1054 cop->nc = nc;
996 cop->zi = zi; 1055 cop->zi = zi;
997 if (NULL != zi) 1056 if (NULL != zi)
998 zi->cache_ops ++; 1057 zi->cache_ops++;
999 cop->rid = rid; 1058 cop->rid = rid;
1000 GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop); 1059 GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop);
1001 cop->qe = GNUNET_NAMECACHE_block_cache (namecache, 1060 cop->qe = GNUNET_NAMECACHE_block_cache (namecache,
@@ -1081,12 +1140,13 @@ continue_store_activity (struct StoreActivity *sa)
1081 "Notifying monitor about changes under label `%s'\n", 1140 "Notifying monitor about changes under label `%s'\n",
1082 sa->conv_name); 1141 sa->conv_name);
1083 zm->limit--; 1142 zm->limit--;
1084 send_lookup_response (zm->nc, 1143 send_lookup_response_with_filter (zm->nc,
1085 0, 1144 0,
1086 &rp_msg->private_key, 1145 &rp_msg->private_key,
1087 sa->conv_name, 1146 sa->conv_name,
1088 rd_count, 1147 rd_count,
1089 rd); 1148 rd,
1149 zm->filter);
1090 sa->zm_pos = zm->next; 1150 sa->zm_pos = zm->next;
1091 } 1151 }
1092 /* great, done with the monitors, unpack (again) for refresh_block operation */ 1152 /* 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)
1454 if (GNUNET_YES == rlc.found) 1514 if (GNUNET_YES == rlc.found)
1455 llr_msg->found = htons (GNUNET_YES); 1515 llr_msg->found = htons (GNUNET_YES);
1456 else if (GNUNET_SYSERR == res) 1516 else if (GNUNET_SYSERR == res)
1457 llr_msg->found = htons (GNUNET_SYSERR); 1517 llr_msg->found = htons (GNUNET_SYSERR);
1458 else 1518 else
1459 llr_msg->found = htons (GNUNET_NO); 1519 llr_msg->found = htons (GNUNET_NO);
1460 GNUNET_memcpy (&llr_msg[1], conv_name, name_len); 1520 GNUNET_memcpy (&llr_msg[1], conv_name, name_len);
@@ -1531,13 +1591,15 @@ get_block_exp_existing (void *cls,
1531 unsigned int rd_pub_count; 1591 unsigned int rd_pub_count;
1532 char *emsg; 1592 char *emsg;
1533 1593
1534 if (GNUNET_OK != GNUNET_GNSRECORD_convert_records_for_export (label, 1594 if (GNUNET_OK !=
1535 rd, 1595 GNUNET_GNSRECORD_normalize_record_set (label,
1536 rd_count, 1596 rd,
1537 rd_pub, 1597 rd_count,
1538 &rd_pub_count, 1598 rd_pub,
1539 exp, 1599 &rd_pub_count,
1540 &emsg)) 1600 exp,
1601 GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE,
1602 &emsg))
1541 { 1603 {
1542 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1604 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1543 "%s\n", emsg); 1605 "%s\n", emsg);
@@ -1673,14 +1735,15 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1673 have_nick = GNUNET_YES; 1735 have_nick = GNUNET_YES;
1674 } 1736 }
1675 } 1737 }
1676 if (GNUNET_OK != GNUNET_GNSRECORD_normalize_record_set (conv_name, 1738 if (GNUNET_OK !=
1677 rd_clean, 1739 GNUNET_GNSRECORD_normalize_record_set (conv_name,
1678 rd_clean_off, 1740 rd_clean,
1679 rd_nf, 1741 rd_clean_off,
1680 &rd_nf_count, 1742 rd_nf,
1681 &new_block_exp, 1743 &rd_nf_count,
1682 GNUNET_YES, 1744 &new_block_exp,
1683 &emsg)) 1745 GNUNET_GNSRECORD_FILTER_NONE,
1746 &emsg))
1684 { 1747 {
1685 send_store_response (nc, GNUNET_SYSERR, emsg, rid); 1748 send_store_response (nc, GNUNET_SYSERR, emsg, rid);
1686 GNUNET_free (emsg); 1749 GNUNET_free (emsg);
@@ -1991,12 +2054,13 @@ zone_iterate_proc (void *cls,
1991 } 2054 }
1992 proc->limit--; 2055 proc->limit--;
1993 proc->zi->seq = seq; 2056 proc->zi->seq = seq;
1994 send_lookup_response (proc->zi->nc, 2057 send_lookup_response_with_filter (proc->zi->nc,
1995 proc->zi->request_id, 2058 proc->zi->request_id,
1996 zone_key, 2059 zone_key,
1997 name, 2060 name,
1998 rd_count, 2061 rd_count,
1999 rd); 2062 rd,
2063 proc->zi->filter);
2000 2064
2001 2065
2002 do_refresh_block = GNUNET_NO; 2066 do_refresh_block = GNUNET_NO;
@@ -2077,6 +2141,7 @@ handle_iteration_start (void *cls,
2077 "Received ZONE_ITERATION_START message\n"); 2141 "Received ZONE_ITERATION_START message\n");
2078 zi = GNUNET_new (struct ZoneIteration); 2142 zi = GNUNET_new (struct ZoneIteration);
2079 zi->request_id = ntohl (zis_msg->gns_header.r_id); 2143 zi->request_id = ntohl (zis_msg->gns_header.r_id);
2144 zi->filter = ntohs (zis_msg->filter);
2080 zi->offset = 0; 2145 zi->offset = 0;
2081 zi->nc = nc; 2146 zi->nc = nc;
2082 zi->zone = zis_msg->zone; 2147 zi->zone = zis_msg->zone;
@@ -2281,6 +2346,7 @@ handle_monitor_start (void *cls, const struct ZoneMonitorStartMessage *zis_msg)
2281 zm->nc = nc; 2346 zm->nc = nc;
2282 zm->zone = zis_msg->zone; 2347 zm->zone = zis_msg->zone;
2283 zm->limit = 1; 2348 zm->limit = 1;
2349 zm->filter = ntohs (zis_msg->filter);
2284 zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first)); 2350 zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2285 GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, zm); 2351 GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, zm);
2286 GNUNET_SERVICE_client_mark_monitor (nc->client); 2352 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
@@ -280,6 +280,12 @@ struct RecordResultMessage
280 struct GNUNET_NAMESTORE_Header gns_header; 280 struct GNUNET_NAMESTORE_Header gns_header;
281 281
282 /** 282 /**
283 * Expiration time if the record result (if any).
284 * Takes TOMBSTONEs into account.
285 */
286 struct GNUNET_TIME_AbsoluteNBO expire;
287
288 /**
283 * Name length 289 * Name length
284 */ 290 */
285 uint16_t name_len GNUNET_PACKED; 291 uint16_t name_len GNUNET_PACKED;
@@ -376,6 +382,17 @@ struct ZoneMonitorStartMessage
376 uint32_t iterate_first GNUNET_PACKED; 382 uint32_t iterate_first GNUNET_PACKED;
377 383
378 /** 384 /**
385 * Record set filter control flags.
386 * See GNUNET_NAMESTORE_Filter enum.
387 */
388 uint16_t filter;
389
390 /**
391 * Reserved for alignment
392 */
393 uint16_t reserved;
394
395 /**
379 * Zone key. 396 * Zone key.
380 */ 397 */
381 struct GNUNET_IDENTITY_PrivateKey zone; 398 struct GNUNET_IDENTITY_PrivateKey zone;
@@ -420,6 +437,17 @@ struct ZoneIterationStartMessage
420 * Zone key. All zeros for "all zones". 437 * Zone key. All zeros for "all zones".
421 */ 438 */
422 struct GNUNET_IDENTITY_PrivateKey zone; 439 struct GNUNET_IDENTITY_PrivateKey zone;
440
441 /**
442 * Record set filter control flags.
443 * See GNUNET_NAMESTORE_Filter enum.
444 */
445 uint16_t filter;
446
447 /**
448 * Reserved for alignment
449 */
450 uint16_t reserved;
423}; 451};
424 452
425 453
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
@@ -83,6 +83,11 @@ struct GNUNET_NAMESTORE_QueueEntry
83 GNUNET_NAMESTORE_RecordMonitor proc; 83 GNUNET_NAMESTORE_RecordMonitor proc;
84 84
85 /** 85 /**
86 * Function to call with the records we get back; or NULL.
87 */
88 GNUNET_NAMESTORE_RecordSetMonitor proc2;
89
90 /**
86 * Closure for @e proc. 91 * Closure for @e proc.
87 */ 92 */
88 void *proc_cls; 93 void *proc_cls;
@@ -151,6 +156,11 @@ struct GNUNET_NAMESTORE_ZoneIterator
151 GNUNET_NAMESTORE_RecordMonitor proc; 156 GNUNET_NAMESTORE_RecordMonitor proc;
152 157
153 /** 158 /**
159 * The continuation to call with the results
160 */
161 GNUNET_NAMESTORE_RecordSetMonitor proc2;
162
163 /**
154 * Closure for @e proc. 164 * Closure for @e proc.
155 */ 165 */
156 void *proc_cls; 166 void *proc_cls;
@@ -630,6 +640,9 @@ handle_record_result (void *cls, const struct RecordResultMessage *msg)
630 { 640 {
631 if (NULL != ze->proc) 641 if (NULL != ze->proc)
632 ze->proc (ze->proc_cls, &msg->private_key, name, rd_count, rd); 642 ze->proc (ze->proc_cls, &msg->private_key, name, rd_count, rd);
643 if (NULL != ze->proc2)
644 ze->proc2 (ze->proc_cls, &msg->private_key, name,
645 rd_count, rd, GNUNET_TIME_absolute_ntoh (msg->expire));
633 return; 646 return;
634 } 647 }
635 } 648 }
@@ -1272,25 +1285,6 @@ GNUNET_NAMESTORE_zone_to_name (
1272} 1285}
1273 1286
1274 1287
1275/**
1276 * Starts a new zone iteration (used to periodically PUT all of our
1277 * records into our DHT). This MUST lock the struct GNUNET_NAMESTORE_Handle
1278 * for any other calls than #GNUNET_NAMESTORE_zone_iterator_next and
1279 * #GNUNET_NAMESTORE_zone_iteration_stop. @a proc will be called once
1280 * immediately, and then again after
1281 * #GNUNET_NAMESTORE_zone_iterator_next is invoked.
1282 *
1283 * @param h handle to the namestore
1284 * @param zone zone to access, NULL for all zones
1285 * @param error_cb function to call on error (i.e. disconnect)
1286 * @param error_cb_cls closure for @a error_cb
1287 * @param proc function to call on each name from the zone; it
1288 * will be called repeatedly with a value (if available)
1289 * @param proc_cls closure for @a proc
1290 * @param finish_cb function to call on completion
1291 * @param finish_cb_cls closure for @a finish_cb
1292 * @return an iterator handle to use for iteration
1293 */
1294struct GNUNET_NAMESTORE_ZoneIterator * 1288struct GNUNET_NAMESTORE_ZoneIterator *
1295GNUNET_NAMESTORE_zone_iteration_start ( 1289GNUNET_NAMESTORE_zone_iteration_start (
1296 struct GNUNET_NAMESTORE_Handle *h, 1290 struct GNUNET_NAMESTORE_Handle *h,
@@ -1332,15 +1326,50 @@ GNUNET_NAMESTORE_zone_iteration_start (
1332 return it; 1326 return it;
1333} 1327}
1334 1328
1329struct GNUNET_NAMESTORE_ZoneIterator *
1330GNUNET_NAMESTORE_zone_iteration_start2 (
1331 struct GNUNET_NAMESTORE_Handle *h,
1332 const struct GNUNET_IDENTITY_PrivateKey *zone,
1333 GNUNET_SCHEDULER_TaskCallback error_cb,
1334 void *error_cb_cls,
1335 GNUNET_NAMESTORE_RecordSetMonitor proc,
1336 void *proc_cls,
1337 GNUNET_SCHEDULER_TaskCallback finish_cb,
1338 void *finish_cb_cls,
1339 enum GNUNET_GNSRECORD_Filter filter)
1340{
1341 struct GNUNET_NAMESTORE_ZoneIterator *it;
1342 struct GNUNET_MQ_Envelope *env;
1343 struct ZoneIterationStartMessage *msg;
1344 uint32_t rid;
1345
1346 LOG (GNUNET_ERROR_TYPE_DEBUG, "Sending ZONE_ITERATION_START message\n");
1347 rid = get_op_id (h);
1348 it = GNUNET_new (struct GNUNET_NAMESTORE_ZoneIterator);
1349 it->h = h;
1350 it->error_cb = error_cb;
1351 it->error_cb_cls = error_cb_cls;
1352 it->finish_cb = finish_cb;
1353 it->finish_cb_cls = finish_cb_cls;
1354 it->proc2 = proc;
1355 it->proc_cls = proc_cls;
1356 it->op_id = rid;
1357 if (NULL != zone)
1358 it->zone = *zone;
1359 GNUNET_CONTAINER_DLL_insert_tail (h->z_head, h->z_tail, it);
1360 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START);
1361 msg->gns_header.r_id = htonl (rid);
1362 msg->filter = htons ((uint16_t) filter);
1363 if (NULL != zone)
1364 msg->zone = *zone;
1365 if (NULL == h->mq)
1366 it->env = env;
1367 else
1368 GNUNET_MQ_send (h->mq, env);
1369 return it;
1370}
1371
1335 1372
1336/**
1337 * Calls the record processor specified in #GNUNET_NAMESTORE_zone_iteration_start
1338 * for the next record.
1339 *
1340 * @param it the iterator
1341 * @param limit number of records to return to the iterator in one shot
1342 * (before #GNUNET_NAMESTORE_zone_iterator_next is to be called again)
1343 */
1344void 1373void
1345GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it, 1374GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it,
1346 uint64_t limit) 1375 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
@@ -65,6 +65,16 @@ struct GNUNET_NAMESTORE_ZoneMonitor
65 GNUNET_NAMESTORE_RecordMonitor monitor; 65 GNUNET_NAMESTORE_RecordMonitor monitor;
66 66
67 /** 67 /**
68 * Function to call on events.
69 */
70 GNUNET_NAMESTORE_RecordSetMonitor monitor2;
71
72 /**
73 * Record set filter for this monitor
74 */
75 enum GNUNET_GNSRECORD_Filter filter;
76
77 /**
68 * Closure for @e monitor. 78 * Closure for @e monitor.
69 */ 79 */
70 void *monitor_cls; 80 void *monitor_cls;
@@ -213,7 +223,11 @@ handle_result (void *cls, const struct RecordResultMessage *lrm)
213 GNUNET_assert ( 223 GNUNET_assert (
214 GNUNET_OK == 224 GNUNET_OK ==
215 GNUNET_GNSRECORD_records_deserialize (rd_len, rd_ser_tmp, rd_count, rd)); 225 GNUNET_GNSRECORD_records_deserialize (rd_len, rd_ser_tmp, rd_count, rd));
216 zm->monitor (zm->monitor_cls, &lrm->private_key, name_tmp, rd_count, rd); 226 if (NULL != zm->monitor2)
227 zm->monitor2 (zm->monitor_cls, &lrm->private_key, name_tmp,
228 rd_count, rd, GNUNET_TIME_absolute_ntoh (lrm->expire));
229 else
230 zm->monitor (zm->monitor_cls, &lrm->private_key, name_tmp, rd_count, rd);
217 } 231 }
218} 232}
219 233
@@ -272,33 +286,11 @@ reconnect (struct GNUNET_NAMESTORE_ZoneMonitor *zm)
272 env = GNUNET_MQ_msg (sm, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START); 286 env = GNUNET_MQ_msg (sm, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START);
273 sm->iterate_first = htonl (zm->iterate_first); 287 sm->iterate_first = htonl (zm->iterate_first);
274 sm->zone = zm->zone; 288 sm->zone = zm->zone;
289 sm->filter = htons ((uint16_t) zm->filter);
275 GNUNET_MQ_send (zm->mq, env); 290 GNUNET_MQ_send (zm->mq, env);
276} 291}
277 292
278 293
279/**
280 * Begin monitoring a zone for changes. If @a iterate_first is set,
281 * we Will first call the @a monitor function on all existing records
282 * in the selected zone(s). In any case, we will call @a sync and
283 * afterwards call @a monitor whenever a record changes.
284 *
285 * @param cfg configuration to use to connect to namestore
286 * @param zone zone to monitor
287 * @param iterate_first #GNUNET_YES to first iterate over all existing records,
288 * #GNUNET_NO to only return changes that happen from now
289 * on
290 * @param error_cb function to call on error (i.e. disconnect); note that
291 * unlike the other error callbacks in this API, a call to this
292 * function does NOT destroy the monitor handle, it merely signals
293 * that monitoring is down. You need to still explicitly call
294 * #GNUNET_NAMESTORE_zone_monitor_stop().
295 * @param error_cb_cls closure for @a error_cb
296 * @param monitor function to call on zone changes
297 * @param monitor_cls closure for @a monitor
298 * @param sync_cb function called when we're in sync with the namestore
299 * @param cls closure for @a sync_cb
300 * @return handle to stop monitoring
301 */
302struct GNUNET_NAMESTORE_ZoneMonitor * 294struct GNUNET_NAMESTORE_ZoneMonitor *
303GNUNET_NAMESTORE_zone_monitor_start ( 295GNUNET_NAMESTORE_zone_monitor_start (
304 const struct GNUNET_CONFIGURATION_Handle *cfg, 296 const struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -333,6 +325,42 @@ GNUNET_NAMESTORE_zone_monitor_start (
333 return zm; 325 return zm;
334} 326}
335 327
328struct GNUNET_NAMESTORE_ZoneMonitor *
329GNUNET_NAMESTORE_zone_monitor_start2 (
330 const struct GNUNET_CONFIGURATION_Handle *cfg,
331 const struct GNUNET_IDENTITY_PrivateKey *zone,
332 int iterate_first,
333 GNUNET_SCHEDULER_TaskCallback error_cb,
334 void *error_cb_cls,
335 GNUNET_NAMESTORE_RecordSetMonitor monitor,
336 void *monitor_cls,
337 GNUNET_SCHEDULER_TaskCallback sync_cb,
338 void *sync_cb_cls,
339 enum GNUNET_GNSRECORD_Filter filter)
340{
341 struct GNUNET_NAMESTORE_ZoneMonitor *zm;
342
343 zm = GNUNET_new (struct GNUNET_NAMESTORE_ZoneMonitor);
344 if (NULL != zone)
345 zm->zone = *zone;
346 zm->iterate_first = iterate_first;
347 zm->error_cb = error_cb;
348 zm->error_cb_cls = error_cb_cls;
349 zm->monitor2 = monitor;
350 zm->monitor_cls = monitor_cls;
351 zm->sync_cb = sync_cb;
352 zm->sync_cb_cls = sync_cb_cls;
353 zm->cfg = cfg;
354 zm->filter = filter;
355 reconnect (zm);
356 if (NULL == zm->mq)
357 {
358 GNUNET_free (zm);
359 return NULL;
360 }
361 return zm;
362}
363
336 364
337/** 365/**
338 * Calls the monitor processor specified in #GNUNET_NAMESTORE_zone_monitor_start 366 * Calls the monitor processor specified in #GNUNET_NAMESTORE_zone_monitor_start