aboutsummaryrefslogtreecommitdiff
path: root/src/gnsrecord
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-02-07 15:59:04 +0100
committerMartin Schanzenbach <schanzen@gnunet.org>2022-02-07 15:59:04 +0100
commit14b3c75ab523830f5c1744d5a0faa4168b4172a7 (patch)
treeeecc64f41891b29f5c1edd42f9315a2ab2733c59 /src/gnsrecord
parent1c89bfe03f45eef178a1e5a5d4d33057946ebf11 (diff)
downloadgnunet-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.c137
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
402unsigned int 403enum GNUNET_GenericReturnValue
403GNUNET_GNSRECORD_convert_records_for_export (const struct GNUNET_GNSRECORD_Data *rd, 404GNUNET_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
525enum GNUNET_GenericReturnValue
526GNUNET_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