aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-03-16 22:11:05 +0100
committerMartin Schanzenbach <schanzen@gnunet.org>2022-03-16 22:11:05 +0100
commit8c02a122d7a38afe7aa2e8cd530b606da027963e (patch)
tree91d15c70b7132eebe7ddc45727e511c37551a91d /src
parent1128bfacad7003d92fd2bafcde61a53c15894a7a (diff)
downloadgnunet-8c02a122d7a38afe7aa2e8cd530b606da027963e.tar.gz
gnunet-8c02a122d7a38afe7aa2e8cd530b606da027963e.zip
-better lock handling/refactoring !coverity
Diffstat (limited to 'src')
-rw-r--r--src/namestore/gnunet-service-namestore.c162
1 files changed, 105 insertions, 57 deletions
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c
index 5d43488a1..20e5bb1b2 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -1421,6 +1421,91 @@ calculate_lock_hash (const char *label,
1421 GNUNET_CRYPTO_hash_context_finish (hctx, result); 1421 GNUNET_CRYPTO_hash_context_finish (hctx, result);
1422} 1422}
1423 1423
1424/**
1425 * Release a lock on a record set.
1426 * Does nothing if lock not held.
1427 *
1428 * @param label the label of the record set
1429 * @param zone the zone
1430 * @param nc the client releasing the lock
1431 */
1432static void
1433NST_label_lock_release (const char *label,
1434 const struct GNUNET_IDENTITY_PrivateKey *zone,
1435 const struct NamestoreClient *nc)
1436{
1437 struct GNUNET_HashCode label_hash;
1438 struct RecordsLock *lock;
1439
1440 calculate_lock_hash (label, zone, &label_hash);
1441 for (lock = locks_head; NULL != lock; lock = lock->next)
1442 if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash)))
1443 break;
1444 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1445 "Record locked: %s\n", (NULL == lock) ? "No" : "Yes");
1446 if (NULL == lock)
1447 return;
1448 if (lock->client != nc)
1449 {
1450 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1451 "Lock is held by other client on `%s'\n", label);
1452 return;
1453 }
1454 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1455 "Unocking %s\n", GNUNET_h2s (&label_hash));
1456 GNUNET_CONTAINER_DLL_remove (locks_head,
1457 locks_tail,
1458 lock);
1459 GNUNET_free (lock);
1460}
1461
1462/**
1463 * Get/set a lock on a record set.
1464 * May be called multiple times but will
1465 * not aquire additional locks.
1466 *
1467 * @param the label of the record set
1468 * @param the zone
1469 * @param the client doing the locking
1470 * @return GNUNET_YES if lock retrieved or set already.
1471 */
1472static enum GNUNET_GenericReturnValue
1473NST_label_lock (const char *label,
1474 const struct GNUNET_IDENTITY_PrivateKey *zone,
1475 struct NamestoreClient *nc)
1476{
1477 struct GNUNET_HashCode label_hash;
1478 struct RecordsLock *lock;
1479
1480 calculate_lock_hash (label, zone, &label_hash);
1481 for (lock = locks_head; NULL != lock; lock = lock->next)
1482 if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash)))
1483 break;
1484 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1485 "Record locked: %s\n", (NULL == lock) ? "No" : "Yes");
1486 if (NULL != lock)
1487 {
1488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1489 "Client holds lock: %s\n", (lock->client != nc) ? "No" : "Yes");
1490 if (lock->client != nc)
1491 {
1492 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1493 "Lock is held by other client on `%s'\n", label);
1494 return GNUNET_NO;
1495 }
1496 return GNUNET_YES;
1497 }
1498 lock = GNUNET_new (struct RecordsLock);
1499 lock->client = nc;
1500 memcpy (&lock->label_hash, &label_hash, sizeof (label_hash));
1501 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1502 "Locking %s\n", GNUNET_h2s (&label_hash));
1503 GNUNET_CONTAINER_DLL_insert (locks_head,
1504 locks_tail,
1505 lock);
1506 return GNUNET_YES;
1507}
1508
1424 1509
1425/** 1510/**
1426 * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message 1511 * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message
@@ -1461,47 +1546,24 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
1461 name_len = strlen (conv_name) + 1; 1546 name_len = strlen (conv_name) + 1;
1462 if (GNUNET_YES == ntohl (ll_msg->locking)) 1547 if (GNUNET_YES == ntohl (ll_msg->locking))
1463 { 1548 {
1464 calculate_lock_hash (conv_name, &ll_msg->zone, &label_hash); 1549 if (GNUNET_NO == NST_label_lock (conv_name, &ll_msg->zone, nc))
1465 for (lock = locks_head; NULL != lock; lock = lock->next)
1466 if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash)))
1467 break;
1468 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1469 "Record locked: %s\n", (NULL == lock) ? "No" : "Yes");
1470 if (NULL != lock)
1471 { 1550 {
1472 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1551 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1473 "Client holds lock: %s\n", (lock->client != nc) ? "No" : "Yes"); 1552 "Lock is held by other client on `%s'\n", conv_name);
1474 1553 env =
1475 if (lock->client != nc) 1554 GNUNET_MQ_msg_extra (llr_msg,
1476 { 1555 name_len,
1477 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1556 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE);
1478 "Lock is held by other client on `%s'\n", conv_name); 1557 llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1479 env = 1558 llr_msg->private_key = ll_msg->zone;
1480 GNUNET_MQ_msg_extra (llr_msg, 1559 llr_msg->name_len = htons (name_len);
1481 name_len, 1560 llr_msg->rd_count = htons (0);
1482 GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE); 1561 llr_msg->rd_len = htons (0);
1483 llr_msg->gns_header.r_id = ll_msg->gns_header.r_id; 1562 llr_msg->found = htons (GNUNET_SYSERR);
1484 llr_msg->private_key = ll_msg->zone; 1563 GNUNET_memcpy (&llr_msg[1], conv_name, name_len);
1485 llr_msg->name_len = htons (name_len); 1564 GNUNET_MQ_send (nc->mq, env);
1486 llr_msg->rd_count = htons (0); 1565 GNUNET_free (conv_name);
1487 llr_msg->rd_len = htons (0); 1566 return;
1488 llr_msg->found = htons (GNUNET_SYSERR);
1489 GNUNET_memcpy (&llr_msg[1], conv_name, name_len);
1490 GNUNET_MQ_send (nc->mq, env);
1491 GNUNET_free (conv_name);
1492 return;
1493 }
1494 }
1495 else
1496 {
1497 lock = GNUNET_new (struct RecordsLock);
1498 lock->client = nc;
1499 memcpy (&lock->label_hash, &label_hash, sizeof (label_hash));
1500 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1501 "Locking %s\n", GNUNET_h2s (&label_hash));
1502 GNUNET_CONTAINER_DLL_insert (locks_head,
1503 locks_tail,
1504 lock);
1505 } 1567 }
1506 } 1568 }
1507 rlc.label = conv_name; 1569 rlc.label = conv_name;
@@ -1693,12 +1755,7 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1693 } 1755 }
1694 if (GNUNET_YES == ntohl (rp_msg->locking)) 1756 if (GNUNET_YES == ntohl (rp_msg->locking))
1695 { 1757 {
1696 calculate_lock_hash (conv_name, &rp_msg->private_key, &label_hash); 1758 if (GNUNET_NO == NST_label_lock (conv_name, &rp_msg->private_key, nc))
1697 for (lock = locks_head; NULL != lock; lock = lock->next)
1698 if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash)))
1699 break;
1700 if ((NULL == lock) ||
1701 (lock->client != nc))
1702 { 1759 {
1703 send_store_response (nc, res, _ ("Record set locked."), rid); 1760 send_store_response (nc, res, _ ("Record set locked."), rid);
1704 GNUNET_SERVICE_client_continue (nc->client); 1761 GNUNET_SERVICE_client_continue (nc->client);
@@ -1707,6 +1764,8 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1707 } 1764 }
1708 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1765 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1709 "Client has lock on `%s', continuing.\n", conv_name); 1766 "Client has lock on `%s', continuing.\n", conv_name);
1767 if (GNUNET_YES == ntohl (rp_msg->locking))
1768 NST_label_lock_release (conv_name, &rp_msg->private_key, nc);
1710 } 1769 }
1711 1770
1712 GNUNET_STATISTICS_update (statistics, 1771 GNUNET_STATISTICS_update (statistics,
@@ -1817,17 +1876,6 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
1817 GNUNET_free (conv_name); 1876 GNUNET_free (conv_name);
1818 return; 1877 return;
1819 } 1878 }
1820 if (GNUNET_YES == ntohl (rp_msg->locking))
1821 {
1822 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1823 "Releasing lock on `%s'\n", conv_name);
1824 GNUNET_assert (NULL != lock);
1825 GNUNET_CONTAINER_DLL_remove (locks_head,
1826 locks_tail,
1827 lock);
1828 GNUNET_free (lock);
1829 }
1830
1831 sa = GNUNET_malloc (sizeof(struct StoreActivity) 1879 sa = GNUNET_malloc (sizeof(struct StoreActivity)
1832 + ntohs (rp_msg->gns_header.header.size)); 1880 + ntohs (rp_msg->gns_header.header.size));
1833 GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa); 1881 GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa);