diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-03-16 22:11:05 +0100 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-03-16 22:11:05 +0100 |
commit | 8c02a122d7a38afe7aa2e8cd530b606da027963e (patch) | |
tree | 91d15c70b7132eebe7ddc45727e511c37551a91d | |
parent | 1128bfacad7003d92fd2bafcde61a53c15894a7a (diff) | |
download | gnunet-8c02a122d7a38afe7aa2e8cd530b606da027963e.tar.gz gnunet-8c02a122d7a38afe7aa2e8cd530b606da027963e.zip |
-better lock handling/refactoring !coverity
-rw-r--r-- | src/namestore/gnunet-service-namestore.c | 162 |
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 | */ | ||
1432 | static void | ||
1433 | NST_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 | */ | ||
1472 | static enum GNUNET_GenericReturnValue | ||
1473 | NST_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); |