static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer) { struct CpsRunContext *crc; static struct GNUNET_HashCode zkey; datastore = GNUNET_DATASTORE_connect (cfg); start_time = GNUNET_TIME_absolute_get (); crc = GNUNET_malloc (sizeof (struct CpsRunContext)); crc->cfg = cfg; crc->phase = RP_PUT; if (NULL == GNUNET_DATASTORE_put (datastore, 0, &zkey, 4, "TEST", GNUNET_BLOCK_TYPE_TEST, 0, 0, 0, GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_SECONDS), 0, 1, GNUNET_TIME_UNIT_MINUTES, &run_tests, crc)) { FPRINTF (stderr, "%s", "Test 'put' operation failed.\n"); ok = 1; GNUNET_free (crc); } }
static void run_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct CpsRunContext *crc = cls; ok = (int) crc->phase; switch (crc->phase) { case RP_PUT: #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "PUT", crc->i); #endif GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key); GNUNET_DATASTORE_put (datastore, 0, &crc->key, get_size (crc->i), get_data (crc->i), get_type (crc->i), get_priority (crc->i), get_anonymity (crc->i), 0, get_expiration (crc->i), 1, 1, TIMEOUT, &check_success, crc); crc->i++; if (crc->i == ITERATIONS) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Sleeping to give datastore time to clean up\n"); sleep (1); crc->phase = RP_GET; crc->i--; } break; case RP_GET: #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET", crc->i); #endif GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key); GNUNET_DATASTORE_get_key (datastore, crc->offset++, &crc->key, get_type (crc->i), 1, 1, TIMEOUT, &check_value, crc); break; case RP_GET_FAIL: #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing `%s' number %u\n", "GET(f)", crc->i); #endif GNUNET_CRYPTO_hash (&crc->i, sizeof (int), &crc->key); GNUNET_DATASTORE_get_key (datastore, crc->offset++, &crc->key, get_type (crc->i), 1, 1, TIMEOUT, &check_nothing, crc); break; case RP_DONE: GNUNET_assert (0 == crc->i); #if VERBOSE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished, disconnecting\n"); #endif GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); ok = 0; } }
/** * Continuation of "GNUNET_FS_publish_ksk" that performs the actual * publishing operation (iterating over all of the keywords). * * @param cls closure of type "struct GNUNET_FS_PublishKskContext*" * @param tc unused */ static void publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_FS_PublishKskContext *pkc = cls; const char *keyword; GNUNET_HashCode key; GNUNET_HashCode query; struct GNUNET_CRYPTO_AesSessionKey skey; struct GNUNET_CRYPTO_AesInitializationVector iv; struct GNUNET_CRYPTO_RsaPrivateKey *pk; pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK; if ((pkc->i == pkc->ksk_uri->data.ksk.keywordCount) || (NULL == pkc->dsh)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "KSK PUT operation complete\n"); pkc->cont (pkc->cont_cls, pkc->ksk_uri, NULL); GNUNET_FS_publish_ksk_cancel (pkc); return; } keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under keyword `%s'\n", &keyword[1]); /* first character of keyword indicates if it is * mandatory or not -- ignore for hashing */ GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key); GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv); GNUNET_CRYPTO_aes_encrypt (&pkc->kb[1], pkc->slen + pkc->mdsize, &skey, &iv, &pkc->cpy[1]); pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&key); GNUNET_assert (NULL != pk); GNUNET_CRYPTO_rsa_key_get_public (pk, &pkc->cpy->keyspace); GNUNET_CRYPTO_hash (&pkc->cpy->keyspace, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &query); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_rsa_sign (pk, &pkc->cpy->purpose, &pkc->cpy->signature)); GNUNET_CRYPTO_rsa_key_free (pk); pkc->qre = GNUNET_DATASTORE_put (pkc->dsh, 0, &query, pkc->mdsize + sizeof (struct KBlock) + pkc->slen, pkc->cpy, GNUNET_BLOCK_TYPE_FS_KBLOCK, pkc->bo.content_priority, pkc->bo.anonymity_level, pkc->bo.replication_level, pkc->bo.expiration_time, -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT, &kb_put_cont, pkc); }
/** * Publish a UBlock. * * @param h handle to the file sharing subsystem * @param dsh datastore handle to use for storage operation * @param label identifier to use * @param ulabel update label to use, may be an empty string for none * @param ns namespace to publish in * @param meta metadata to use * @param uri URI to refer to in the UBlock * @param bo per-block options * @param options publication options * @param cont continuation * @param cont_cls closure for @a cont * @return NULL on error (@a cont will still be called) */ struct GNUNET_FS_PublishUblockContext * GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h, struct GNUNET_DATASTORE_Handle *dsh, const char *label, const char *ulabel, const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns, const struct GNUNET_CONTAINER_MetaData *meta, const struct GNUNET_FS_Uri *uri, const struct GNUNET_FS_BlockOptions *bo, enum GNUNET_FS_PublishOptions options, GNUNET_FS_UBlockContinuation cont, void *cont_cls) { struct GNUNET_FS_PublishUblockContext *uc; struct GNUNET_HashCode query; struct GNUNET_CRYPTO_SymmetricInitializationVector iv; struct GNUNET_CRYPTO_SymmetricSessionKey skey; struct GNUNET_CRYPTO_EcdsaPrivateKey *nsd; struct GNUNET_CRYPTO_EcdsaPublicKey pub; char *uris; size_t size; char *kbe; char *sptr; ssize_t mdsize; size_t slen; size_t ulen; struct UBlock *ub_plain; struct UBlock *ub_enc; /* compute ublock to publish */ if (NULL == meta) mdsize = 0; else mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); GNUNET_assert (mdsize >= 0); uris = GNUNET_FS_uri_to_string (uri); slen = strlen (uris) + 1; if (NULL == ulabel) ulen = 1; else ulen = strlen (ulabel) + 1; size = mdsize + sizeof (struct UBlock) + slen + ulen; if (size > MAX_UBLOCK_SIZE) { size = MAX_UBLOCK_SIZE; mdsize = size - sizeof (struct UBlock) - (slen + ulen); } ub_plain = GNUNET_malloc (size); kbe = (char *) &ub_plain[1]; if (NULL != ulabel) memcpy (kbe, ulabel, ulen); kbe += ulen; memcpy (kbe, uris, slen); kbe += slen; GNUNET_free (uris); sptr = kbe; if (NULL != meta) mdsize = GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, mdsize, GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); if (-1 == mdsize) { GNUNET_break (0); GNUNET_free (ub_plain); cont (cont_cls, _("Internal error.")); return NULL; } size = sizeof (struct UBlock) + slen + mdsize + ulen; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under identifier `%s'\n", label); /* get public key of the namespace */ GNUNET_CRYPTO_ecdsa_key_get_public (ns, &pub); derive_ublock_encryption_key (&skey, &iv, label, &pub); /* encrypt ublock */ ub_enc = GNUNET_malloc (size); GNUNET_CRYPTO_symmetric_encrypt (&ub_plain[1], ulen + slen + mdsize, &skey, &iv, &ub_enc[1]); GNUNET_free (ub_plain); ub_enc->purpose.size = htonl (ulen + slen + mdsize + sizeof (struct UBlock) - sizeof (struct GNUNET_CRYPTO_EcdsaSignature)); ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK); /* derive signing-key from 'label' and public key of the namespace */ nsd = GNUNET_CRYPTO_ecdsa_private_key_derive (ns, label, "fs-ublock"); GNUNET_CRYPTO_ecdsa_key_get_public (nsd, &ub_enc->verification_key); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (nsd, &ub_enc->purpose, &ub_enc->signature)); GNUNET_CRYPTO_hash (&ub_enc->verification_key, sizeof (ub_enc->verification_key), &query); GNUNET_free (nsd); uc = GNUNET_new (struct GNUNET_FS_PublishUblockContext); uc->cont = cont; uc->cont_cls = cont_cls; uc->qre = GNUNET_DATASTORE_put (dsh, 0, &query, ulen + slen + mdsize + sizeof (struct UBlock), ub_enc, GNUNET_BLOCK_TYPE_FS_UBLOCK, bo->content_priority, bo->anonymity_level, bo->replication_level, bo->expiration_time, -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT, &ublock_put_cont, uc); return uc; }
static void run_continuation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct CpsRunContext *crc = cls; size_t size; static struct GNUNET_HashCode key; static char data[65536]; int i; int k; char gstr[128]; ok = (int) crc->phase; switch (crc->phase) { case RP_PUT: memset (&key, 256 - crc->i, sizeof (struct GNUNET_HashCode)); i = crc->j; k = crc->i; /* most content is 32k */ size = 32 * 1024; if (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16) == 0) /* but some of it is less! */ size = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 32 * 1024); crc->size = size = size - (size & 7); /* always multiple of 8 */ GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &key); memset (data, i, size); if (i > 255) memset (data, i - 255, size / 2); data[0] = k; GNUNET_assert (NULL != GNUNET_DATASTORE_put (datastore, 0, &key, size, data, i + 1, GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100), i, 0, GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000))), 1, 1, TIMEOUT, &check_success, crc)); break; case RP_CUT: /* trim down below MAX_SIZE again */ GNUNET_assert (NULL != GNUNET_DATASTORE_get_for_replication (datastore, 1, 1, TIMEOUT, &delete_value, crc)); break; case RP_REPORT: printf ( #if REPORT_ID "\n" #endif "Stored %llu kB / %lluk ops / %llu ops/s\n", stored_bytes / 1024, /* used size in k */ stored_ops / 1024, /* total operations (in k) */ 1000 * stored_ops / (1 + GNUNET_TIME_absolute_get_duration (start_time).rel_value)); crc->phase = RP_PUT; crc->j = 0; GNUNET_SCHEDULER_add_continuation (&run_continuation, crc, GNUNET_SCHEDULER_REASON_PREREQ_DONE); break; case RP_DONE: GNUNET_snprintf (gstr, sizeof (gstr), "DATASTORE-%s", plugin_name); if ((crc->i == ITERATIONS) && (stored_ops > 0)) GAUGER (gstr, "PUT operation duration", GNUNET_TIME_absolute_get_duration (start_time).rel_value / stored_ops, "ms/operation"); GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); ok = 0; break; case RP_ERROR: GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); ok = 1; break; default: GNUNET_assert (0); } }
/** * Main state machine. Executes the next step of the benchmark * depending on the current state. * * @param cls the `struct CpsRunContext` */ static void run_continuation (void *cls) { struct CpsRunContext *crc = cls; size_t size; static struct GNUNET_HashCode key; static char data[65536]; char gstr[128]; ok = (int) crc->phase; switch (crc->phase) { case RP_PUT: memset (&key, 256 - crc->i, sizeof (struct GNUNET_HashCode)); /* most content is 32k */ size = 32 * 1024; if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16)) /* but some of it is less! */ size = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 32 * 1024); crc->size = size = size - (size & 7); /* always multiple of 8 */ GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &key); memset (data, (int) crc->j, size); if (crc->j > 255) memset (data, (int) (crc->j - 255), size / 2); data[0] = crc->i; GNUNET_assert (NULL != GNUNET_DATASTORE_put (datastore, 0, &key, size, data, crc->j + 1, GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100), crc->j, 0, GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000))), 1, 1, &check_success, crc)); break; case RP_CUT: /* trim down below MAX_SIZE again */ GNUNET_assert (NULL != GNUNET_DATASTORE_get_for_replication (datastore, 1, 1, &delete_value, crc)); break; case RP_REPORT: printf ( #if REPORT_ID "\n" #endif "Stored %llu kB / %lluk ops / %llu ops/s\n", stored_bytes / 1024, /* used size in k */ stored_ops / 1024, /* total operations (in k) */ 1000LL * 1000LL * stored_ops / (1 + GNUNET_TIME_absolute_get_duration (start_time).rel_value_us)); crc->phase = RP_PUT; crc->j = 0; GNUNET_SCHEDULER_add_now (&run_continuation, crc); break; case RP_PUT_QUOTA: memset (&key, 256 - crc->i, sizeof (struct GNUNET_HashCode)); /* most content is 32k */ size = 32 * 1024; if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16)) /* but some of it is less! */ size = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 32 * 1024); crc->size = size = size - (size & 7); /* always multiple of 8 */ GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &key); memset (data, (int) crc->j, size); if (crc->j > 255) memset (data, (int) (crc->j - 255), size / 2); data[0] = crc->i; GNUNET_assert (NULL != GNUNET_DATASTORE_put (datastore, 0, /* reservation ID */ &key, size, data, crc->j + 1, /* type */ GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 100), /* priority */ crc->j, /* anonymity */ 0, /* replication */ GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000))), 1, 1, &check_success, crc)); break; case RP_DONE: GNUNET_snprintf (gstr, sizeof (gstr), "DATASTORE-%s", plugin_name); if ((crc->i == ITERATIONS) && (stored_ops > 0)) { GAUGER (gstr, "PUT operation duration", GNUNET_TIME_absolute_get_duration (start_time).rel_value_us / 1000LL / stored_ops, "ms/operation"); fprintf (stdout, "\nPUT performance: %s for %llu operations\n", GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start_time), GNUNET_YES), stored_ops); fprintf (stdout, "PUT performance: %llu ms/operation\n", GNUNET_TIME_absolute_get_duration (start_time).rel_value_us / 1000LL / stored_ops); } GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); ok = 0; break; case RP_ERROR: GNUNET_DATASTORE_disconnect (datastore, GNUNET_YES); GNUNET_free (crc); ok = 1; break; default: GNUNET_assert (0); } }