aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
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/namestore
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/namestore')
-rw-r--r--src/namestore/gnunet-service-namestore.c103
-rw-r--r--src/namestore/namestore.h14
-rw-r--r--src/namestore/namestore_api.c46
3 files changed, 112 insertions, 51 deletions
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index acf49de9e..51f9b9168 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -808,7 +808,8 @@ send_lookup_response (struct NamestoreClient *nc,
808 * @param rid client's request ID 808 * @param rid client's request ID
809 */ 809 */
810static void 810static void
811send_store_response (struct NamestoreClient *nc, int res, uint32_t rid) 811send_store_response (struct NamestoreClient *nc, int res, const char*emsg,
812 uint32_t rid)
812{ 813{
813 struct GNUNET_MQ_Envelope *env; 814 struct GNUNET_MQ_Envelope *env;
814 struct RecordStoreResponseMessage *rcr_msg; 815 struct RecordStoreResponseMessage *rcr_msg;
@@ -820,10 +821,17 @@ send_store_response (struct NamestoreClient *nc, int res, uint32_t rid)
820 "Store requests completed", 821 "Store requests completed",
821 1, 822 1,
822 GNUNET_NO); 823 GNUNET_NO);
823 env = GNUNET_MQ_msg (rcr_msg, 824 env = GNUNET_MQ_msg_extra (rcr_msg,
824 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE); 825 (NULL != emsg) ? strlen (emsg) + 1 : 0,
826 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE);
825 rcr_msg->gns_header.r_id = htonl (rid); 827 rcr_msg->gns_header.r_id = htonl (rid);
826 rcr_msg->op_result = htonl (res); 828 rcr_msg->op_result = htonl (res);
829 rcr_msg->reserved = htons (0);
830 if (NULL != emsg)
831 {
832 rcr_msg->emsg_len = htons (strlen (emsg) + 1);
833 memcpy (&rcr_msg[1], emsg, strlen (emsg) + 1);
834 }
827 GNUNET_MQ_send (nc->mq, env); 835 GNUNET_MQ_send (nc->mq, env);
828} 836}
829 837
@@ -874,7 +882,7 @@ finish_cache_operation (void *cls, int32_t success, const char *emsg)
874 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n"); 882 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n");
875 GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); 883 GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop);
876 if (NULL != cop->nc) 884 if (NULL != cop->nc)
877 send_store_response (cop->nc, success, cop->rid); 885 send_store_response (cop->nc, success, emsg, cop->rid);
878 if (NULL != (zi = cop->zi)) 886 if (NULL != (zi = cop->zi))
879 { 887 {
880 zi->cache_ops--; 888 zi->cache_ops--;
@@ -931,7 +939,7 @@ refresh_block (struct NamestoreClient *nc,
931 if (0 == res_count) 939 if (0 == res_count)
932 { 940 {
933 if (NULL != nc) 941 if (NULL != nc)
934 send_store_response (nc, GNUNET_OK, rid); 942 send_store_response (nc, GNUNET_OK, NULL, rid);
935 if (rd != res) 943 if (rd != res)
936 GNUNET_free (res); 944 GNUNET_free (res);
937 return; /* no data, no need to update cache */ 945 return; /* no data, no need to update cache */
@@ -943,7 +951,7 @@ refresh_block (struct NamestoreClient *nc,
943 1, 951 1,
944 GNUNET_NO); 952 GNUNET_NO);
945 if (NULL != nc) 953 if (NULL != nc)
946 send_store_response (nc, GNUNET_OK, rid); 954 send_store_response (nc, GNUNET_OK, NULL, rid);
947 if (rd != res) 955 if (rd != res)
948 GNUNET_free (res); 956 GNUNET_free (res);
949 return; 957 return;
@@ -1472,11 +1480,21 @@ get_block_exp_existing (void *cls,
1472{ 1480{
1473 struct GNUNET_TIME_Absolute *exp = cls; 1481 struct GNUNET_TIME_Absolute *exp = cls;
1474 struct GNUNET_GNSRECORD_Data rd_pub[rd_count]; 1482 struct GNUNET_GNSRECORD_Data rd_pub[rd_count];
1483 unsigned int rd_pub_count;
1484 char *emsg;
1475 1485
1476 GNUNET_GNSRECORD_convert_records_for_export (rd, 1486 if (GNUNET_OK != GNUNET_GNSRECORD_convert_records_for_export (label,
1487 rd,
1477 rd_count, 1488 rd_count,
1478 rd_pub, 1489 rd_pub,
1479 exp); 1490 &rd_pub_count,
1491 exp,
1492 &emsg))
1493 {
1494 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1495 "%s\n", emsg);
1496 GNUNET_free (emsg);
1497 }
1480} 1498}
1481 1499
1482 1500
@@ -1501,12 +1519,10 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1501 struct StoreActivity *sa; 1519 struct StoreActivity *sa;
1502 struct GNUNET_TIME_Absolute existing_block_exp; 1520 struct GNUNET_TIME_Absolute existing_block_exp;
1503 struct GNUNET_TIME_Absolute new_block_exp; 1521 struct GNUNET_TIME_Absolute new_block_exp;
1504 struct GNUNET_GNSRECORD_Data *tombstone_record;
1505 1522
1506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1523 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1507 "Received NAMESTORE_RECORD_STORE message\n"); 1524 "Received NAMESTORE_RECORD_STORE message\n");
1508 existing_block_exp.abs_value_us = 0; 1525 existing_block_exp.abs_value_us = 0;
1509 tombstone_record = NULL;
1510 rid = ntohl (rp_msg->gns_header.r_id); 1526 rid = ntohl (rp_msg->gns_header.r_id);
1511 name_len = ntohs (rp_msg->name_len); 1527 name_len = ntohs (rp_msg->name_len);
1512 rd_count = ntohs (rp_msg->rd_count); 1528 rd_count = ntohs (rp_msg->rd_count);
@@ -1560,21 +1576,23 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1560 /* remove "NICK" records, unless this is for the 1576 /* remove "NICK" records, unless this is for the
1561 #GNUNET_GNS_EMPTY_LABEL_AT label 1577 #GNUNET_GNS_EMPTY_LABEL_AT label
1562 We may need one additional record later for tombstone. 1578 We may need one additional record later for tombstone.
1579 FIXME: Since we must normalize the record set (check for
1580 consistency etc) we have to iterate the set twice.
1581 May be inefficient.
1582 We cannot really move the nick caching into GNSRECORD.
1563 */ 1583 */
1564 struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count) + 1]; 1584 struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)];
1585 struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1];
1565 unsigned int rd_clean_off; 1586 unsigned int rd_clean_off;
1587 unsigned int rd_nf_count;
1588 char *emsg;
1566 int have_nick; 1589 int have_nick;
1567 1590
1568 rd_clean_off = 0; 1591 rd_clean_off = 0;
1569 have_nick = GNUNET_NO; 1592 have_nick = GNUNET_NO;
1570 for (unsigned int i = 0; i < rd_count; i++) 1593 for (unsigned int i = 0; i < rd_count; i++)
1571 { 1594 {
1572 /* Do not allow to set tombstone records unless zonemaster */
1573 rd_clean[rd_clean_off] = rd[i]; 1595 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];
1576 if (GNUNET_YES == GNUNET_GNSRECORD_is_critical (rd[i].record_type))
1577 rd_clean[rd_clean_off].flags |= GNUNET_GNSRECORD_RF_CRITICAL;
1578 1596
1579 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) || 1597 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) ||
1580 (GNUNET_GNSRECORD_TYPE_NICK != rd[i].record_type)) 1598 (GNUNET_GNSRECORD_TYPE_NICK != rd[i].record_type))
@@ -1587,10 +1605,21 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1587 have_nick = GNUNET_YES; 1605 have_nick = GNUNET_YES;
1588 } 1606 }
1589 } 1607 }
1590 GNUNET_GNSRECORD_convert_records_for_export (rd, 1608 if (GNUNET_OK != GNUNET_GNSRECORD_normalize_record_set (conv_name,
1591 rd_clean_off, 1609 rd_clean,
1592 rd_clean, 1610 rd_clean_off,
1593 &new_block_exp); 1611 rd_nf,
1612 &rd_nf_count,
1613 &new_block_exp,
1614 GNUNET_YES,
1615 &emsg))
1616 {
1617 send_store_response (nc, res, emsg, rid);
1618 GNUNET_free (emsg);
1619 GNUNET_SERVICE_client_continue (nc->client);
1620 GNUNET_free (conv_name);
1621 return;
1622 }
1594 /* 1623 /*
1595 * If existing_block_exp is 0, then there was not record set 1624 * If existing_block_exp is 0, then there was not record set
1596 * and no tombstone. 1625 * and no tombstone.
@@ -1598,27 +1627,15 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1598 * new block expiration would be, we need to add a tombstone 1627 * new block expiration would be, we need to add a tombstone
1599 * or update it. 1628 * or update it.
1600 */ 1629 */
1601 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1602 "New exp: %s\n",
1603 GNUNET_STRINGS_absolute_time_to_string (new_block_exp));
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)) 1630 if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, existing_block_exp))
1608 { 1631 {
1609 /* There was already a TS record in the set given */ 1632 rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
1610 if (NULL != tombstone_record) 1633 rd_nf[rd_nf_count].expiration_time =
1611 { 1634 existing_block_exp.abs_value_us;
1612 tombstone_record->expiration_time = existing_block_exp.abs_value_us; 1635 rd_nf[rd_nf_count].data = NULL;
1613 } 1636 rd_nf[rd_nf_count].data_size = 0;
1614 else { 1637 rd_nf[rd_nf_count].flags |= GNUNET_GNSRECORD_RF_PRIVATE;
1615 rd_clean[rd_clean_off].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE; 1638 rd_nf_count++;
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 }
1622 } 1639 }
1623 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) && 1640 if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1624 (GNUNET_NO == have_nick)) 1641 (GNUNET_NO == have_nick))
@@ -1629,17 +1646,13 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1629 res = GSN_database->store_records (GSN_database->cls, 1646 res = GSN_database->store_records (GSN_database->cls,
1630 &rp_msg->private_key, 1647 &rp_msg->private_key,
1631 conv_name, 1648 conv_name,
1632 rd_clean_off, 1649 rd_nf_count,
1633 rd_clean); 1650 rd_nf);
1634 } 1651 }
1635 1652
1636 if (GNUNET_OK != res) 1653 if (GNUNET_OK != res)
1637 { 1654 {
1638 /* store not successful or zonemaster, not need to tell monitors */ 1655 /* store not successful or zonemaster, not need to tell monitors */
1639 send_store_response (nc, res, rid);
1640 GNUNET_SERVICE_client_continue (nc->client);
1641 GNUNET_free (conv_name);
1642 return;
1643 } 1656 }
1644 1657
1645 sa = GNUNET_malloc (sizeof(struct StoreActivity) 1658 sa = GNUNET_malloc (sizeof(struct StoreActivity)
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h
index 05a1d97ad..8391d9d74 100644
--- a/src/namestore/namestore.h
+++ b/src/namestore/namestore.h
@@ -113,6 +113,20 @@ struct RecordStoreResponseMessage
113 * #GNUNET_SYSERR on failure, #GNUNET_OK on success 113 * #GNUNET_SYSERR on failure, #GNUNET_OK on success
114 */ 114 */
115 int32_t op_result GNUNET_PACKED; 115 int32_t op_result GNUNET_PACKED;
116
117 /**
118 * Error message length
119 */
120 uint16_t emsg_len GNUNET_PACKED;
121
122 /**
123 * Reserved for alignment.
124 */
125 uint16_t reserved GNUNET_PACKED;
126
127 /**
128 * Followed by error message
129 */
116}; 130};
117 131
118 132
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index d4d06bab9..bb2f7465f 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -346,6 +346,44 @@ check_rd (size_t rd_len, const void *rd_buf, unsigned int rd_count)
346 return GNUNET_OK; 346 return GNUNET_OK;
347} 347}
348 348
349/**
350 * Handle an incoming message of type
351 * #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
352 *
353 * @param cls
354 * @param msg the message we received
355 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
356 */
357static int
358check_record_store_response (void *cls,
359 const struct RecordStoreResponseMessage *msg)
360{
361 const char *emsg;
362 size_t msg_len;
363 size_t emsg_len;
364
365 (void) cls;
366 msg_len = ntohs (msg->gns_header.header.size);
367 emsg_len = ntohs (msg->emsg_len);
368 if (0 != ntohs (msg->reserved))
369 {
370 GNUNET_break (0);
371 return GNUNET_SYSERR;
372 }
373 if (msg_len != sizeof(struct RecordStoreResponseMessage) + emsg_len)
374 {
375 GNUNET_break (0);
376 return GNUNET_SYSERR;
377 }
378 emsg = (const char *) &msg[1];
379 if ((0 != emsg_len) && ('\0' != emsg[emsg_len - 1]))
380 {
381 GNUNET_break (0);
382 return GNUNET_SYSERR;
383 }
384 return GNUNET_OK;
385}
386
349 387
350/** 388/**
351 * Handle an incoming message of type 389 * Handle an incoming message of type
@@ -364,15 +402,11 @@ handle_record_store_response (void *cls,
364 const char *emsg; 402 const char *emsg;
365 403
366 qe = find_qe (h, ntohl (msg->gns_header.r_id)); 404 qe = find_qe (h, ntohl (msg->gns_header.r_id));
405 emsg = (const char *) &msg[1];
367 res = ntohl (msg->op_result); 406 res = ntohl (msg->op_result);
368 LOG (GNUNET_ERROR_TYPE_DEBUG, 407 LOG (GNUNET_ERROR_TYPE_DEBUG,
369 "Received RECORD_STORE_RESPONSE with result %d\n", 408 "Received RECORD_STORE_RESPONSE with result %d\n",
370 res); 409 res);
371 /* TODO: add actual error message from namestore to response... */
372 if (GNUNET_SYSERR == res)
373 emsg = _ ("Namestore failed to store record\n");
374 else
375 emsg = NULL;
376 if (NULL == qe) 410 if (NULL == qe)
377 return; 411 return;
378 if (NULL != qe->cont) 412 if (NULL != qe->cont)
@@ -775,7 +809,7 @@ static void
775reconnect (struct GNUNET_NAMESTORE_Handle *h) 809reconnect (struct GNUNET_NAMESTORE_Handle *h)
776{ 810{
777 struct GNUNET_MQ_MessageHandler handlers[] = 811 struct GNUNET_MQ_MessageHandler handlers[] =
778 { GNUNET_MQ_hd_fixed_size (record_store_response, 812 { GNUNET_MQ_hd_var_size (record_store_response,
779 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE, 813 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE,
780 struct RecordStoreResponseMessage, 814 struct RecordStoreResponseMessage,
781 h), 815 h),