aboutsummaryrefslogtreecommitdiff
path: root/src/zonemaster
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-02-05 17:17:37 +0100
committerMartin Schanzenbach <schanzen@gnunet.org>2022-02-05 17:17:37 +0100
commitaa85ac347e31b22bcd86c6fbe9875dc4ffa93229 (patch)
tree91ed15a290b2a81ee4e8993e486d5a0de54cec37 /src/zonemaster
parent32da9a943942efc8a1384f5a6839cc84f79a42db (diff)
downloadgnunet-aa85ac347e31b22bcd86c6fbe9875dc4ffa93229.tar.gz
gnunet-aa85ac347e31b22bcd86c6fbe9875dc4ffa93229.zip
GNS: Add tombstone string processing; also handle tombstones in monitor properly
Diffstat (limited to 'src/zonemaster')
-rw-r--r--src/zonemaster/gnunet-service-zonemaster-monitor.c166
1 files changed, 160 insertions, 6 deletions
diff --git a/src/zonemaster/gnunet-service-zonemaster-monitor.c b/src/zonemaster/gnunet-service-zonemaster-monitor.c
index 3392a19d7..081398f0e 100644
--- a/src/zonemaster/gnunet-service-zonemaster-monitor.c
+++ b/src/zonemaster/gnunet-service-zonemaster-monitor.c
@@ -58,6 +58,29 @@
58 */ 58 */
59#define DHT_GNS_REPLICATION_LEVEL 5 59#define DHT_GNS_REPLICATION_LEVEL 5
60 60
61/**
62 * Handle for tombston updates which are executed for each published
63 * record set.
64 */
65struct TombstoneActivity
66{
67 /**
68 * Kept in a DLL.
69 */
70 struct TombstoneActivity *next;
71
72 /**
73 * Kept in a DLL.
74 */
75 struct TombstoneActivity *prev;
76
77 /**
78 * Handle for the store operation.
79 */
80 struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
81
82};
83
61 84
62/** 85/**
63 * Handle for DHT PUT activity triggered from the namestore monitor. 86 * Handle for DHT PUT activity triggered from the namestore monitor.
@@ -107,6 +130,17 @@ static struct GNUNET_NAMESTORE_Handle *namestore_handle;
107static struct GNUNET_NAMESTORE_ZoneMonitor *zmon; 130static struct GNUNET_NAMESTORE_ZoneMonitor *zmon;
108 131
109/** 132/**
133 * Head of the tombstone operations
134 */
135static struct TombstoneActivity *ta_head;
136
137/**
138 * Tail of the tombstone operations
139 */
140static struct TombstoneActivity *ta_tail;
141
142
143/**
110 * Head of monitor activities; kept in a DLL. 144 * Head of monitor activities; kept in a DLL.
111 */ 145 */
112static struct DhtPutActivity *ma_head; 146static struct DhtPutActivity *ma_head;
@@ -138,6 +172,7 @@ static void
138shutdown_task (void *cls) 172shutdown_task (void *cls)
139{ 173{
140 struct DhtPutActivity *ma; 174 struct DhtPutActivity *ma;
175 struct TombstoneActivity *ta;
141 176
142 (void) cls; 177 (void) cls;
143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -151,6 +186,14 @@ shutdown_task (void *cls)
151 ma); 186 ma);
152 GNUNET_free (ma); 187 GNUNET_free (ma);
153 } 188 }
189 while (NULL != (ta = ta_head))
190 {
191 GNUNET_NAMESTORE_cancel (ta->ns_qe);
192 GNUNET_CONTAINER_DLL_remove (ta_head,
193 ta_tail,
194 ta);
195 GNUNET_free (ta);
196 }
154 if (NULL != statistics) 197 if (NULL != statistics)
155 { 198 {
156 GNUNET_STATISTICS_destroy (statistics, 199 GNUNET_STATISTICS_destroy (statistics,
@@ -209,22 +252,51 @@ dht_put_monitor_continuation (void *cls)
209static unsigned int 252static unsigned int
210convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, 253convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd,
211 unsigned int rd_count, 254 unsigned int rd_count,
212 struct GNUNET_GNSRECORD_Data *rd_public) 255 struct GNUNET_GNSRECORD_Data *rd_public,
256 struct GNUNET_TIME_Absolute *expiry)
213{ 257{
258 const struct GNUNET_GNSRECORD_TombstoneRecord *tombstone;
259 struct GNUNET_TIME_Absolute expiry_tombstone;
214 struct GNUNET_TIME_Absolute now; 260 struct GNUNET_TIME_Absolute now;
215 unsigned int rd_public_count; 261 unsigned int rd_public_count;
216 262
217 rd_public_count = 0; 263 rd_public_count = 0;
264 tombstone = NULL;
218 now = GNUNET_TIME_absolute_get (); 265 now = GNUNET_TIME_absolute_get ();
219 for (unsigned int i = 0; i < rd_count; i++) 266 for (unsigned int i = 0; i < rd_count; i++)
220 { 267 {
221 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) 268 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))
222 continue; 269 continue;
270 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
271 {
272 tombstone = rd[i].data;
273 continue;
274 }
223 if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) && 275 if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) &&
224 (rd[i].expiration_time < now.abs_value_us)) 276 (rd[i].expiration_time < now.abs_value_us))
225 continue; /* record already expired, skip it */ 277 continue; /* record already expired, skip it */
226 rd_public[rd_public_count++] = rd[i]; 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;
227 } 298 }
299
228 return rd_public_count; 300 return rd_public_count;
229} 301}
230 302
@@ -244,16 +316,14 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key,
244 const char *label, 316 const char *label,
245 const struct GNUNET_GNSRECORD_Data *rd_public, 317 const struct GNUNET_GNSRECORD_Data *rd_public,
246 unsigned int rd_public_count, 318 unsigned int rd_public_count,
319 struct GNUNET_TIME_Absolute expire,
247 struct DhtPutActivity *ma) 320 struct DhtPutActivity *ma)
248{ 321{
249 struct GNUNET_GNSRECORD_Block *block; 322 struct GNUNET_GNSRECORD_Block *block;
250 struct GNUNET_HashCode query; 323 struct GNUNET_HashCode query;
251 struct GNUNET_TIME_Absolute expire;
252 size_t block_size; 324 size_t block_size;
253 struct GNUNET_DHT_PutHandle *ret; 325 struct GNUNET_DHT_PutHandle *ret;
254 326
255 expire = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count,
256 rd_public);
257 if (cache_keys) 327 if (cache_keys)
258 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, 328 GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key,
259 expire, 329 expire,
@@ -301,6 +371,76 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key,
301 return ret; 371 return ret;
302} 372}
303 373
374static void
375ts_store_cont (void *cls, int32_t success, const char *emsg)
376{
377 struct TombstoneActivity *ta = cls;
378
379 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
380 "Tombstone update complete\n");
381 GNUNET_CONTAINER_DLL_remove (ta_head,
382 ta_tail,
383 ta);
384 GNUNET_free (ta);
385
386}
387
388
389/**
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
304 444
305/** 445/**
306 * Process a record that was stored in the namestore 446 * Process a record that was stored in the namestore
@@ -322,6 +462,8 @@ handle_monitor_event (void *cls,
322 struct GNUNET_GNSRECORD_Data rd_public[rd_count]; 462 struct GNUNET_GNSRECORD_Data rd_public[rd_count];
323 unsigned int rd_public_count; 463 unsigned int rd_public_count;
324 struct DhtPutActivity *ma; 464 struct DhtPutActivity *ma;
465 struct TombstoneActivity *ta;
466 struct GNUNET_TIME_Absolute expire;
325 467
326 (void) cls; 468 (void) cls;
327 GNUNET_STATISTICS_update (statistics, 469 GNUNET_STATISTICS_update (statistics,
@@ -336,7 +478,8 @@ handle_monitor_event (void *cls,
336 absolute expiration time. */ 478 absolute expiration time. */
337 rd_public_count = convert_records_for_export (rd, 479 rd_public_count = convert_records_for_export (rd,
338 rd_count, 480 rd_count,
339 rd_public); 481 rd_public,
482 &expire);
340 if (0 == rd_public_count) 483 if (0 == rd_public_count)
341 { 484 {
342 GNUNET_NAMESTORE_zone_monitor_next (zmon, 485 GNUNET_NAMESTORE_zone_monitor_next (zmon,
@@ -349,7 +492,18 @@ handle_monitor_event (void *cls,
349 label, 492 label,
350 rd, 493 rd,
351 rd_count, 494 rd_count,
495 expire,
352 ma); 496 ma);
497 ta = GNUNET_new (struct TombstoneActivity);
498 ta->ns_qe = touch_tombstone (zone,
499 label,
500 rd,
501 rd_count,
502 expire,
503 ta);
504 GNUNET_CONTAINER_DLL_insert_tail (ta_head,
505 ta_tail,
506 ta);
353 if (NULL == ma->ph) 507 if (NULL == ma->ph)
354 { 508 {
355 /* PUT failed, do not remember operation */ 509 /* PUT failed, do not remember operation */