aboutsummaryrefslogtreecommitdiff
path: root/src/namestore/gnunet-service-namestore.c
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/gnunet-service-namestore.c
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/gnunet-service-namestore.c')
-rw-r--r--src/namestore/gnunet-service-namestore.c144
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 */
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);