diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-02-07 15:59:04 +0100 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-02-07 15:59:04 +0100 |
commit | 14b3c75ab523830f5c1744d5a0faa4168b4172a7 (patch) | |
tree | eecc64f41891b29f5c1edd42f9315a2ab2733c59 /src/gnsrecord | |
parent | 1c89bfe03f45eef178a1e5a5d4d33057946ebf11 (diff) | |
download | gnunet-14b3c75ab523830f5c1744d5a0faa4168b4172a7.tar.gz gnunet-14b3c75ab523830f5c1744d5a0faa4168b4172a7.zip |
GNS: LSD0001 improvements
NAMESTORE: Better error handling. Fixed private record feature.
GNSRECORD: Record inconsistency check for delegation and redirection
records
Diffstat (limited to 'src/gnsrecord')
-rw-r--r-- | src/gnsrecord/gnsrecord_misc.c | 137 |
1 files changed, 121 insertions, 16 deletions
diff --git a/src/gnsrecord/gnsrecord_misc.c b/src/gnsrecord/gnsrecord_misc.c index 5c20dbedc..5bf4aa371 100644 --- a/src/gnsrecord/gnsrecord_misc.c +++ b/src/gnsrecord/gnsrecord_misc.c | |||
@@ -300,7 +300,8 @@ GNUNET_GNSRECORD_data_from_identity (const struct | |||
300 | return GNUNET_SYSERR; | 300 | return GNUNET_SYSERR; |
301 | tmp = GNUNET_malloc (*data_size); | 301 | tmp = GNUNET_malloc (*data_size); |
302 | if (GNUNET_IDENTITY_write_key_to_buffer (key, tmp, *data_size) | 302 | if (GNUNET_IDENTITY_write_key_to_buffer (key, tmp, *data_size) |
303 | != *data_size) { | 303 | != *data_size) |
304 | { | ||
304 | GNUNET_free (tmp); | 305 | GNUNET_free (tmp); |
305 | *data_size = 0; | 306 | *data_size = 0; |
306 | return GNUNET_SYSERR; | 307 | return GNUNET_SYSERR; |
@@ -399,44 +400,148 @@ GNUNET_GNSRECORD_record_to_identity_key (const struct GNUNET_GNSRECORD_Data *rd, | |||
399 | 400 | ||
400 | } | 401 | } |
401 | 402 | ||
402 | unsigned int | 403 | enum GNUNET_GenericReturnValue |
403 | GNUNET_GNSRECORD_convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, | 404 | GNUNET_GNSRECORD_normalize_record_set (const char *label, |
404 | unsigned int rd_count, | 405 | const struct |
405 | struct GNUNET_GNSRECORD_Data *rd_public, | 406 | GNUNET_GNSRECORD_Data *rd, |
406 | struct GNUNET_TIME_Absolute *expiry) | 407 | unsigned int rd_count, |
408 | struct GNUNET_GNSRECORD_Data * | ||
409 | rd_public, | ||
410 | unsigned int *rd_count_public, | ||
411 | struct GNUNET_TIME_Absolute *expiry, | ||
412 | int include_private, | ||
413 | char **emsg) | ||
407 | { | 414 | { |
408 | struct GNUNET_TIME_Absolute expiry_tombstone; | 415 | struct GNUNET_TIME_Absolute expiry_tombstone; |
409 | struct GNUNET_TIME_Absolute now; | 416 | struct GNUNET_TIME_Absolute now; |
410 | struct GNUNET_TIME_Absolute minimum_expiration; | 417 | struct GNUNET_TIME_Absolute minimum_expiration; |
411 | unsigned int rd_public_count; | 418 | int have_zone_delegation = GNUNET_NO; |
419 | int have_gns2dns = GNUNET_NO; | ||
420 | int have_other = GNUNET_NO; | ||
421 | int have_redirect = GNUNET_NO; | ||
422 | int have_empty_label = (0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, label)); | ||
423 | unsigned int rd_count_tmp; | ||
412 | 424 | ||
413 | rd_public_count = 0; | ||
414 | minimum_expiration = GNUNET_TIME_UNIT_FOREVER_ABS; | 425 | minimum_expiration = GNUNET_TIME_UNIT_FOREVER_ABS; |
415 | now = GNUNET_TIME_absolute_get (); | 426 | now = GNUNET_TIME_absolute_get (); |
427 | rd_count_tmp = 0; | ||
416 | for (unsigned int i = 0; i < rd_count; i++) | 428 | for (unsigned int i = 0; i < rd_count; i++) |
417 | { | 429 | { |
430 | /* Ignore the tombstone. For maintenance only. Remember expiration time. */ | ||
418 | if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type) | 431 | if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type) |
419 | { | 432 | { |
420 | minimum_expiration.abs_value_us = rd[i].expiration_time; | 433 | minimum_expiration.abs_value_us = rd[i].expiration_time; |
421 | continue; | 434 | continue; |
422 | } | 435 | } |
423 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE)) | 436 | /* No NICK records unless empty label */ |
437 | if (have_empty_label && | ||
438 | (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type)) | ||
439 | continue; | ||
440 | |||
441 | /** | ||
442 | * Check for delegation and redirect consistency. | ||
443 | * Note that we check for consistency BEFORE we filter for | ||
444 | * private records ON PURPOSE. | ||
445 | * We also want consistent record sets in our local zone(s). | ||
446 | * The only exception is the tombstone (above) which we ignore | ||
447 | * for the consistency check(s). | ||
448 | */ | ||
449 | if (GNUNET_YES == GNUNET_GNSRECORD_is_zonekey_type (rd[i].record_type)) | ||
450 | { | ||
451 | have_zone_delegation = GNUNET_YES; | ||
452 | /* No delegation records under empty label*/ | ||
453 | if (have_empty_label) | ||
454 | { | ||
455 | *emsg = GNUNET_strdup (_ ( | ||
456 | "Record set inconsistent: Multiple delegation records.")); | ||
457 | return GNUNET_SYSERR; | ||
458 | } | ||
459 | } | ||
460 | else if (GNUNET_GNSRECORD_TYPE_REDIRECT == rd[i].record_type) | ||
461 | { | ||
462 | if (GNUNET_YES == have_redirect) | ||
463 | { | ||
464 | *emsg = GNUNET_strdup (_ ( | ||
465 | "Record set inconsistent: Multiple REDIRECT records.")); | ||
466 | return GNUNET_SYSERR; | ||
467 | } | ||
468 | have_redirect = GNUNET_YES; | ||
469 | /* No redirection records under empty label*/ | ||
470 | if (have_empty_label) | ||
471 | { | ||
472 | *emsg = GNUNET_strdup (_ ( | ||
473 | "Record set inconsistent: REDIRECT record under apex label.")); | ||
474 | return GNUNET_SYSERR; | ||
475 | } | ||
476 | } | ||
477 | else if (GNUNET_GNSRECORD_TYPE_GNS2DNS == rd[i].record_type) | ||
478 | { | ||
479 | have_gns2dns = GNUNET_YES; | ||
480 | /* No gns2dns records under empty label*/ | ||
481 | if (have_empty_label) | ||
482 | { | ||
483 | *emsg = GNUNET_strdup (_ ( | ||
484 | "Record set inconsistent: GNS2DNS record under apex label.\n")); | ||
485 | return GNUNET_SYSERR; | ||
486 | } | ||
487 | } | ||
488 | else | ||
489 | { | ||
490 | /* Some other record. | ||
491 | * Not allowed for zone delegations or redirections */ | ||
492 | if ((GNUNET_YES == have_zone_delegation) || | ||
493 | (GNUNET_YES == have_redirect) || | ||
494 | (GNUNET_YES == have_gns2dns)) | ||
495 | { | ||
496 | *emsg = GNUNET_strdup (_("Record set inconsistent: Mutually exclusive records.\n")); | ||
497 | return GNUNET_SYSERR; | ||
498 | have_other = GNUNET_YES; | ||
499 | } | ||
500 | } | ||
501 | |||
502 | /* Ignore private records for public record set */ | ||
503 | |||
504 | if ((GNUNET_NO != include_private) && | ||
505 | (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_PRIVATE))) | ||
424 | continue; | 506 | continue; |
507 | /* Skip expired records */ | ||
425 | if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) && | 508 | if ((0 == (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) && |
426 | (rd[i].expiration_time < now.abs_value_us)) | 509 | (rd[i].expiration_time < now.abs_value_us)) |
427 | continue; /* record already expired, skip it */ | 510 | continue; /* record already expired, skip it */ |
428 | rd_public[rd_public_count] = rd[i]; | 511 | rd_public[rd_count_tmp] = rd[i]; |
429 | /* Make sure critical record types are published as such */ | 512 | /* Make sure critical record types are marked as such */ |
430 | if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type)) | 513 | if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type)) |
431 | rd_public[rd_public_count].flags |= GNUNET_GNSRECORD_RF_CRITICAL; | 514 | rd_public[rd_count_tmp].flags |= GNUNET_GNSRECORD_RF_CRITICAL; |
432 | rd_public_count++; | 515 | rd_count_tmp++; |
433 | } | 516 | } |
434 | 517 | ||
435 | *expiry = GNUNET_GNSRECORD_record_get_expiration_time (rd_public_count, | 518 | *expiry = GNUNET_GNSRECORD_record_get_expiration_time (rd_count_tmp, |
436 | rd_public, | 519 | rd_public, |
437 | minimum_expiration); | 520 | minimum_expiration); |
521 | *rd_count_public = rd_count_tmp; | ||
522 | return GNUNET_OK; | ||
523 | } | ||
524 | |||
525 | enum GNUNET_GenericReturnValue | ||
526 | GNUNET_GNSRECORD_convert_records_for_export (const char *label, | ||
527 | const struct | ||
528 | GNUNET_GNSRECORD_Data *rd, | ||
529 | unsigned int rd_count, | ||
530 | struct GNUNET_GNSRECORD_Data * | ||
531 | rd_public, | ||
532 | unsigned int *rd_count_public, | ||
533 | struct GNUNET_TIME_Absolute *expiry, | ||
534 | char **emsg) | ||
535 | { | ||
536 | return GNUNET_GNSRECORD_normalize_record_set (label, | ||
537 | rd, | ||
538 | rd_count, | ||
539 | rd_public, | ||
540 | rd_count_public, | ||
541 | expiry, | ||
542 | GNUNET_NO, | ||
543 | emsg); | ||
438 | 544 | ||
439 | return rd_public_count; | ||
440 | } | 545 | } |
441 | 546 | ||
442 | 547 | ||