From 4e95b59a6f3cd35c9c1b5dcdc6320f0e0dfef79b Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Mon, 21 Mar 2022 13:54:28 +0100 Subject: NAMESTORE: Towards new transaction-based API --- contrib/gana | 2 +- src/include/gnunet_namestore_service.h | 156 ++++++++----- src/namestore/Makefile.am | 11 - src/namestore/gnunet-service-namestore.c | 183 --------------- src/namestore/namestore.h | 10 - src/namestore/namestore_api.c | 115 +++++---- src/namestore/test_namestore_api_store_locking.c | 283 ----------------------- 7 files changed, 169 insertions(+), 591 deletions(-) delete mode 100644 src/namestore/test_namestore_api_store_locking.c diff --git a/contrib/gana b/contrib/gana index baeb82036..048ad729b 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit baeb820366b88befd6f5aa2a551e2827ef406daf +Subproject commit 048ad729b3177a5de1726517bc905e6cd7688d0d diff --git a/src/include/gnunet_namestore_service.h b/src/include/gnunet_namestore_service.h index 619b81aed..86572803f 100644 --- a/src/include/gnunet_namestore_service.h +++ b/src/include/gnunet_namestore_service.h @@ -211,61 +211,6 @@ GNUNET_NAMESTORE_records_lookup (struct GNUNET_NAMESTORE_Handle *h, void *rm_cls); -/** - * Open a record set for editing. - * Retrieves an exclusive lock on this set. - * Must be commited using @a GNUNET_NAMESTORE_records_commit - * - * @param h handle to the namestore - * @param pkey private key of the zone - * @param label name that is being mapped - * @param error_cb function to call on error (i.e. disconnect or unable to get lock) - * the handle is afterwards invalid - * @param error_cb_cls closure for @a error_cb - * @param rm function to call with the result (with 0 records if we don't have that label) - * @param rm_cls closure for @a rm - * @return handle to abort the request - */ -struct GNUNET_NAMESTORE_QueueEntry * -GNUNET_NAMESTORE_records_open (struct GNUNET_NAMESTORE_Handle *h, - const struct - GNUNET_IDENTITY_PrivateKey *pkey, - const char *label, - GNUNET_SCHEDULER_TaskCallback error_cb, - void *error_cb_cls, - GNUNET_NAMESTORE_RecordMonitor rm, - void *rm_cls); - -/** - * Commit the record set to the namestore. - * Releases the lock on the record set. - * Use an empty array to - * remove all records under the given name. - * - * The continuation is called after the value has been stored in the - * database. Monitors may be notified asynchronously (basically with - * a buffer). However, if any monitor is consistently too slow to - * keep up with the changes, calling @a cont will be delayed until the - * monitors do keep up. - * - * @param h handle to the namestore - * @param pkey private key of the zone - * @param label name that is being mapped - * @param rd_count number of records in the 'rd' array - * @param rd array of records with data to store - * @param cont continuation to call when done - * @param cont_cls closure for @a cont - * @return handle to abort the request - */ -struct GNUNET_NAMESTORE_QueueEntry * -GNUNET_NAMESTORE_records_commit (struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_IDENTITY_PrivateKey *pkey, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd, - GNUNET_NAMESTORE_ContinuationWithStatus cont, - void *cont_cls); - /** * Look for an existing PKEY delegation record for a given public key. * Returns at most one result to the processor. @@ -448,6 +393,107 @@ void GNUNET_NAMESTORE_zone_monitor_stop (struct GNUNET_NAMESTORE_ZoneMonitor *zm); +/** + * New API draft. Experimental + */ + +/** + * Begin a namestore transaction. + * + * @param h handle to the namestore + * @param error_cb function to call on error (i.e. disconnect or unable to get lock) + * the handle is afterwards invalid + * @param error_cb_cls closure for @a error_cb + * @return handle to abort the request + */ +struct GNUNET_NAMESTORE_QueueEntry * +GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h, + GNUNET_SCHEDULER_TaskCallback error_cb, + void *error_cb_cls); + +/** + * Begin rollback all actions in a transaction. + * Reverts all actions performed since #GNUNET_NAMESTORE_transaction_begin + * + * @param h handle to the namestore + * @param error_cb function to call on error (i.e. disconnect or unable to get lock) + * the handle is afterwards invalid + * @param error_cb_cls closure for @a error_cb + * @return handle to abort the request + */ +struct GNUNET_NAMESTORE_QueueEntry * +GNUNET_NAMESTORE_transaction_abort (struct GNUNET_NAMESTORE_Handle *h, + GNUNET_SCHEDULER_TaskCallback error_cb, + void *error_cb_cls); +/** + * Commit a namestore transaction. + * Saves all actions performed since #GNUNET_NAMESTORE_transaction_begin + * + * @param h handle to the namestore + * @param error_cb function to call on error (i.e. disconnect or unable to get lock) + * the handle is afterwards invalid + * @param error_cb_cls closure for @a error_cb + * @return handle to abort the request + */ +struct GNUNET_NAMESTORE_QueueEntry * +GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h, + GNUNET_SCHEDULER_TaskCallback error_cb, + void *error_cb_cls); + +/** + * Lookup an item in the namestore. + * + * @param h handle to the namestore + * @param pkey private key of the zone + * @param label name that is being mapped + * @param error_cb function to call on error (i.e. disconnect) + * the handle is afterwards invalid + * @param error_cb_cls closure for @a error_cb + * @param rm function to call with the result (with 0 records if we don't have that label); + * the handle is afterwards invalid + * @param rm_cls closure for @a rm + * @return handle to abort the request + */ +struct GNUNET_NAMESTORE_QueueEntry * +GNUNET_NAMESTORE_records_select (struct GNUNET_NAMESTORE_Handle *h, + const struct + GNUNET_IDENTITY_PrivateKey *pkey, + const char *label, + GNUNET_SCHEDULER_TaskCallback error_cb, + void *error_cb_cls, + GNUNET_NAMESTORE_RecordMonitor rm, + void *rm_cls); + + +/** + * Creates, deletes or updates an item in the namestore. + * If the item is already present, it is replaced with the new record set. + * Use an empty array to remove all records under the given name. + * + * The continuation is called after the value has been stored in the + * database. Monitors may be notified asynchronously (basically with + * a buffer). However, if any monitor is consistently too slow to + * keep up with the changes, calling @a cont will be delayed until the + * monitors do keep up. + * + * @param h handle to the namestore + * @param pkey private key of the zone + * @param label name that is being mapped + * @param rd_count number of records in the 'rd' array + * @param rd array of records with data to store + * @param cont continuation to call when done + * @param cont_cls closure for @a cont + * @return handle to abort the request + */ +struct GNUNET_NAMESTORE_QueueEntry * +GNUNET_NAMESTORE_records_replace (struct GNUNET_NAMESTORE_Handle *h, + const struct GNUNET_IDENTITY_PrivateKey *pkey, + const char *label, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd, + GNUNET_NAMESTORE_ContinuationWithStatus cont, + void *cont_cls); + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am index 2441b864a..51708dd67 100644 --- a/src/namestore/Makefile.am +++ b/src/namestore/Makefile.am @@ -39,7 +39,6 @@ if HAVE_SQLITE SQLITE_PLUGIN = libgnunet_plugin_namestore_sqlite.la SQLITE_TESTS = test_plugin_namestore_sqlite \ test_namestore_api_store_sqlite \ - test_namestore_api_store_locking_sqlite \ test_namestore_api_store_update_sqlite \ test_namestore_api_zone_iteration_sqlite \ test_namestore_api_remove_sqlite \ @@ -250,16 +249,6 @@ test_namestore_api_store_sqlite_LDADD = \ $(top_builddir)/src/identity/libgnunetidentity.la \ libgnunetnamestore.la -test_namestore_api_store_locking_sqlite_SOURCES = \ - test_namestore_api_store_locking.c -test_namestore_api_store_locking_sqlite_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ - $(top_builddir)/src/identity/libgnunetidentity.la \ - libgnunetnamestore.la - - test_namestore_api_store_postgres_SOURCES = \ test_namestore_api_store.c test_namestore_api_store_postgres_LDADD = \ diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index d735822fb..95260ff9c 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c @@ -121,24 +121,6 @@ struct ZoneIteration int send_end; }; -/** - * Lock on a record set - */ -struct RecordsLock -{ - /* DLL */ - struct RecordsLock *prev; - - /* DLL */ - struct RecordsLock *next; - - /* Hash of the locked label */ - struct GNUNET_HashCode label_hash; - - /* Client locking the zone */ - struct NamestoreClient *client; -}; - /** * A namestore client */ @@ -410,16 +392,6 @@ static struct StoreActivity *sa_head; */ static struct StoreActivity *sa_tail; -/** - * Head of the DLL of record set locks - */ -static struct RecordsLock *locks_head; - -/** - * Tail of the DLL of record set locks - */ -static struct RecordsLock *locks_tail; - /** * Notification context shared by all monitors. */ @@ -447,7 +419,6 @@ static void cleanup_task (void *cls) { struct CacheOperation *cop; - struct RecordsLock *lock; (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); @@ -459,13 +430,6 @@ cleanup_task (void *cls) GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); GNUNET_free (cop); } - while (NULL != (lock = locks_head)) - { - GNUNET_CONTAINER_DLL_remove (locks_head, - locks_tail, - lock); - GNUNET_free (lock); - } if (NULL != namecache) { @@ -1154,7 +1118,6 @@ client_disconnect_cb (void *cls, struct NamestoreClient *nc = app_ctx; struct ZoneIteration *no; struct CacheOperation *cop; - struct RecordsLock *lock; (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client); @@ -1205,15 +1168,6 @@ client_disconnect_cb (void *cls, for (cop = cop_head; NULL != cop; cop = cop->next) if (nc == cop->nc) cop->nc = NULL; - for (lock = locks_head; NULL != lock; lock = lock->next) - { - if (nc != lock->client) - continue; - GNUNET_CONTAINER_DLL_remove (locks_head, - locks_tail, - lock); - GNUNET_free (lock); - } GNUNET_free (nc); } @@ -1407,105 +1361,6 @@ check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) return GNUNET_OK; } -static void -calculate_lock_hash (const char *label, - const struct GNUNET_IDENTITY_PrivateKey *zone, - struct GNUNET_HashCode *result) -{ - struct GNUNET_HashContext *hctx; - - hctx = GNUNET_CRYPTO_hash_context_start (); - GNUNET_CRYPTO_hash_context_read (hctx, label, strlen (label)); - GNUNET_CRYPTO_hash_context_read (hctx, zone, - sizeof (*zone)); - GNUNET_CRYPTO_hash_context_finish (hctx, result); -} - -/** - * Release a lock on a record set. - * Does nothing if lock not held. - * - * @param label the label of the record set - * @param zone the zone - * @param nc the client releasing the lock - */ -static void -NST_label_lock_release (const char *label, - const struct GNUNET_IDENTITY_PrivateKey *zone, - const struct NamestoreClient *nc) -{ - struct GNUNET_HashCode label_hash; - struct RecordsLock *lock; - - calculate_lock_hash (label, zone, &label_hash); - for (lock = locks_head; NULL != lock; lock = lock->next) - if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash))) - break; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Record locked: %s\n", (NULL == lock) ? "No" : "Yes"); - if (NULL == lock) - return; - if (lock->client != nc) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Lock is held by other client on `%s'\n", label); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Unocking %s\n", GNUNET_h2s (&label_hash)); - GNUNET_CONTAINER_DLL_remove (locks_head, - locks_tail, - lock); - GNUNET_free (lock); -} - -/** - * Get/set a lock on a record set. - * May be called multiple times but will - * not aquire additional locks. - * - * @param the label of the record set - * @param the zone - * @param the client doing the locking - * @return GNUNET_YES if lock retrieved or set already. - */ -static enum GNUNET_GenericReturnValue -NST_label_lock (const char *label, - const struct GNUNET_IDENTITY_PrivateKey *zone, - struct NamestoreClient *nc) -{ - struct GNUNET_HashCode label_hash; - struct RecordsLock *lock; - - calculate_lock_hash (label, zone, &label_hash); - for (lock = locks_head; NULL != lock; lock = lock->next) - if (0 == memcmp (&label_hash, &lock->label_hash, sizeof (label_hash))) - break; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Record locked: %s\n", (NULL == lock) ? "No" : "Yes"); - if (NULL != lock) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Client holds lock: %s\n", (lock->client != nc) ? "No" : "Yes"); - if (lock->client != nc) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Lock is held by other client on `%s'\n", label); - return GNUNET_NO; - } - return GNUNET_YES; - } - lock = GNUNET_new (struct RecordsLock); - lock->client = nc; - memcpy (&lock->label_hash, &label_hash, sizeof (label_hash)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Locking %s\n", GNUNET_h2s (&label_hash)); - GNUNET_CONTAINER_DLL_insert (locks_head, - locks_tail, - lock); - return GNUNET_YES; -} - /** * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message @@ -1520,7 +1375,6 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) struct GNUNET_MQ_Envelope *env; struct LabelLookupResponseMessage *llr_msg; struct RecordLookupContext rlc; - struct RecordsLock *lock; struct GNUNET_HashCode label_hash; const char *name_tmp; char *res_name; @@ -1544,28 +1398,6 @@ handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg) return; } name_len = strlen (conv_name) + 1; - if (GNUNET_YES == ntohl (ll_msg->locking)) - { - if (GNUNET_NO == NST_label_lock (conv_name, &ll_msg->zone, nc)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Lock is held by other client on `%s'\n", conv_name); - env = - GNUNET_MQ_msg_extra (llr_msg, - name_len, - GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE); - llr_msg->gns_header.r_id = ll_msg->gns_header.r_id; - llr_msg->private_key = ll_msg->zone; - llr_msg->name_len = htons (name_len); - llr_msg->rd_count = htons (0); - llr_msg->rd_len = htons (0); - llr_msg->found = htons (GNUNET_SYSERR); - GNUNET_memcpy (&llr_msg[1], conv_name, name_len); - GNUNET_MQ_send (nc->mq, env); - GNUNET_free (conv_name); - return; - } - } rlc.label = conv_name; rlc.found = GNUNET_NO; rlc.res_rd_count = 0; @@ -1699,7 +1531,6 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) unsigned int rd_count; int res; struct StoreActivity *sa; - struct RecordsLock *lock; struct GNUNET_HashCode label_hash; struct GNUNET_TIME_Absolute existing_block_exp; struct GNUNET_TIME_Absolute new_block_exp; @@ -1753,20 +1584,6 @@ handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg) GNUNET_SERVICE_client_continue (nc->client); return; } - if (GNUNET_YES == ntohl (rp_msg->locking)) - { - if (GNUNET_NO == NST_label_lock (conv_name, &rp_msg->private_key, nc)) - { - send_store_response (nc, GNUNET_SYSERR, _ ("Record set locked."), rid); - GNUNET_SERVICE_client_continue (nc->client); - GNUNET_free (conv_name); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Client has lock on `%s', continuing.\n", conv_name); - if (GNUNET_YES == ntohl (rp_msg->locking)) - NST_label_lock_release (conv_name, &rp_msg->private_key, nc); - } GNUNET_STATISTICS_update (statistics, "Well-formed store requests received", diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index 0f3ffa837..583ec1e68 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h @@ -67,11 +67,6 @@ struct RecordStoreMessage */ struct GNUNET_TIME_AbsoluteNBO expire; - /** - * Unock the label with this request. - */ - uint32_t locking GNUNET_PACKED; - /** * Name length */ @@ -150,11 +145,6 @@ struct LabelLookupMessage */ uint32_t label_len GNUNET_PACKED; - /** - * Lock the label with this lookup - */ - uint32_t locking GNUNET_PACKED; - /** * The private key of the zone to look up in */ diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index a7380bbde..73f985803 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c @@ -411,7 +411,7 @@ handle_record_store_response (void *cls, return; if (NULL != qe->cont) qe->cont (qe->cont_cls, res, - (GNUNET_OK == res) ? NULL : emsg); + (GNUNET_OK == res) ? NULL : emsg); free_qe (qe); } @@ -482,7 +482,7 @@ handle_lookup_result (void *cls, const struct LabelLookupResponseMessage *msg) int16_t found = (int16_t) ntohs (msg->found); LOG (GNUNET_ERROR_TYPE_DEBUG, "Received RECORD_LOOKUP_RESULT (found=%i)\n", - found); + found); qe = find_qe (h, ntohl (msg->gns_header.r_id)); if (NULL == qe) return; @@ -820,9 +820,9 @@ reconnect (struct GNUNET_NAMESTORE_Handle *h) { struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size (record_store_response, - GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE, - struct RecordStoreResponseMessage, - h), + GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE, + struct RecordStoreResponseMessage, + h), GNUNET_MQ_hd_var_size (zone_to_name_response, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE, struct ZoneToNameResponseMessage, @@ -1013,16 +1013,16 @@ warn_delay (void *cls) GNUNET_NAMESTORE_cancel (qe); } + struct GNUNET_NAMESTORE_QueueEntry * -records_store_ ( +GNUNET_NAMESTORE_records_store ( struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, GNUNET_NAMESTORE_ContinuationWithStatus cont, - void *cont_cls, - int locking) + void *cont_cls) { struct GNUNET_NAMESTORE_QueueEntry *qe; struct GNUNET_MQ_Envelope *env; @@ -1067,9 +1067,8 @@ records_store_ ( msg->name_len = htons (name_len); msg->rd_count = htons (rd_count); msg->rd_len = htons (rd_ser_len); - msg->reserved = ntohs(0); + msg->reserved = ntohs (0); msg->private_key = *pkey; - msg->locking = htonl (locking); name_tmp = (char *) &msg[1]; GNUNET_memcpy (name_tmp, label, name_len); @@ -1101,22 +1100,11 @@ records_store_ ( return qe; } +/** + * TODO: Experimental API will replace API above. + */ struct GNUNET_NAMESTORE_QueueEntry * -GNUNET_NAMESTORE_records_store ( - struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_IDENTITY_PrivateKey *pkey, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd, - GNUNET_NAMESTORE_ContinuationWithStatus cont, - void *cont_cls) -{ - return records_store_ (h, pkey, label, - rd_count, rd, cont, cont_cls, GNUNET_NO); -} - -struct GNUNET_NAMESTORE_QueueEntry * -GNUNET_NAMESTORE_records_commit ( +GNUNET_NAMESTORE_records_replace ( struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, @@ -1125,21 +1113,19 @@ GNUNET_NAMESTORE_records_commit ( GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls) { - return records_store_ (h, pkey, label, - rd_count, rd, cont, cont_cls, GNUNET_YES); + return GNUNET_NAMESTORE_records_store (h, pkey, label, rd_count, rd, + cont, cont_cls); } - struct GNUNET_NAMESTORE_QueueEntry * -records_lookup_ ( +GNUNET_NAMESTORE_records_lookup ( struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor rm, - void *rm_cls, - int locking) + void *rm_cls) { struct GNUNET_NAMESTORE_QueueEntry *qe; struct GNUNET_MQ_Envelope *env; @@ -1167,7 +1153,6 @@ records_lookup_ ( msg->gns_header.r_id = htonl (qe->op_id); msg->zone = *pkey; msg->label_len = htonl (label_len); - msg->locking = htonl (locking); GNUNET_memcpy (&msg[1], label, label_len); if (NULL == h->mq) qe->env = env; @@ -1176,22 +1161,12 @@ records_lookup_ ( return qe; } -struct GNUNET_NAMESTORE_QueueEntry * -GNUNET_NAMESTORE_records_lookup ( - struct GNUNET_NAMESTORE_Handle *h, - const struct GNUNET_IDENTITY_PrivateKey *pkey, - const char *label, - GNUNET_SCHEDULER_TaskCallback error_cb, - void *error_cb_cls, - GNUNET_NAMESTORE_RecordMonitor rm, - void *rm_cls) -{ - return records_lookup_ (h, pkey, label, - error_cb, error_cb_cls, rm, rm_cls, GNUNET_NO); -} +/** + * TODO experimental API. Will replace old API above. + */ struct GNUNET_NAMESTORE_QueueEntry * -GNUNET_NAMESTORE_records_open ( +GNUNET_NAMESTORE_records_select ( struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *pkey, const char *label, @@ -1200,8 +1175,9 @@ GNUNET_NAMESTORE_records_open ( GNUNET_NAMESTORE_RecordMonitor rm, void *rm_cls) { - return records_lookup_ (h, pkey, label, - error_cb, error_cb_cls, rm, rm_cls, GNUNET_YES); + return GNUNET_NAMESTORE_records_lookup (h, pkey, label, + error_cb, error_cb_cls, + rm, rm_cls); } struct GNUNET_NAMESTORE_QueueEntry * @@ -1364,5 +1340,48 @@ GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe) free_qe (qe); } +/** + * New API draft. Experimental + */ + +struct GNUNET_NAMESTORE_QueueEntry * +GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h, + GNUNET_SCHEDULER_TaskCallback error_cb, + void *error_cb_cls) +{ + GNUNET_break (0); + return NULL; +} + + +struct GNUNET_NAMESTORE_QueueEntry * +GNUNET_NAMESTORE_transaction_abort (struct GNUNET_NAMESTORE_Handle *h, + GNUNET_SCHEDULER_TaskCallback error_cb, + void *error_cb_cls) +{ + GNUNET_break (0); + return NULL; +} + + +/** + * Commit a namestore transaction. + * Saves all actions performed since #GNUNET_NAMESTORE_transaction_begin + * + * @param h handle to the namestore + * @param error_cb function to call on error (i.e. disconnect or unable to get lock) + * the handle is afterwards invalid + * @param error_cb_cls closure for @a error_cb + * @return handle to abort the request + */ +struct GNUNET_NAMESTORE_QueueEntry * +GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h, + GNUNET_SCHEDULER_TaskCallback error_cb, + void *error_cb_cls) +{ + GNUNET_break (0); + return NULL; +} + /* end of namestore_api.c */ diff --git a/src/namestore/test_namestore_api_store_locking.c b/src/namestore/test_namestore_api_store_locking.c deleted file mode 100644 index a80cad523..000000000 --- a/src/namestore/test_namestore_api_store_locking.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2012 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - - SPDX-License-Identifier: AGPL3.0-or-later - */ -/** - * @file namestore/test_namestore_api_store_locking.c - * @brief testcase for namestore_api.c: store a record, locking - */ -#include "platform.h" -#include "gnunet_namestore_service.h" -#include "gnunet_testing_lib.h" -#include "gnunet_dnsparser_lib.h" - -#define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT - -#define TEST_RECORD_DATALEN 123 - -#define TEST_RECORD_DATA 'a' - -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100) - - -static struct GNUNET_NAMESTORE_Handle *nsh; - -static struct GNUNET_NAMESTORE_Handle *nsh_alt; - -static struct GNUNET_SCHEDULER_Task *endbadly_task; - -static struct GNUNET_IDENTITY_PrivateKey privkey; - -static struct GNUNET_IDENTITY_PublicKey pubkey; - -static int res; - -static struct GNUNET_NAMESTORE_QueueEntry *nsqe; - -static struct GNUNET_NAMESTORE_QueueEntry *nsqe_alt; - - -static void -cleanup () -{ - if (NULL != nsh) - { - GNUNET_NAMESTORE_disconnect (nsh); - nsh = NULL; - } - if (NULL != nsh_alt) - { - GNUNET_NAMESTORE_disconnect (nsh_alt); - nsh_alt = NULL; - } - GNUNET_SCHEDULER_shutdown (); -} - - -/** - * Re-establish the connection to the service. - * - * @param cls handle to use to re-connect. - */ -static void -endbadly (void *cls) -{ - if (NULL != nsqe) - { - GNUNET_NAMESTORE_cancel (nsqe); - nsqe = NULL; - } - cleanup (); - res = 1; -} - - -static void -end (void *cls) -{ - cleanup (); - res = 0; -} - - -static void -open_alt_second_failed (void *cls) -{ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Got did not get lock when I should...\n"); - nsqe_alt = NULL; - GNUNET_SCHEDULER_cancel (endbadly_task); - endbadly_task = NULL; - GNUNET_SCHEDULER_add_now (&endbadly, NULL); -} - - -void -open_alt_second_cont (void *cls, - const struct - GNUNET_IDENTITY_PrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd) -{ - nsqe_alt = NULL; - GNUNET_SCHEDULER_cancel (endbadly_task); - endbadly_task = NULL; - GNUNET_SCHEDULER_add_now (&end, NULL); -} - - -static void -put_cont (void *cls, int32_t success, const char *emsg) -{ - const char *name = cls; - - nsqe = NULL; - GNUNET_assert (NULL != cls); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Name store added record for `%s': %s\n", - name, - (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); - /* This should not work */ - nsqe_alt = GNUNET_NAMESTORE_records_open (nsh_alt, - &privkey, - name, - &open_alt_second_failed, - NULL, - &open_alt_second_cont, - NULL); -} - -static void -open_alt_failed (void *cls) -{ - struct GNUNET_GNSRECORD_Data rd; - const char *name = "dummy"; - - nsqe_alt = NULL; - rd.expiration_time = GNUNET_TIME_absolute_get ().abs_value_us; - rd.record_type = TEST_RECORD_TYPE; - rd.data_size = TEST_RECORD_DATALEN; - rd.data = GNUNET_malloc (TEST_RECORD_DATALEN); - rd.flags = 0; - memset ((char *) rd.data, 'a', TEST_RECORD_DATALEN); - - nsqe = GNUNET_NAMESTORE_records_commit (nsh, - &privkey, - name, - 1, - &rd, - &put_cont, - (void *) name); - - GNUNET_free_nz ((void *) rd.data); - -} - - -void -open_alt_cont (void *cls, - const struct - GNUNET_IDENTITY_PrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd) -{ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Got lock when I should not...\n"); - nsqe_alt = NULL; - GNUNET_SCHEDULER_cancel (endbadly_task); - endbadly_task = NULL; - GNUNET_SCHEDULER_add_now (&endbadly, NULL); -} - -void -open_cont (void *cls, - const struct - GNUNET_IDENTITY_PrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd) -{ - const char *name = "dummy"; - /* Record set does not exist */ - GNUNET_assert (NULL == rd); - nsqe = NULL; - endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, - &endbadly, NULL); - - /* This should not work */ - nsqe_alt = GNUNET_NAMESTORE_records_open (nsh_alt, - &privkey, - name, - &open_alt_failed, - NULL, - &open_alt_cont, - NULL); - -} - - -static void -open_cont_failed (void *cls) -{ - nsqe = NULL; - GNUNET_SCHEDULER_cancel (endbadly_task); - endbadly_task = NULL; - GNUNET_SCHEDULER_add_now (&endbadly, NULL); -} - - -static void -run (void *cls, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Peer *peer) -{ - const char *name = "dummy"; - privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); - GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key); - GNUNET_IDENTITY_key_get_public (&privkey, &pubkey); - - - nsh = GNUNET_NAMESTORE_connect (cfg); - GNUNET_break (NULL != nsh); - nsh_alt = GNUNET_NAMESTORE_connect (cfg); - GNUNET_break (NULL != nsh_alt); - - nsqe = GNUNET_NAMESTORE_records_open (nsh, - &privkey, - name, - &open_cont_failed, - NULL, - &open_cont, - NULL); - if (NULL == nsqe) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ ("Namestore cannot store no block\n")); - } -} - - -#include "test_common.c" - - -int -main (int argc, char *argv[]) -{ - const char *plugin_name; - char *cfg_name; - - SETUP_CFG (plugin_name, cfg_name); - res = 1; - if (0 != - GNUNET_TESTING_peer_run ("test-namestore-api", - cfg_name, - &run, - NULL)) - { - res = 1; - } - GNUNET_DISK_purge_cfg_dir (cfg_name, - "GNUNET_TEST_HOME"); - GNUNET_free (cfg_name); - return res; -} - - -/* end of test_namestore_api_store.c */ -- cgit v1.2.3