diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-02-05 17:17:37 +0100 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-02-05 17:17:37 +0100 |
commit | aa85ac347e31b22bcd86c6fbe9875dc4ffa93229 (patch) | |
tree | 91ed15a290b2a81ee4e8993e486d5a0de54cec37 /src/zonemaster | |
parent | 32da9a943942efc8a1384f5a6839cc84f79a42db (diff) | |
download | gnunet-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.c | 166 |
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 | */ | ||
65 | struct 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; | |||
107 | static struct GNUNET_NAMESTORE_ZoneMonitor *zmon; | 130 | static struct GNUNET_NAMESTORE_ZoneMonitor *zmon; |
108 | 131 | ||
109 | /** | 132 | /** |
133 | * Head of the tombstone operations | ||
134 | */ | ||
135 | static struct TombstoneActivity *ta_head; | ||
136 | |||
137 | /** | ||
138 | * Tail of the tombstone operations | ||
139 | */ | ||
140 | static 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 | */ |
112 | static struct DhtPutActivity *ma_head; | 146 | static struct DhtPutActivity *ma_head; |
@@ -138,6 +172,7 @@ static void | |||
138 | shutdown_task (void *cls) | 172 | shutdown_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) | |||
209 | static unsigned int | 252 | static unsigned int |
210 | convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, | 253 | convert_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 | ||
374 | static void | ||
375 | ts_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 | */ | ||
400 | static struct GNUNET_NAMESTORE_QueueEntry * | ||
401 | touch_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 */ |