diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-10-19 16:02:47 +0900 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-10-19 16:02:47 +0900 |
commit | da036970cd6b71908052eee17dc1b50f31e6b310 (patch) | |
tree | e7b55956f355067eda76b239b45b5d1763631940 /src/namestore | |
parent | c0e8a01c7ce54d96b80a17b4ddd9f10b83081732 (diff) | |
download | gnunet-da036970cd6b71908052eee17dc1b50f31e6b310.tar.gz gnunet-da036970cd6b71908052eee17dc1b50f31e6b310.zip |
-fix deletion of tombstone records
Diffstat (limited to 'src/namestore')
-rw-r--r-- | src/namestore/gnunet-service-namestore.c | 65 |
1 files changed, 49 insertions, 16 deletions
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index c164fed3a..c39dab53e 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c | |||
@@ -1492,6 +1492,8 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) | |||
1492 | } | 1492 | } |
1493 | name_len = strlen (conv_name) + 1; | 1493 | name_len = strlen (conv_name) + 1; |
1494 | rlc.label = conv_name; | 1494 | rlc.label = conv_name; |
1495 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1496 | "Looking up with filter %u\n", ntohs(ll_msg->filter)); | ||
1495 | rlc.filter = ntohs (ll_msg->filter); | 1497 | rlc.filter = ntohs (ll_msg->filter); |
1496 | rlc.found = GNUNET_NO; | 1498 | rlc.found = GNUNET_NO; |
1497 | rlc.res_rd_count = 0; | 1499 | rlc.res_rd_count = 0; |
@@ -1563,6 +1565,22 @@ check_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1563 | return GNUNET_OK; | 1565 | return GNUNET_OK; |
1564 | } | 1566 | } |
1565 | 1567 | ||
1568 | struct LookupExistingRecordsContext | ||
1569 | { | ||
1570 | |||
1571 | /** | ||
1572 | * The expiration of the existing records or tombstone | ||
1573 | */ | ||
1574 | struct GNUNET_TIME_Absolute exp; | ||
1575 | |||
1576 | /** | ||
1577 | * Whether the existing record set consists only of a tombstone | ||
1578 | * (e.g. is "empty") | ||
1579 | */ | ||
1580 | int only_tombstone; | ||
1581 | |||
1582 | }; | ||
1583 | |||
1566 | 1584 | ||
1567 | /** | 1585 | /** |
1568 | * Check if set contains a tombstone, store if necessary | 1586 | * Check if set contains a tombstone, store if necessary |
@@ -1575,26 +1593,32 @@ check_record_store (void *cls, const struct RecordStoreMessage *rp_msg) | |||
1575 | * @param rd records stored under @a label in the zone | 1593 | * @param rd records stored under @a label in the zone |
1576 | */ | 1594 | */ |
1577 | static void | 1595 | static void |
1578 | get_block_exp_existing (void *cls, | 1596 | get_existing_rd_exp (void *cls, |
1579 | uint64_t seq, | 1597 | uint64_t seq, |
1580 | const struct | 1598 | const struct |
1581 | GNUNET_IDENTITY_PrivateKey *private_key, | 1599 | GNUNET_IDENTITY_PrivateKey *private_key, |
1582 | const char *label, | 1600 | const char *label, |
1583 | unsigned int rd_count, | 1601 | unsigned int rd_count, |
1584 | const struct GNUNET_GNSRECORD_Data *rd) | 1602 | const struct GNUNET_GNSRECORD_Data *rd) |
1585 | { | 1603 | { |
1586 | struct GNUNET_TIME_Absolute *exp = cls; | 1604 | struct LookupExistingRecordsContext *lctx = cls; |
1587 | struct GNUNET_GNSRECORD_Data rd_pub[rd_count]; | 1605 | struct GNUNET_GNSRECORD_Data rd_pub[rd_count]; |
1588 | unsigned int rd_pub_count; | 1606 | unsigned int rd_pub_count; |
1589 | char *emsg; | 1607 | char *emsg; |
1590 | 1608 | ||
1609 | if ((1 == rd_count) && | ||
1610 | (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[0].record_type)) | ||
1611 | { | ||
1612 | /* This record set contains only a tombstone! */ | ||
1613 | lctx->only_tombstone = GNUNET_YES; | ||
1614 | } | ||
1591 | if (GNUNET_OK != | 1615 | if (GNUNET_OK != |
1592 | GNUNET_GNSRECORD_normalize_record_set (label, | 1616 | GNUNET_GNSRECORD_normalize_record_set (label, |
1593 | rd, | 1617 | rd, |
1594 | rd_count, | 1618 | rd_count, |
1595 | rd_pub, | 1619 | rd_pub, |
1596 | &rd_pub_count, | 1620 | &rd_pub_count, |
1597 | exp, | 1621 | &lctx->exp, |
1598 | GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE, | 1622 | GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE, |
1599 | &emsg)) | 1623 | &emsg)) |
1600 | { | 1624 | { |
@@ -1618,11 +1642,12 @@ store_record_set (struct NamestoreClient *nc, | |||
1618 | char *conv_name; | 1642 | char *conv_name; |
1619 | unsigned int rd_count; | 1643 | unsigned int rd_count; |
1620 | int res; | 1644 | int res; |
1621 | struct GNUNET_TIME_Absolute existing_block_exp; | ||
1622 | struct GNUNET_TIME_Absolute new_block_exp; | 1645 | struct GNUNET_TIME_Absolute new_block_exp; |
1646 | struct LookupExistingRecordsContext lctx; | ||
1623 | *len = sizeof (struct RecordSet); | 1647 | *len = sizeof (struct RecordSet); |
1624 | 1648 | ||
1625 | existing_block_exp = GNUNET_TIME_UNIT_ZERO_ABS; | 1649 | lctx.only_tombstone = GNUNET_NO; |
1650 | lctx.exp = GNUNET_TIME_UNIT_ZERO_ABS; | ||
1626 | new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS; | 1651 | new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS; |
1627 | name_len = ntohs (rd_set->name_len); | 1652 | name_len = ntohs (rd_set->name_len); |
1628 | *len += name_len; | 1653 | *len += name_len; |
@@ -1675,9 +1700,8 @@ store_record_set (struct NamestoreClient *nc, | |||
1675 | if ((GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls, | 1700 | if ((GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls, |
1676 | private_key, | 1701 | private_key, |
1677 | conv_name, | 1702 | conv_name, |
1678 | & | 1703 | &get_existing_rd_exp, |
1679 | get_block_exp_existing, | 1704 | &lctx)) |
1680 | &existing_block_exp)) | ||
1681 | && | 1705 | && |
1682 | (rd_count == 0)) | 1706 | (rd_count == 0)) |
1683 | { | 1707 | { |
@@ -1742,11 +1766,11 @@ store_record_set (struct NamestoreClient *nc, | |||
1742 | * new block expiration would be, we need to add a tombstone | 1766 | * new block expiration would be, we need to add a tombstone |
1743 | * or update it. | 1767 | * or update it. |
1744 | */ | 1768 | */ |
1745 | if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, existing_block_exp)) | 1769 | if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, lctx.exp)) |
1746 | { | 1770 | { |
1747 | rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE; | 1771 | rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE; |
1748 | rd_nf[rd_nf_count].expiration_time = | 1772 | rd_nf[rd_nf_count].expiration_time = |
1749 | existing_block_exp.abs_value_us; | 1773 | lctx.exp.abs_value_us; |
1750 | rd_nf[rd_nf_count].data = NULL; | 1774 | rd_nf[rd_nf_count].data = NULL; |
1751 | rd_nf[rd_nf_count].data_size = 0; | 1775 | rd_nf[rd_nf_count].data_size = 0; |
1752 | rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE; | 1776 | rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE; |
@@ -1765,6 +1789,15 @@ store_record_set (struct NamestoreClient *nc, | |||
1765 | conv_name, | 1789 | conv_name, |
1766 | rd_nf_count, | 1790 | rd_nf_count, |
1767 | rd_nf); | 1791 | rd_nf); |
1792 | /* If after a store there is only a TOMBSTONE left, and | ||
1793 | * there was >1 record under this label found (the tombstone; indicated | ||
1794 | * through res != GNUNET_NO) then we should return "NOT FOUND" == GNUNET_NO | ||
1795 | */ | ||
1796 | if ((GNUNET_SYSERR != res) && | ||
1797 | (1 == rd_nf_count) && | ||
1798 | (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd_nf[0].record_type) && | ||
1799 | (lctx.only_tombstone)) | ||
1800 | res = GNUNET_NO; | ||
1768 | } | 1801 | } |
1769 | 1802 | ||
1770 | if (GNUNET_SYSERR == res) | 1803 | if (GNUNET_SYSERR == res) |