aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-02-06 14:30:00 +0100
committerMartin Schanzenbach <schanzen@gnunet.org>2022-02-06 14:30:00 +0100
commit215032563755ba48d4e871b82c9c6697611726f8 (patch)
tree51123c26b3d1418d0d400593438e23da48a8b4c8 /src/namestore
parentd322de96b95a7afad7f5bd255bf70642840a3778 (diff)
downloadgnunet-215032563755ba48d4e871b82c9c6697611726f8.tar.gz
gnunet-215032563755ba48d4e871b82c9c6697611726f8.zip
-simlify and correct tombstone logic
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/gnunet-service-namestore.c108
-rw-r--r--src/namestore/namestore.h6
-rw-r--r--src/namestore/namestore_api.c36
3 files changed, 61 insertions, 89 deletions
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index 7669e90f5..acf49de9e 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -948,7 +948,8 @@ refresh_block (struct NamestoreClient *nc,
948 GNUNET_free (res); 948 GNUNET_free (res);
949 return; 949 return;
950 } 950 }
951 exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res); 951 exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res,
952 GNUNET_TIME_UNIT_FOREVER_ABS);
952 if (cache_keys) 953 if (cache_keys)
953 GNUNET_assert (GNUNET_OK == 954 GNUNET_assert (GNUNET_OK ==
954 GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name, 955 GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name,
@@ -1461,25 +1462,21 @@ check_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1461 * @param rd records stored under @a label in the zone 1462 * @param rd records stored under @a label in the zone
1462 */ 1463 */
1463static void 1464static void
1464lookup_tombstone_it (void *cls, 1465get_block_exp_existing (void *cls,
1465 uint64_t seq, 1466 uint64_t seq,
1466 const struct GNUNET_IDENTITY_PrivateKey *private_key, 1467 const struct
1467 const char *label, 1468 GNUNET_IDENTITY_PrivateKey *private_key,
1468 unsigned int rd_count, 1469 const char *label,
1469 const struct GNUNET_GNSRECORD_Data *rd) 1470 unsigned int rd_count,
1471 const struct GNUNET_GNSRECORD_Data *rd)
1470{ 1472{
1471 struct GNUNET_GNSRECORD_TombstoneRecord *ts = cls; 1473 struct GNUNET_TIME_Absolute *exp = cls;
1474 struct GNUNET_GNSRECORD_Data rd_pub[rd_count];
1472 1475
1473 (void) private_key; 1476 GNUNET_GNSRECORD_convert_records_for_export (rd,
1474 GNUNET_assert (0 != seq); 1477 rd_count,
1475 for (unsigned int c = 0; c < rd_count; c++) 1478 rd_pub,
1476 { 1479 exp);
1477 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[c].record_type)
1478 {
1479 memcpy (ts, rd[c].data, rd[c].data_size);
1480 return;
1481 }
1482 }
1483} 1480}
1484 1481
1485 1482
@@ -1502,11 +1499,14 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1502 unsigned int rd_count; 1499 unsigned int rd_count;
1503 int res; 1500 int res;
1504 struct StoreActivity *sa; 1501 struct StoreActivity *sa;
1505 struct GNUNET_GNSRECORD_TombstoneRecord tombstone; 1502 struct GNUNET_TIME_Absolute existing_block_exp;
1503 struct GNUNET_TIME_Absolute new_block_exp;
1504 struct GNUNET_GNSRECORD_Data *tombstone_record;
1506 1505
1507 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1508 "Received NAMESTORE_RECORD_STORE message\n"); 1507 "Received NAMESTORE_RECORD_STORE message\n");
1509 tombstone.time_of_death.abs_value_us__ = 0; 1508 existing_block_exp.abs_value_us = 0;
1509 tombstone_record = NULL;
1510 rid = ntohl (rp_msg->gns_header.r_id); 1510 rid = ntohl (rp_msg->gns_header.r_id);
1511 name_len = ntohs (rp_msg->name_len); 1511 name_len = ntohs (rp_msg->name_len);
1512 rd_count = ntohs (rp_msg->rd_count); 1512 rd_count = ntohs (rp_msg->rd_count);
@@ -1545,8 +1545,8 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1545 if ((GNUNET_NO == GSN_database->lookup_records (GSN_database->cls, 1545 if ((GNUNET_NO == GSN_database->lookup_records (GSN_database->cls,
1546 &rp_msg->private_key, 1546 &rp_msg->private_key,
1547 conv_name, 1547 conv_name,
1548 &lookup_tombstone_it, 1548 &get_block_exp_existing,
1549 &tombstone)) && 1549 &existing_block_exp)) &&
1550 (rd_count == 0)) 1550 (rd_count == 0))
1551 { 1551 {
1552 /* This name does not exist, so cannot be removed */ 1552 /* This name does not exist, so cannot be removed */
@@ -1559,28 +1559,20 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1559 { 1559 {
1560 /* remove "NICK" records, unless this is for the 1560 /* remove "NICK" records, unless this is for the
1561 #GNUNET_GNS_EMPTY_LABEL_AT label 1561 #GNUNET_GNS_EMPTY_LABEL_AT label
1562 Also, add or update tombstone record if this is a zonemaster request. 1562 We may need one additional record later for tombstone.
1563 Also, add existing tombstone record to set if this is not a zonemaster 1563 */
1564 request if one existed in the old set.
1565 This is why we (may) need one additional record */
1566 struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count) + 1]; 1564 struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count) + 1];
1567 unsigned int rd_clean_off; 1565 unsigned int rd_clean_off;
1568 int have_nick; 1566 int have_nick;
1569 int have_tombstone;
1570 1567
1571 rd_clean_off = 0; 1568 rd_clean_off = 0;
1572 have_nick = GNUNET_NO; 1569 have_nick = GNUNET_NO;
1573 have_tombstone = GNUNET_NO;
1574 for (unsigned int i = 0; i < rd_count; i++) 1570 for (unsigned int i = 0; i < rd_count; i++)
1575 { 1571 {
1576 /* Do not allow to set tombstone records unless zonemaster */ 1572 /* Do not allow to set tombstone records unless zonemaster */
1577 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
1578 {
1579 if (1 != ntohs (rp_msg->is_zonemaster))
1580 continue;
1581 have_tombstone = GNUNET_YES;
1582 }
1583 rd_clean[rd_clean_off] = rd[i]; 1573 rd_clean[rd_clean_off] = rd[i];
1574 if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type)
1575 tombstone_record = &rd_clean[rd_clean_off];
1584 if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type)) 1576 if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type))
1585 rd_clean[rd_clean_off].flags |= GNUNET_GNSRECORD_RF_CRITICAL; 1577 rd_clean[rd_clean_off].flags |= GNUNET_GNSRECORD_RF_CRITICAL;
1586 1578
@@ -1595,24 +1587,38 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1595 have_nick = GNUNET_YES; 1587 have_nick = GNUNET_YES;
1596 } 1588 }
1597 } 1589 }
1598 /* At this point we are either zonemaster and have set a new tombstone 1590 GNUNET_GNSRECORD_convert_records_for_export (rd,
1599 * (have_tombstone) 1591 rd_clean_off,
1600 * or we are not zonemaster and we may want to 1592 rd_clean,
1601 * add the old tombstone (if there was any and if it is not already 1593 &new_block_exp);
1602 * old). 1594 /*
1595 * If existing_block_exp is 0, then there was not record set
1596 * and no tombstone.
1597 * Otherwise, if the existing block expiration is after the
1598 * new block expiration would be, we need to add a tombstone
1599 * or update it.
1603 */ 1600 */
1604 if ((GNUNET_NO == have_tombstone) && 1601 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1605 GNUNET_TIME_absolute_cmp ( 1602 "New exp: %s\n",
1606 GNUNET_TIME_absolute_get (), <, GNUNET_TIME_absolute_ntoh ( 1603 GNUNET_STRINGS_absolute_time_to_string (new_block_exp));
1607 tombstone.time_of_death))) 1604 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1605 "Old exp: %s\n",
1606 GNUNET_STRINGS_absolute_time_to_string (existing_block_exp));
1607 if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, existing_block_exp))
1608 { 1608 {
1609 rd_clean[rd_clean_off].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE; 1609 /* There was already a TS record in the set given */
1610 rd_clean[rd_clean_off].expiration_time = 1610 if (NULL != tombstone_record)
1611 GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; 1611 {
1612 rd_clean[rd_clean_off].data = &tombstone; 1612 tombstone_record->expiration_time = existing_block_exp.abs_value_us;
1613 rd_clean[rd_clean_off].data_size = sizeof (tombstone); 1613 }
1614 rd_clean[rd_clean_off].flags |= GNUNET_GNSRECORD_RF_PRIVATE; 1614 else {
1615 rd_clean_off++; 1615 rd_clean[rd_clean_off].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
1616 rd_clean[rd_clean_off].expiration_time = existing_block_exp.abs_value_us;
1617 rd_clean[rd_clean_off].data = NULL;
1618 rd_clean[rd_clean_off].data_size = 0;
1619 rd_clean[rd_clean_off].flags |= GNUNET_GNSRECORD_RF_PRIVATE;
1620 rd_clean_off++;
1621 }
1616 } 1622 }
1617 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) && 1623 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1618 (GNUNET_NO == have_nick)) 1624 (GNUNET_NO == have_nick))
@@ -1627,7 +1633,7 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1627 rd_clean); 1633 rd_clean);
1628 } 1634 }
1629 1635
1630 if ((GNUNET_OK != res) || (1 == ntohs (rp_msg->is_zonemaster))) 1636 if (GNUNET_OK != res)
1631 { 1637 {
1632 /* store not successful or zonemaster, not need to tell monitors */ 1638 /* store not successful or zonemaster, not need to tell monitors */
1633 send_store_response (nc, res, rid); 1639 send_store_response (nc, res, rid);
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h
index bcc8f5d4e..05a1d97ad 100644
--- a/src/namestore/namestore.h
+++ b/src/namestore/namestore.h
@@ -83,11 +83,9 @@ struct RecordStoreMessage
83 uint16_t rd_count GNUNET_PACKED; 83 uint16_t rd_count GNUNET_PACKED;
84 84
85 /** 85 /**
86 * This is a zonemaster request. 86 * Reserved for alignment.
87 * It means more authoritative tombstone processing
88 * and not notification of monitors.
89 */ 87 */
90 uint16_t is_zonemaster GNUNET_PACKED; 88 uint16_t reserved GNUNET_PACKED;
91 89
92 /** 90 /**
93 * The private key of the authority. 91 * The private key of the authority.
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index 935357d36..d4d06bab9 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -970,13 +970,12 @@ warn_delay (void *cls)
970} 970}
971 971
972struct GNUNET_NAMESTORE_QueueEntry * 972struct GNUNET_NAMESTORE_QueueEntry *
973GNUNET_NAMESTORE_records_store_ ( 973GNUNET_NAMESTORE_records_store (
974 struct GNUNET_NAMESTORE_Handle *h, 974 struct GNUNET_NAMESTORE_Handle *h,
975 const struct GNUNET_IDENTITY_PrivateKey *pkey, 975 const struct GNUNET_IDENTITY_PrivateKey *pkey,
976 const char *label, 976 const char *label,
977 unsigned int rd_count, 977 unsigned int rd_count,
978 const struct GNUNET_GNSRECORD_Data *rd, 978 const struct GNUNET_GNSRECORD_Data *rd,
979 int is_zonemaster,
980 GNUNET_NAMESTORE_ContinuationWithStatus cont, 979 GNUNET_NAMESTORE_ContinuationWithStatus cont,
981 void *cont_cls) 980 void *cont_cls)
982{ 981{
@@ -1023,7 +1022,7 @@ GNUNET_NAMESTORE_records_store_ (
1023 msg->name_len = htons (name_len); 1022 msg->name_len = htons (name_len);
1024 msg->rd_count = htons (rd_count); 1023 msg->rd_count = htons (rd_count);
1025 msg->rd_len = htons (rd_ser_len); 1024 msg->rd_len = htons (rd_ser_len);
1026 msg->is_zonemaster = (GNUNET_YES == is_zonemaster) ? ntohs(1) : ntohs(0); 1025 msg->reserved = ntohs(0);
1027 msg->private_key = *pkey; 1026 msg->private_key = *pkey;
1028 1027
1029 name_tmp = (char *) &msg[1]; 1028 name_tmp = (char *) &msg[1];
@@ -1057,37 +1056,6 @@ GNUNET_NAMESTORE_records_store_ (
1057} 1056}
1058 1057
1059/** 1058/**
1060 * Store an item in the namestore. If the item is already present,
1061 * it is replaced with the new record. Use an empty array to
1062 * remove all records under the given name.
1063 *
1064 * @param h handle to the namestore
1065 * @param pkey private key of the zone
1066 * @param label name that is being mapped (at most 255 characters long)
1067 * @param rd_count number of records in the @a rd array
1068 * @param rd array of records with data to store
1069 * @param cont continuation to call when done
1070 * @param cont_cls closure for @a cont
1071 * @return handle to abort the request
1072 */
1073struct GNUNET_NAMESTORE_QueueEntry *
1074GNUNET_NAMESTORE_records_store (
1075 struct GNUNET_NAMESTORE_Handle *h,
1076 const struct GNUNET_IDENTITY_PrivateKey *pkey,
1077 const char *label,
1078 unsigned int rd_count,
1079 const struct GNUNET_GNSRECORD_Data *rd,
1080 GNUNET_NAMESTORE_ContinuationWithStatus cont,
1081 void *cont_cls)
1082{
1083 return GNUNET_NAMESTORE_records_store_ (h, pkey, label, rd_count, rd,
1084 GNUNET_NO, cont, cont_cls);
1085}
1086
1087
1088
1089
1090/**
1091 * Lookup an item in the namestore. 1059 * Lookup an item in the namestore.
1092 * 1060 *
1093 * @param h handle to the namestore 1061 * @param h handle to the namestore