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/gnunet-service-namestore.c | |
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/gnunet-service-namestore.c')
-rw-r--r-- | src/namestore/gnunet-service-namestore.c | 144 |
1 files changed, 105 insertions, 39 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); |