aboutsummaryrefslogtreecommitdiff
path: root/src/zonemaster
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-02-05 21:37:40 +0100
committerMartin Schanzenbach <schanzen@gnunet.org>2022-02-05 21:37:40 +0100
commit3ab4b92da2ff2aeb135c2ddf2a51eeec93e33468 (patch)
tree3b35806d183f51706e2b16be204970c7bf859eda /src/zonemaster
parenta3563c94b702719db253b05dab99b2783e35a0de (diff)
downloadgnunet-3ab4b92da2ff2aeb135c2ddf2a51eeec93e33468.tar.gz
gnunet-3ab4b92da2ff2aeb135c2ddf2a51eeec93e33468.zip
-refactor zonemaster
Diffstat (limited to 'src/zonemaster')
-rw-r--r--src/zonemaster/Makefile.am6
-rw-r--r--src/zonemaster/gnunet-service-zonemaster-monitor.c153
-rw-r--r--src/zonemaster/gnunet-service-zonemaster.c172
-rw-r--r--src/zonemaster/zonemaster_misc.c132
-rw-r--r--src/zonemaster/zonemaster_misc.h62
5 files changed, 259 insertions, 266 deletions
diff --git a/src/zonemaster/Makefile.am b/src/zonemaster/Makefile.am
index f2d569c75..d561d75fe 100644
--- a/src/zonemaster/Makefile.am
+++ b/src/zonemaster/Makefile.am
@@ -20,7 +20,8 @@ libexec_PROGRAMS = \
20 gnunet-service-zonemaster-monitor 20 gnunet-service-zonemaster-monitor
21 21
22gnunet_service_zonemaster_SOURCES = \ 22gnunet_service_zonemaster_SOURCES = \
23 gnunet-service-zonemaster.c 23 gnunet-service-zonemaster.c \
24 zonemaster_misc.c zonemaster_misc.h
24gnunet_service_zonemaster_LDADD = \ 25gnunet_service_zonemaster_LDADD = \
25 $(top_builddir)/src/dht/libgnunetdht.la \ 26 $(top_builddir)/src/dht/libgnunetdht.la \
26 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ 27 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
@@ -32,7 +33,8 @@ gnunet_service_zonemaster_LDADD = \
32 33
33 34
34gnunet_service_zonemaster_monitor_SOURCES = \ 35gnunet_service_zonemaster_monitor_SOURCES = \
35 gnunet-service-zonemaster-monitor.c 36 gnunet-service-zonemaster-monitor.c \
37 zonemaster_misc.c zonemaster_misc.h
36gnunet_service_zonemaster_monitor_LDADD = \ 38gnunet_service_zonemaster_monitor_LDADD = \
37 $(top_builddir)/src/dht/libgnunetdht.la \ 39 $(top_builddir)/src/dht/libgnunetdht.la \
38 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ 40 $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
diff --git a/src/zonemaster/gnunet-service-zonemaster-monitor.c b/src/zonemaster/gnunet-service-zonemaster-monitor.c
index b51d1cb97..dcacec60f 100644
--- a/src/zonemaster/gnunet-service-zonemaster-monitor.c
+++ b/src/zonemaster/gnunet-service-zonemaster-monitor.c
@@ -28,7 +28,7 @@
28#include "gnunet_dht_service.h" 28#include "gnunet_dht_service.h"
29#include "gnunet_namestore_service.h" 29#include "gnunet_namestore_service.h"
30#include "gnunet_statistics_service.h" 30#include "gnunet_statistics_service.h"
31 31#include "zonemaster_misc.h"
32 32
33#define LOG_STRERROR_FILE(kind, syscall, \ 33#define LOG_STRERROR_FILE(kind, syscall, \
34 filename) GNUNET_log_from_strerror_file (kind, "util", \ 34 filename) GNUNET_log_from_strerror_file (kind, "util", \
@@ -240,68 +240,6 @@ dht_put_monitor_continuation (void *cls)
240 240
241 241
242/** 242/**
243 * Convert namestore records from the internal format to that
244 * suitable for publication (removes private records, converts
245 * to absolute expiration time).
246 *
247 * @param rd input records
248 * @param rd_count size of the @a rd and @a rd_public arrays
249 * @param rd_public where to write the converted records
250 * @return number of records written to @a rd_public
251 */
252static unsigned int
253convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd,
254 unsigned int rd_count,
255 struct GNUNET_GNSRECORD_Data *rd_public,
256 struct GNUNET_TIME_Absolute *expiry)
257{
258 const struct GNUNET_GNSRECORD_TombstoneRecord *tombstone;
259 struct GNUNET_TIME_Absolute expiry_tombstone;
260 struct GNUNET_TIME_Absolute now;
261 unsigned int rd_public_count;
262
263 rd_public_count = 0;
264 tombstone = NULL;
265 now = GNUNET_TIME_absolute_get ();
266 for (unsigned int i = 0; i < rd_count; i++)
267 {
268 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
269 {
270 tombstone = rd[i].data;
271 continue;
272 }
273 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))
274 continue;
275 if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) &&
276 (rd[i].expiration_time < now.abs_value_us))
277 continue; /* record already expired, skip it */
278 rd_public[rd_public_count] = rd[i];
279 /* Make sure critical record types are published as such */
280 if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type))
281 rd_public[rd_public_count].flags |= GNUNET_GNSRECORD_RF_CRITICAL;
282 rd_public_count++;
283 }
284
285 *expiry = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count,
286 rd_public);
287
288 /* We need to check if the tombstone has an expiration in the fututre
289 * which would mean there was a block published under this label
290 * previously that is still valid. In this case we MUST NOT publish this
291 * block
292 */
293 if (NULL != tombstone)
294 {
295 expiry_tombstone = GNUNET_TIME_absolute_ntoh (tombstone->time_of_death);
296 if (GNUNET_TIME_absolute_cmp (*expiry,<=,expiry_tombstone))
297 return 0;
298 }
299
300 return rd_public_count;
301}
302
303
304/**
305 * Store GNS records in the DHT. 243 * Store GNS records in the DHT.
306 * 244 *
307 * @param key key of the zone 245 * @param key key of the zone
@@ -387,62 +325,6 @@ ts_store_cont (void *cls, int32_t success, const char *emsg)
387 325
388 326
389/** 327/**
390 * Update tombstone records.
391 *
392 * @param key key of the zone
393 * @param label label to store under
394 * @param rd_public public record data
395 * @param rd_public_count number of records in @a rd_public
396 * @param expire the expiration time for the tombstone
397 * @param ta handle for the put operation
398 * @return Namestore queue entry, NULL on error
399 */
400static struct GNUNET_NAMESTORE_QueueEntry *
401touch_tombstone (const struct GNUNET_IDENTITY_PrivateKey *key,
402 const char *label,
403 const struct GNUNET_GNSRECORD_Data *rd_original,
404 unsigned int rd_count_original,
405 const struct GNUNET_TIME_Absolute expire,
406 struct TombstoneActivity *ta)
407{
408 struct GNUNET_TIME_AbsoluteNBO exp_nbo;
409 struct GNUNET_GNSRECORD_Data rd[rd_count_original + 1];
410 int tombstone_exists = GNUNET_NO;
411 unsigned int rd_count;
412
413 exp_nbo = GNUNET_TIME_absolute_hton (expire);
414 for (rd_count = 0; rd_count < rd_count_original; rd_count++)
415 {
416 memcpy (&rd[rd_count], &rd_original[rd_count],
417 sizeof (struct GNUNET_GNSRECORD_Data));
418 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[rd_count].record_type)
419 {
420 rd[rd_count].data = &exp_nbo;
421 tombstone_exists = GNUNET_YES;
422 }
423 }
424 if (GNUNET_NO == tombstone_exists)
425 {
426 rd[rd_count].data = &exp_nbo;
427 rd[rd_count].data_size = sizeof (exp_nbo);
428 rd[rd_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
429 rd[rd_count].flags = GNUNET_GNSRECORD_RF_PRIVATE;
430 rd[rd_count].expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
431 rd_count++;
432 }
433 return GNUNET_NAMESTORE_records_store_ (namestore_handle,
434 key,
435 label,
436 rd_count,
437 rd,
438 GNUNET_YES,
439 &ts_store_cont,
440 ta);
441}
442
443
444
445/**
446 * Process a record that was stored in the namestore 328 * Process a record that was stored in the namestore
447 * (invoked by the monitor). 329 * (invoked by the monitor).
448 * 330 *
@@ -460,7 +342,9 @@ handle_monitor_event (void *cls,
460 const struct GNUNET_GNSRECORD_Data *rd) 342 const struct GNUNET_GNSRECORD_Data *rd)
461{ 343{
462 struct GNUNET_GNSRECORD_Data rd_public[rd_count]; 344 struct GNUNET_GNSRECORD_Data rd_public[rd_count];
345 struct GNUNET_GNSRECORD_Data rd_fresh[rd_count + 1];
463 unsigned int rd_public_count; 346 unsigned int rd_public_count;
347 unsigned int rd_fresh_count;
464 struct DhtPutActivity *ma; 348 struct DhtPutActivity *ma;
465 struct TombstoneActivity *ta; 349 struct TombstoneActivity *ta;
466 struct GNUNET_TIME_Absolute expire; 350 struct GNUNET_TIME_Absolute expire;
@@ -476,10 +360,10 @@ handle_monitor_event (void *cls,
476 label); 360 label);
477 /* filter out records that are not public, and convert to 361 /* filter out records that are not public, and convert to
478 absolute expiration time. */ 362 absolute expiration time. */
479 rd_public_count = convert_records_for_export (rd, 363 rd_public_count = ZMSTR_convert_records_for_export (rd,
480 rd_count, 364 rd_count,
481 rd_public, 365 rd_public,
482 &expire); 366 &expire);
483 if (0 == rd_public_count) 367 if (0 == rd_public_count)
484 { 368 {
485 GNUNET_NAMESTORE_zone_monitor_next (zmon, 369 GNUNET_NAMESTORE_zone_monitor_next (zmon,
@@ -495,12 +379,23 @@ handle_monitor_event (void *cls,
495 expire, 379 expire,
496 ma); 380 ma);
497 ta = GNUNET_new (struct TombstoneActivity); 381 ta = GNUNET_new (struct TombstoneActivity);
498 ta->ns_qe = touch_tombstone (zone, 382 ZMSTR_touch_tombstone (zone,
499 label, 383 label,
500 rd, 384 rd,
501 rd_count, 385 rd_count,
502 expire, 386 rd_fresh,
503 ta); 387 &rd_fresh_count,
388 expire);
389 ta->ns_qe = GNUNET_NAMESTORE_records_store_ (namestore_handle,
390 zone,
391 label,
392 rd_fresh_count,
393 rd_fresh,
394 GNUNET_YES,
395 &ts_store_cont,
396 ta);
397
398
504 GNUNET_CONTAINER_DLL_insert_tail (ta_head, 399 GNUNET_CONTAINER_DLL_insert_tail (ta_head,
505 ta_tail, 400 ta_tail,
506 ta); 401 ta);
diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c
index 3a8ac4be1..9f0de8a54 100644
--- a/src/zonemaster/gnunet-service-zonemaster.c
+++ b/src/zonemaster/gnunet-service-zonemaster.c
@@ -29,7 +29,7 @@
29#include "gnunet_dht_service.h" 29#include "gnunet_dht_service.h"
30#include "gnunet_namestore_service.h" 30#include "gnunet_namestore_service.h"
31#include "gnunet_statistics_service.h" 31#include "gnunet_statistics_service.h"
32 32#include "zonemaster_misc.h"
33 33
34#define LOG_STRERROR_FILE(kind, syscall, \ 34#define LOG_STRERROR_FILE(kind, syscall, \
35 filename) GNUNET_log_from_strerror_file (kind, "util", \ 35 filename) GNUNET_log_from_strerror_file (kind, "util", \
@@ -569,75 +569,6 @@ dht_put_continuation (void *cls)
569} 569}
570 570
571 571
572/**
573 * Convert namestore records from the internal format to that
574 * suitable for publication (removes private records, converts
575 * to absolute expiration time).
576 *
577 * @param rd input records
578 * @param rd_count size of the @a rd and @a rd_public arrays
579 * @param rd_public where to write the converted records
580 * @param expire the expiration of the block
581 * @return number of records written to @a rd_public
582 */
583static unsigned int
584convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd,
585 unsigned int rd_count,
586 struct GNUNET_GNSRECORD_Data *rd_public,
587 struct GNUNET_TIME_Absolute *expiry)
588{
589 const struct GNUNET_GNSRECORD_TombstoneRecord *tombstone;
590 struct GNUNET_TIME_Absolute expiry_tombstone;
591 struct GNUNET_TIME_Absolute now;
592 unsigned int rd_public_count;
593
594 rd_public_count = 0;
595 tombstone = NULL;
596 now = GNUNET_TIME_absolute_get ();
597 for (unsigned int i = 0; i < rd_count; i++)
598 {
599 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
600 {
601 tombstone = rd[i].data;
602 continue;
603 }
604 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))
605 continue;
606 if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) &&
607 (rd[i].expiration_time < now.abs_value_us))
608 continue; /* record already expired, skip it */
609 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
610 {
611 /* GNUNET_GNSRECORD_block_create will convert to absolute time;
612 we just need to adjust our iteration frequency */
613 min_relative_record_time.rel_value_us =
614 GNUNET_MIN (rd[i].expiration_time,
615 min_relative_record_time.rel_value_us);
616 }
617 rd_public[rd_public_count] = rd[i];
618 /* Make sure critical record types are published as such */
619 if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type))
620 rd_public[rd_public_count].flags |= GNUNET_GNSRECORD_RF_CRITICAL;
621 rd_public_count++;
622 }
623
624 *expiry = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count,
625 rd_public);
626
627 /* We need to check if the tombstone has an expiration in the fututre
628 * which would mean there was a block published under this label
629 * previously that is still valid. In this case we MUST NOT publish this
630 * block
631 */
632 if (NULL != tombstone)
633 {
634 expiry_tombstone = GNUNET_TIME_absolute_ntoh (tombstone->time_of_death);
635 if (GNUNET_TIME_absolute_cmp (*expiry,<=,expiry_tombstone))
636 return 0;
637 }
638 return rd_public_count;
639}
640
641 572
642/** 573/**
643 * Store GNS records in the DHT. 574 * Store GNS records in the DHT.
@@ -796,60 +727,6 @@ ts_store_cont (void *cls, int32_t success, const char *emsg)
796 727
797} 728}
798 729
799/**
800 * Update tombstone records.
801 *
802 * @param key key of the zone
803 * @param label label to store under
804 * @param rd_public public record data
805 * @param rd_public_count number of records in @a rd_public
806 * @param expire the expiration time for the tombstone
807 * @param ta handle for the put operation
808 * @return Namestore queue entry, NULL on error
809 */
810static struct GNUNET_NAMESTORE_QueueEntry *
811touch_tombstone (const struct GNUNET_IDENTITY_PrivateKey *key,
812 const char *label,
813 const struct GNUNET_GNSRECORD_Data *rd_original,
814 unsigned int rd_count_original,
815 const struct GNUNET_TIME_Absolute expire,
816 struct TombstoneActivity *ta)
817{
818 struct GNUNET_TIME_AbsoluteNBO exp_nbo;
819 struct GNUNET_GNSRECORD_Data rd[rd_count_original + 1];
820 int tombstone_exists = GNUNET_NO;
821 unsigned int rd_count;
822
823 exp_nbo = GNUNET_TIME_absolute_hton (expire);
824 for (rd_count = 0; rd_count < rd_count_original; rd_count++)
825 {
826 memcpy (&rd[rd_count], &rd_original[rd_count],
827 sizeof (struct GNUNET_GNSRECORD_Data));
828 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[rd_count].record_type)
829 {
830 rd[rd_count].data = &exp_nbo;
831 tombstone_exists = GNUNET_YES;
832 }
833 }
834 if (GNUNET_NO == tombstone_exists)
835 {
836 rd[rd_count].data = &exp_nbo;
837 rd[rd_count].data_size = sizeof (exp_nbo);
838 rd[rd_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
839 rd[rd_count].flags = GNUNET_GNSRECORD_RF_PRIVATE;
840 rd[rd_count].expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
841 rd_count++;
842 }
843 return GNUNET_NAMESTORE_records_store_ (namestore_handle,
844 key,
845 label,
846 rd_count,
847 rd,
848 GNUNET_YES,
849 &ts_store_cont,
850 ta);
851}
852
853 730
854/** 731/**
855 * Function used to put all records successively into the DHT. 732 * Function used to put all records successively into the DHT.
@@ -868,17 +745,19 @@ put_gns_record (void *cls,
868 const struct GNUNET_GNSRECORD_Data *rd) 745 const struct GNUNET_GNSRECORD_Data *rd)
869{ 746{
870 struct GNUNET_GNSRECORD_Data rd_public[rd_count]; 747 struct GNUNET_GNSRECORD_Data rd_public[rd_count];
748 struct GNUNET_GNSRECORD_Data rd_fresh[rd_count + 1];
871 unsigned int rd_public_count; 749 unsigned int rd_public_count;
750 unsigned int rd_fresh_count = 0;
872 struct DhtPutActivity *ma; 751 struct DhtPutActivity *ma;
873 struct TombstoneActivity *ta; 752 struct TombstoneActivity *ta;
874 struct GNUNET_TIME_Absolute expire; 753 struct GNUNET_TIME_Absolute expire;
875 754
876 (void) cls; 755 (void) cls;
877 ns_iteration_left--; 756 ns_iteration_left--;
878 rd_public_count = convert_records_for_export (rd, 757 rd_public_count = ZMSTR_convert_records_for_export (rd,
879 rd_count, 758 rd_count,
880 rd_public, 759 rd_public,
881 &expire); 760 &expire);
882 if (0 == rd_public_count) 761 if (0 == rd_public_count)
883 { 762 {
884 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 763 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -886,6 +765,19 @@ put_gns_record (void *cls,
886 check_zone_namestore_next (); 765 check_zone_namestore_next ();
887 return; 766 return;
888 } 767 }
768 for (unsigned int i = 0; i < rd_public_count; i++)
769 {
770 if (0 != (rd_public[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
771 {
772 /* GNUNET_GNSRECORD_block_create will convert to absolute time;
773 we just need to adjust our iteration frequency */
774 min_relative_record_time.rel_value_us =
775 GNUNET_MIN (rd_public[i].expiration_time,
776 min_relative_record_time.rel_value_us);
777 }
778 }
779
780
889 /* We got a set of records to publish */ 781 /* We got a set of records to publish */
890 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 782 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
891 "Starting DHT PUT\n"); 783 "Starting DHT PUT\n");
@@ -899,12 +791,23 @@ put_gns_record (void *cls,
899 expire, 791 expire,
900 ma); 792 ma);
901 ta = GNUNET_new (struct TombstoneActivity); 793 ta = GNUNET_new (struct TombstoneActivity);
902 ta->ns_qe = touch_tombstone (key, 794 ZMSTR_touch_tombstone (key,
903 label, 795 label,
904 rd, 796 rd,
905 rd_count, 797 rd_count,
906 expire, 798 rd_fresh,
907 ta); 799 &rd_fresh_count,
800 expire);
801 ta->ns_qe = GNUNET_NAMESTORE_records_store_ (namestore_handle,
802 key,
803 label,
804 rd_fresh_count,
805 rd_fresh,
806 GNUNET_YES,
807 &ts_store_cont,
808 ta);
809
810
908 GNUNET_CONTAINER_DLL_insert_tail (ta_head, 811 GNUNET_CONTAINER_DLL_insert_tail (ta_head,
909 ta_tail, 812 ta_tail,
910 ta); 813 ta);
@@ -940,7 +843,6 @@ put_gns_record (void *cls,
940 } 843 }
941} 844}
942 845
943
944/** 846/**
945 * Periodically iterate over all zones and store everything in DHT 847 * Periodically iterate over all zones and store everything in DHT
946 * 848 *
diff --git a/src/zonemaster/zonemaster_misc.c b/src/zonemaster/zonemaster_misc.c
new file mode 100644
index 000000000..f067e9c62
--- /dev/null
+++ b/src/zonemaster/zonemaster_misc.c
@@ -0,0 +1,132 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21
22#include "zonemaster_misc.h"
23
24/**
25 * Convert namestore records from the internal format to that
26 * suitable for publication (removes private records, converts
27 * to absolute expiration time).
28 *
29 * @param rd input records
30 * @param rd_count size of the @a rd and @a rd_public arrays
31 * @param rd_public where to write the converted records
32 * @param expire the expiration of the block
33 * @return number of records written to @a rd_public
34 */
35unsigned int
36ZMSTR_convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd,
37 unsigned int rd_count,
38 struct GNUNET_GNSRECORD_Data *rd_public,
39 struct GNUNET_TIME_Absolute *expiry)
40{
41 const struct GNUNET_GNSRECORD_TombstoneRecord *tombstone;
42 struct GNUNET_TIME_Absolute expiry_tombstone;
43 struct GNUNET_TIME_Absolute now;
44 unsigned int rd_public_count;
45
46 rd_public_count = 0;
47 tombstone = NULL;
48 now = GNUNET_TIME_absolute_get ();
49 for (unsigned int i = 0; i < rd_count; i++)
50 {
51 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
52 {
53 tombstone = rd[i].data;
54 continue;
55 }
56 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))
57 continue;
58 if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) &&
59 (rd[i].expiration_time < now.abs_value_us))
60 continue; /* record already expired, skip it */
61 rd_public[rd_public_count] = rd[i];
62 /* Make sure critical record types are published as such */
63 if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type))
64 rd_public[rd_public_count].flags |= GNUNET_GNSRECORD_RF_CRITICAL;
65 rd_public_count++;
66 }
67
68 *expiry = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count,
69 rd_public);
70
71 /* We need to check if the tombstone has an expiration in the fututre
72 * which would mean there was a block published under this label
73 * previously that is still valid. In this case we MUST NOT publish this
74 * block
75 */
76 if (NULL != tombstone)
77 {
78 expiry_tombstone = GNUNET_TIME_absolute_ntoh (tombstone->time_of_death);
79 if (GNUNET_TIME_absolute_cmp (*expiry,<=,expiry_tombstone))
80 return 0;
81 }
82 return rd_public_count;
83}
84
85
86/**
87 * Update tombstone records.
88 *
89 * @param key key of the zone
90 * @param label label to store under
91 * @param rd_public public record data
92 * @param rd_public_count number of records in @a rd_public
93 * @param rd the buffer for the result. Must be rd_public_count +1
94 * @param rd_count the actual number of records written to rd
95 * @param expire the expiration time for the tombstone
96 * @return Namestore queue entry, NULL on error
97 */
98void
99ZMSTR_touch_tombstone (const struct GNUNET_IDENTITY_PrivateKey *key,
100 const char *label,
101 const struct GNUNET_GNSRECORD_Data *rd_original,
102 unsigned int rd_count_original,
103 struct GNUNET_GNSRECORD_Data *rd,
104 unsigned int *rd_count,
105 const struct GNUNET_TIME_Absolute expire)
106{
107 struct GNUNET_TIME_AbsoluteNBO exp_nbo;
108 int tombstone_exists = GNUNET_NO;
109 unsigned int i;
110
111 exp_nbo = GNUNET_TIME_absolute_hton (expire);
112 for (i = 0; i < rd_count_original; i++)
113 {
114 memcpy (&rd[i], &rd_original[i],
115 sizeof (struct GNUNET_GNSRECORD_Data));
116 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
117 {
118 rd[i].data = &exp_nbo;
119 tombstone_exists = GNUNET_YES;
120 }
121 }
122 if (GNUNET_NO == tombstone_exists)
123 {
124 rd[i].data = &exp_nbo;
125 rd[i].data_size = sizeof (exp_nbo);
126 rd[i].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
127 rd[i].flags = GNUNET_GNSRECORD_RF_PRIVATE;
128 rd[i].expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
129 i++;
130 }
131 *rd_count = i;
132}
diff --git a/src/zonemaster/zonemaster_misc.h b/src/zonemaster/zonemaster_misc.h
new file mode 100644
index 000000000..27ef3aab7
--- /dev/null
+++ b/src/zonemaster/zonemaster_misc.h
@@ -0,0 +1,62 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21#include "platform.h"
22#include "gnunet_util_lib.h"
23#include "gnunet_namestore_service.h"
24
25
26/**
27 * Convert namestore records from the internal format to that
28 * suitable for publication (removes private records, converts
29 * to absolute expiration time).
30 *
31 * @param rd input records
32 * @param rd_count size of the @a rd and @a rd_public arrays
33 * @param rd_public where to write the converted records
34 * @param expire the expiration of the block
35 * @return number of records written to @a rd_public
36 */
37unsigned int
38ZMSTR_convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd,
39 unsigned int rd_count,
40 struct GNUNET_GNSRECORD_Data *rd_public,
41 struct GNUNET_TIME_Absolute *expiry);
42
43/**
44 * Update tombstone records.
45 *
46 * @param key key of the zone
47 * @param label label to store under
48 * @param rd_public public record data
49 * @param rd_public_count number of records in @a rd_public
50 * @param rd the buffer for the result. Must be rd_public_count +1
51 * @param rd_count the actual number of records written to rd
52 * @param expire the expiration time for the tombstone
53 * @return Namestore queue entry, NULL on error
54 */
55void
56ZMSTR_touch_tombstone (const struct GNUNET_IDENTITY_PrivateKey *key,
57 const char *label,
58 const struct GNUNET_GNSRECORD_Data *rd_original,
59 unsigned int rd_count_original,
60 struct GNUNET_GNSRECORD_Data *rd,
61 unsigned int *rd_count,
62 const struct GNUNET_TIME_Absolute expire);