diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-09-28 14:05:01 +0900 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-09-28 14:05:01 +0900 |
commit | 3ec2b451f938398eb4d2f92603f0659c26f6675c (patch) | |
tree | 03f34b6819b1422ad8da2e566908748e87cf9975 /src/namestore | |
parent | 64480e6f4e07743a5fd20389eef92e0e9eadc563 (diff) | |
download | gnunet-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.c | 144 | ||||
-rw-r--r-- | src/namestore/namestore.h | 28 | ||||
-rw-r--r-- | src/namestore/namestore_api.c | 83 | ||||
-rw-r--r-- | src/namestore/namestore_api_monitor.c | 76 |
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 | */ |
721 | static void | 732 | static void |
722 | send_lookup_response (struct NamestoreClient *nc, | 733 | send_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 | */ | ||
850 | static void | ||
851 | send_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 | */ | ||
1294 | struct GNUNET_NAMESTORE_ZoneIterator * | 1288 | struct GNUNET_NAMESTORE_ZoneIterator * |
1295 | GNUNET_NAMESTORE_zone_iteration_start ( | 1289 | GNUNET_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 | ||
1329 | struct GNUNET_NAMESTORE_ZoneIterator * | ||
1330 | GNUNET_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 | */ | ||
1344 | void | 1373 | void |
1345 | GNUNET_NAMESTORE_zone_iterator_next (struct GNUNET_NAMESTORE_ZoneIterator *it, | 1374 | GNUNET_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 | */ | ||
302 | struct GNUNET_NAMESTORE_ZoneMonitor * | 294 | struct GNUNET_NAMESTORE_ZoneMonitor * |
303 | GNUNET_NAMESTORE_zone_monitor_start ( | 295 | GNUNET_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 | ||
328 | struct GNUNET_NAMESTORE_ZoneMonitor * | ||
329 | GNUNET_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 |