/** * We obtained a result for our query to the shorten zone from * the namestore. Try to decrypt. * * @param cls the handle to our shorten operation * @param block resulting encrypted block */ static void process_pseu_block_ns (void *cls, const struct GNUNET_GNSRECORD_Block *block) { struct GetPseuAuthorityHandle *gph = cls; struct GNUNET_CRYPTO_EcdsaPublicKey pub; gph->namecache_task = NULL; if (NULL == block) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namecache did not return information for label `%s' \n", gph->current_label); process_pseu_lookup_ns (gph, 0, NULL); return; } GNUNET_CRYPTO_ecdsa_key_get_public (&gph->shorten_zone_key, &pub); if (GNUNET_OK != GNUNET_GNSRECORD_block_decrypt (block, &pub, gph->current_label, &process_pseu_lookup_ns, gph)) { GNUNET_break (0); free_get_pseu_authority_handle (gph); return; } }
static void adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) { struct GNUNET_CONTAINER_MetaData *meta; struct GNUNET_CRYPTO_EcdsaPrivateKey *ns; struct GNUNET_FS_BlockOptions bo; if (NULL != emsg) { FPRINTF (stderr, "Error publishing: %s\n", emsg); err = 1; GNUNET_FS_stop (fs); return; } ns = GNUNET_CRYPTO_ecdsa_key_create (); meta = GNUNET_CONTAINER_meta_data_create (); sks_expect_uri = GNUNET_FS_uri_dup (uri); bo.content_priority = 1; bo.anonymity_level = 1; bo.replication_level = 0; bo.expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); GNUNET_CRYPTO_ecdsa_key_get_public (ns, &nsid); GNUNET_FS_publish_sks (fs, ns, "this", "next", meta, uri, &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont, NULL); GNUNET_CONTAINER_meta_data_destroy (meta); GNUNET_free (ns); }
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_GNSRECORD_Block *block; struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; /* load privat key */ char *hostkey_file; GNUNET_asprintf(&hostkey_file, "zonefiles%s%s", DIR_SEPARATOR_STR, "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s'\n", hostkey_file); privkey = GNUNET_CRYPTO_ecdsa_key_create_from_file(hostkey_file); GNUNET_free (hostkey_file); GNUNET_assert (privkey != NULL); struct GNUNET_TIME_Absolute expire = GNUNET_TIME_absolute_get(); /* get public key */ GNUNET_CRYPTO_ecdsa_key_get_public(privkey, &pubkey); /* create record */ s_name = "DUMMY.dummy.gnunet"; s_rd = create_record (RECORDS); /* Create block */ GNUNET_assert (NULL != (block = GNUNET_GNSRECORD_block_create (privkey, expire,s_name, s_rd, RECORDS))); GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_verify (block)); GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_decrypt (block, &pubkey, s_name, &rd_decrypt_cb, s_name)); GNUNET_free (block); }
/** * Get the identifier (public key) of an ego. * * @param ego identity handle with the private key * @param pk set to ego's public key */ void GNUNET_IDENTITY_ego_get_public_key (const struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk) { GNUNET_CRYPTO_ecdsa_key_get_public (ego->pk, pk); }
/** * Calculate the DHT query for a given @a label in a given @a zone. * * @param zone private key of the zone * @param label label of the record * @param query hash to use for the query */ void GNUNET_GNSRECORD_query_from_private_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, struct GNUNET_HashCode *query) { struct GNUNET_CRYPTO_EcdsaPublicKey pub; GNUNET_CRYPTO_ecdsa_key_get_public (zone, &pub); GNUNET_GNSRECORD_query_from_public_key (&pub, label, query); }
/** * Obtain the ego representing 'anonymous' users. * * @return handle for the anonymous user, must not be freed */ const struct GNUNET_IDENTITY_Ego * GNUNET_IDENTITY_ego_get_anonymous () { static struct GNUNET_IDENTITY_Ego anon; struct GNUNET_CRYPTO_EcdsaPublicKey pub; if (NULL != anon.pk) return &anon; anon.pk = (struct GNUNET_CRYPTO_EcdsaPrivateKey *) GNUNET_CRYPTO_ecdsa_key_get_anonymous (); GNUNET_CRYPTO_ecdsa_key_get_public (anon.pk, &pub); GNUNET_CRYPTO_hash (&pub, sizeof (pub), &anon.id); return &anon; }
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer) { struct GNUNET_GNSRECORD_Data rd; char *hostkey_file; directory = NULL; GNUNET_CONFIGURATION_get_value_string(cfg, "PATHS", "GNUNET_TEST_HOME", &directory); GNUNET_DISK_directory_remove (directory); update_performed = GNUNET_NO; endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); GNUNET_asprintf (&hostkey_file, "zonefiles%s%s", DIR_SEPARATOR_STR, "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); privkey = GNUNET_CRYPTO_ecdsa_key_create_from_file (hostkey_file); GNUNET_free (hostkey_file); GNUNET_assert (privkey != NULL); GNUNET_CRYPTO_ecdsa_key_get_public (privkey, &pubkey); rd.flags = GNUNET_GNSRECORD_RF_NONE; rd.expiration_time = GNUNET_TIME_absolute_get().abs_value_us + 1000000000; rd.record_type = TEST_RECORD_TYPE; rd.data_size = TEST_RECORD_DATALEN; rd.data = GNUNET_malloc (TEST_RECORD_DATALEN); memset ((char *) rd.data, TEST_RECORD_DATA, TEST_RECORD_DATALEN); nsh = GNUNET_NAMESTORE_connect (cfg); GNUNET_break (NULL != nsh); nch = GNUNET_NAMECACHE_connect (cfg); GNUNET_break (NULL != nch); nsqe = GNUNET_NAMESTORE_records_store (nsh, privkey, name, 1, &rd, &put_cont, (void *) name); if (NULL == nsqe) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Namestore cannot store no block\n")); } GNUNET_free ((void *)rd.data); }
/** * Function to handle call request from the client * * @param cls the `struct Line` the message is about * @param msg the message from the client */ static void handle_client_call_message (void *cls, const struct ClientCallMessage *msg) { struct Line *line = cls; struct Channel *ch; struct GNUNET_MQ_Envelope *e; struct CadetPhoneRingMessage *ring; struct CadetPhoneRingInfoPS rs; line->line_port = msg->line_port; rs.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CONVERSATION_RING); rs.purpose.size = htonl (sizeof (struct CadetPhoneRingInfoPS)); rs.line_port = line->line_port; rs.target_peer = msg->target; rs.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (RING_TIMEOUT)); ch = GNUNET_new (struct Channel); ch->line = line; GNUNET_CONTAINER_DLL_insert (line->channel_head, line->channel_tail, ch); ch->status = CS_CALLER_CALLING; ch->channel = GNUNET_CADET_channel_create (cadet, ch, &msg->target, &msg->line_port, GNUNET_CADET_OPTION_RELIABLE); ch->mq = GNUNET_CADET_mq_create (ch->channel); e = GNUNET_MQ_msg (ring, GNUNET_MESSAGE_TYPE_CONVERSATION_CADET_PHONE_RING); GNUNET_CRYPTO_ecdsa_key_get_public (&msg->caller_id, &ring->caller_id); ring->expiration_time = rs.expiration_time; GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecdsa_sign (&msg->caller_id, &rs.purpose, &ring->signature)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending RING message via CADET\n"); GNUNET_MQ_send (ch->mq, e); GNUNET_SERVICE_client_continue (line->client); }
/** * If necessary, connect to the datastore and remove the KBlocks. * * @param uc context for the unindex operation. */ void GNUNET_FS_unindex_do_remove_kblocks_ (struct GNUNET_FS_UnindexContext *uc) { const char *keyword; const struct GNUNET_CRYPTO_EcdsaPrivateKey *anon; struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub; struct GNUNET_CRYPTO_EcdsaPublicKey dpub; if (NULL == uc->dsh) uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg); if (NULL == uc->dsh) { uc->state = UNINDEX_STATE_ERROR; uc->emsg = GNUNET_strdup (_("Failed to connect to `datastore' service.")); GNUNET_FS_unindex_sync_ (uc); signal_unindex_error (uc); return; } if ( (NULL == uc->ksk_uri) || (uc->ksk_offset >= uc->ksk_uri->data.ksk.keywordCount) ) { unindex_finish (uc); return; } anon = GNUNET_CRYPTO_ecdsa_key_get_anonymous (); GNUNET_CRYPTO_ecdsa_key_get_public (anon, &anon_pub); keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1]; GNUNET_CRYPTO_ecdsa_public_key_derive (&anon_pub, keyword, "fs-ublock", &dpub); GNUNET_CRYPTO_hash (&dpub, sizeof (dpub), &uc->uquery); uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh, uc->roff++, &uc->uquery, GNUNET_BLOCK_TYPE_FS_UBLOCK, 0 /* priority */, 1 /* queue size */, GNUNET_TIME_UNIT_FOREVER_REL, &process_kblock_for_unindex, uc); }
/** * Lookup in the namecache for the shorten zone the given label. * * @param gph the handle to our shorten operation * @param label the label to lookup */ static void perform_nick_lookup (struct GetPseuAuthorityHandle *gph, const char *label) { struct GNUNET_CRYPTO_EcdsaPublicKey pub; struct GNUNET_HashCode query; GNUNET_CRYPTO_ecdsa_key_get_public (&gph->shorten_zone_key, &pub); GNUNET_free_non_null (gph->current_label); gph->current_label = GNUNET_strdup (label); GNUNET_GNSRECORD_query_from_public_key (&pub, label, &query); gph->namecache_task = GNUNET_NAMECACHE_lookup_block (namecache_handle, &query, &process_pseu_block_ns, gph); }
static void put_cont (void *cls, int32_t success, const char *emsg) { const char *name = cls; struct GNUNET_HashCode derived_hash; struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; 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"); /* Create derived hash */ GNUNET_CRYPTO_ecdsa_key_get_public (privkey, &pubkey); GNUNET_GNSRECORD_query_from_public_key (&pubkey, name, &derived_hash); ncqe = GNUNET_NAMECACHE_lookup_block (nch, &derived_hash, &name_lookup_proc, (void *) name); }
/** * Start shortening algorithm, try to allocate a nice short * canonical name for @a pub in @a shorten_zone, using * @a original_label as one possible suggestion. * * @param original_label original label for the zone * @param suggested_label suggested label for the zone * @param pub public key of the zone to shorten * @param shorten_zone private key of the target zone for the new record */ void GNS_shorten_start (const char *original_label, const char *suggested_label, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, const struct GNUNET_CRYPTO_EcdsaPrivateKey *shorten_zone) { struct GetPseuAuthorityHandle *gph; struct GNUNET_CRYPTO_EcdsaPublicKey shorten_pub; if (strlen (original_label) > GNUNET_DNSPARSER_MAX_LABEL_LENGTH) { GNUNET_break (0); return; } GNUNET_CRYPTO_ecdsa_key_get_public (shorten_zone, &shorten_pub); if (0 == memcmp (&shorten_pub, pub, sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) { /* Do not shorten the shorten zone */ return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting shortening process for `%s' with old label `%s' and suggested nickname `%s'\n", GNUNET_GNSRECORD_z2s (pub), original_label, suggested_label); gph = GNUNET_new (struct GetPseuAuthorityHandle); gph->shorten_zone_key = *shorten_zone; gph->target_zone = *pub; gph->suggested_label = GNUNET_strdup (suggested_label); strcpy (gph->label, original_label); GNUNET_CONTAINER_DLL_insert (gph_head, gph_tail, gph); /* first, check if we *already* have a record for this zone */ gph->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, shorten_zone, pub, &zone_to_name_error_cb, gph, &process_zone_to_name_discover, gph); }
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TESTING_Peer *peer) { char *hostkey_file; const char * name = "dummy.dummy.gnunet"; directory = NULL; GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "PATHS", "GNUNET_TEST_HOME", &directory)); GNUNET_DISK_directory_remove (directory); endbadly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &endbadly, NULL); GNUNET_asprintf (&hostkey_file, "zonefiles%s%s", DIR_SEPARATOR_STR, "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey"); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file); privkey = GNUNET_CRYPTO_ecdsa_key_create_from_file (hostkey_file); GNUNET_free (hostkey_file); GNUNET_assert (privkey != NULL); GNUNET_CRYPTO_ecdsa_key_get_public (privkey, &pubkey); nsh = GNUNET_NAMESTORE_connect (cfg); GNUNET_break (NULL != nsh); nsqe = GNUNET_NAMESTORE_records_store (nsh, privkey, name, 0, NULL, &put_cont, (void *) name); if (NULL == nsqe) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Namestore cannot store no block\n")); } }
/** * 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; }
/** * Function called with the result from the check if the namestore * service is actually running. If it is, we start the actual * operation. * * @param cls closure with our configuration * @param result #GNUNET_YES if the namestore service is running */ static void testservice_task (void *cls, int result) { const struct GNUNET_CONFIGURATION_Handle *cfg = cls; struct GNUNET_CRYPTO_EcdsaPublicKey pub; struct GNUNET_GNSRECORD_Data rd; if (GNUNET_YES != result) { FPRINTF (stderr, _("Service `%s' is not running\n"), "namestore"); return; } if (! (add|del|list|(NULL != nickstring)|(NULL != uri)|(NULL != reverse_pkey)) ) { /* nothing more to be done */ fprintf (stderr, _("No options given\n")); GNUNET_SCHEDULER_shutdown (); return; } GNUNET_CRYPTO_ecdsa_key_get_public (&zone_pkey, &pub); ns = GNUNET_NAMESTORE_connect (cfg); if (NULL == ns) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to namestore\n")); return; } if (add) { if (NULL == name) { fprintf (stderr, _("Missing option `%s' for operation `%s'\n"), "-n", _("add")); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } if (NULL == typestring) { fprintf (stderr, _("Missing option `%s' for operation `%s'\n"), "-t", _("add")); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } type = GNUNET_GNSRECORD_typename_to_number (typestring); if (UINT32_MAX == type) { fprintf (stderr, _("Unsupported type `%s'\n"), typestring); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } if (NULL == value) { fprintf (stderr, _("Missing option `%s' for operation `%s'\n"), "-V", _("add")); ret = 1; GNUNET_SCHEDULER_shutdown (); return; } if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value (type, value, &data, &data_size)) { fprintf (stderr, _("Value `%s' invalid for record type `%s'\n"), value, typestring); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } if (NULL == expirationstring) { fprintf (stderr, _("Missing option `%s' for operation `%s'\n"), "-e", _("add")); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } if (0 == strcmp (expirationstring, "never")) { etime_abs = GNUNET_TIME_UNIT_FOREVER_ABS; etime_is_rel = GNUNET_NO; } else if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_relative (expirationstring, &etime_rel)) { etime_is_rel = GNUNET_YES; } else if (GNUNET_OK == GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, &etime_abs)) { etime_is_rel = GNUNET_NO; } else { fprintf (stderr, _("Invalid time format `%s'\n"), expirationstring); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } add_qe = GNUNET_NAMESTORE_records_lookup (ns, &zone_pkey, name, &get_existing_record, NULL ); } if (del) { if (NULL == name) { fprintf (stderr, _("Missing option `%s' for operation `%s'\n"), "-n", _("del")); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } del_qe = GNUNET_NAMESTORE_records_lookup (ns, &zone_pkey, name, &del_monitor, NULL); } if (list) { list_it = GNUNET_NAMESTORE_zone_iteration_start (ns, &zone_pkey, &display_record, NULL); } if (NULL != reverse_pkey) { struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (reverse_pkey, strlen (reverse_pkey), &pubkey)) { fprintf (stderr, _("Invalid public key for reverse lookup `%s'\n"), reverse_pkey); GNUNET_SCHEDULER_shutdown (); } reverse_qe = GNUNET_NAMESTORE_zone_to_name (ns, &zone_pkey, &pubkey, &handle_reverse_lookup, NULL); } if (NULL != uri) { char sh[105]; char sname[64]; struct GNUNET_CRYPTO_EcdsaPublicKey pkey; GNUNET_STRINGS_utf8_tolower (uri, uri); if ( (2 != (sscanf (uri, "gnunet://gns/%52s/%63s", sh, sname)) ) || (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (sh, strlen (sh), &pkey)) ) { fprintf (stderr, _("Invalid URI `%s'\n"), uri); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } memset (&rd, 0, sizeof (rd)); rd.data = &pkey; rd.data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; if (GNUNET_YES == etime_is_rel) { rd.expiration_time = etime_rel.rel_value_us; rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; } else if (GNUNET_NO == etime_is_rel) rd.expiration_time = etime_abs.abs_value_us; else rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; if (1 == is_shadow) rd.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; add_qe_uri = GNUNET_NAMESTORE_records_store (ns, &zone_pkey, sname, 1, &rd, &add_continuation, &add_qe_uri); } if (NULL != nickstring) { if (0 == strlen(nickstring)) { fprintf (stderr, _("Invalid nick `%s'\n"), nickstring); GNUNET_SCHEDULER_shutdown (); ret = 1; return; } add_qe_uri = GNUNET_NAMESTORE_set_nick(ns, &zone_pkey, nickstring, &add_continuation, &add_qe_uri); } if (monitor) { zm = GNUNET_NAMESTORE_zone_monitor_start (cfg, &zone_pkey, GNUNET_YES, &display_record, &sync_cb, NULL); } }
static int testNamespace (int i) { char *uri; struct GNUNET_FS_Uri *ret; char *emsg; struct GNUNET_CRYPTO_EcdsaPrivateKey *ph; struct GNUNET_CRYPTO_EcdsaPublicKey id; char buf[1024]; char ubuf[1024]; char *sret; if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/sks/D1KJS9H2A82Q65VKQ0ML3RFU6U1D3VUK", &emsg))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (emsg); if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/sks/XQHH4R288W26EBV369F6RCE0PJVJTX2Y74Q2FJPMPGA31HJX2JG/this", &emsg))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (emsg); if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/sks/test", &emsg))) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } GNUNET_free (emsg); ph = GNUNET_CRYPTO_ecdsa_key_create (); GNUNET_CRYPTO_ecdsa_key_get_public (ph, &id); sret = GNUNET_STRINGS_data_to_string (&id, sizeof (id), ubuf, sizeof (ubuf) - 1); GNUNET_assert (NULL != sret); sret[0] = '\0'; GNUNET_snprintf (buf, sizeof (buf), "gnunet://fs/sks/%s/test", ubuf); ret = GNUNET_FS_uri_parse (buf, &emsg); if (NULL == ret) { GNUNET_free (emsg); GNUNET_assert (0); } if (GNUNET_FS_uri_test_ksk (ret)) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } if (!GNUNET_FS_uri_test_sks (ret)) { GNUNET_FS_uri_destroy (ret); GNUNET_assert (0); } uri = GNUNET_FS_uri_to_string (ret); if (0 != strcmp (uri, buf)) { GNUNET_FS_uri_destroy (ret); GNUNET_free (uri); GNUNET_assert (0); } GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); return 0; }
/** * Function called from datastore with result from us looking for * a UBlock. There are four cases: * 1) no result, means we move on to the next keyword * 2) UID is the same as the first UID, means we move on to next keyword * 3) UBlock for a different CHK, means we keep looking for more * 4) UBlock is for our CHK, means we remove the block and then move * on to the next keyword * * @param cls the 'struct GNUNET_FS_UnindexContext *' * @param key key for the content * @param size number of bytes in data * @param data content stored * @param type type of the content * @param priority priority of the content * @param anonymity anonymity-level for the content * @param expiration expiration time for the content * @param uid unique identifier for the datum; * maybe 0 if no unique identifier is available */ static void process_kblock_for_unindex (void *cls, const struct GNUNET_HashCode *key, size_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, uint64_t uid) { struct GNUNET_FS_UnindexContext *uc = cls; const struct UBlock *ub; struct GNUNET_FS_Uri *chk_uri; struct GNUNET_HashCode query; struct GNUNET_HashCode dh; uc->dqe = NULL; if (NULL == data) { /* no result */ GNUNET_CONTAINER_multihashmap_clear (uc->seen_dh); uc->ksk_offset++; GNUNET_FS_unindex_do_remove_kblocks_ (uc); return; } GNUNET_CRYPTO_hash (data, size, &dh); if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (uc->seen_dh, &dh)) { GNUNET_CONTAINER_multihashmap_clear (uc->seen_dh); uc->ksk_offset++; GNUNET_FS_unindex_do_remove_kblocks_ (uc); return; } GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (uc->seen_dh, &dh, uc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); GNUNET_assert (GNUNET_BLOCK_TYPE_FS_UBLOCK == type); if (size < sizeof (struct UBlock)) { GNUNET_break (0); goto get_next; } ub = data; GNUNET_CRYPTO_hash (&ub->verification_key, sizeof (ub->verification_key), &query); if (0 != memcmp (&query, key, sizeof (struct GNUNET_HashCode))) { /* result does not match our keyword, skip */ goto get_next; } { char pt[size - sizeof (struct UBlock)]; struct GNUNET_CRYPTO_EcdsaPublicKey anon_pub; const char *keyword; GNUNET_CRYPTO_ecdsa_key_get_public (GNUNET_CRYPTO_ecdsa_key_get_anonymous (), &anon_pub); keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1]; GNUNET_FS_ublock_decrypt_ (&ub[1], size - sizeof (struct UBlock), &anon_pub, keyword, pt); if (NULL == memchr (&pt[1], 0, sizeof (pt) - 1)) { GNUNET_break_op (0); /* malformed UBlock */ goto get_next; } chk_uri = GNUNET_FS_uri_parse (&pt[1], NULL); if (NULL == chk_uri) { GNUNET_break_op (0); /* malformed UBlock */ goto get_next; } } if (0 != memcmp (&uc->chk, &chk_uri->data.chk.chk, sizeof (struct ContentHashKey))) { /* different CHK, ignore */ GNUNET_FS_uri_destroy (chk_uri); goto get_next; } GNUNET_FS_uri_destroy (chk_uri); /* matches! */ uc->dqe = GNUNET_DATASTORE_remove (uc->dsh, key, size, data, 0 /* priority */, 1 /* queue size */, GNUNET_TIME_UNIT_FOREVER_REL, &continue_after_remove, uc); return; get_next: uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh, uc->roff++, &uc->uquery, GNUNET_BLOCK_TYPE_FS_UBLOCK, 0 /* priority */, 1 /* queue size */, GNUNET_TIME_UNIT_FOREVER_REL, &process_kblock_for_unindex, uc); }
/** * Type of a function to call when we receive a message * from the service. * * @param cls closure * @param msg message received, NULL on timeout or fatal error */ static void message_handler (void *cls, const struct GNUNET_MessageHeader *msg) { struct GNUNET_IDENTITY_Handle *h = cls; struct GNUNET_IDENTITY_Operation *op; struct GNUNET_IDENTITY_Ego *ego; const struct GNUNET_IDENTITY_ResultCodeMessage *rcm; const struct GNUNET_IDENTITY_UpdateMessage *um; const struct GNUNET_IDENTITY_SetDefaultMessage *sdm; struct GNUNET_CRYPTO_EcdsaPublicKey pub; struct GNUNET_HashCode id; const char *str; uint16_t size; uint16_t name_len; if (NULL == msg) { reschedule_connect (h); return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %d from identity service\n", ntohs (msg->type)); size = ntohs (msg->size); switch (ntohs (msg->type)) { case GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE: if (size < sizeof (struct GNUNET_IDENTITY_ResultCodeMessage)) { GNUNET_break (0); reschedule_connect (h); return; } rcm = (const struct GNUNET_IDENTITY_ResultCodeMessage *) msg; str = (const char *) &rcm[1]; if ( (size > sizeof (struct GNUNET_IDENTITY_ResultCodeMessage)) && ('\0' != str[size - sizeof (struct GNUNET_IDENTITY_ResultCodeMessage) - 1]) ) { GNUNET_break (0); reschedule_connect (h); return; } if (size == sizeof (struct GNUNET_IDENTITY_ResultCodeMessage)) str = NULL; op = h->op_head; GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op); GNUNET_CLIENT_receive (h->client, &message_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); if (NULL != op->cont) op->cont (op->cls, str); else if (NULL != op->cb) op->cb (op->cls, NULL, NULL, NULL); GNUNET_free (op); break; case GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE: if (size < sizeof (struct GNUNET_IDENTITY_UpdateMessage)) { GNUNET_break (0); reschedule_connect (h); return; } um = (const struct GNUNET_IDENTITY_UpdateMessage *) msg; name_len = ntohs (um->name_len); str = (const char *) &um[1]; if ( (size != name_len + sizeof (struct GNUNET_IDENTITY_UpdateMessage)) || ( (0 != name_len) && ('\0' != str[name_len - 1])) ) { GNUNET_break (0); reschedule_connect (h); return; } if (GNUNET_YES == ntohs (um->end_of_list)) { /* end of initial list of data */ GNUNET_CLIENT_receive (h->client, &message_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); if (NULL != h->cb) h->cb (h->cb_cls, NULL, NULL, NULL); break; } GNUNET_CRYPTO_ecdsa_key_get_public (&um->private_key, &pub); GNUNET_CRYPTO_hash (&pub, sizeof (pub), &id); if (0 == name_len) str = NULL; else str = (const char *) &um[1]; ego = GNUNET_CONTAINER_multihashmap_get (h->egos, &id); if (NULL == ego) { /* ego was created */ if (NULL == str) { /* deletion of unknown ego? not allowed */ GNUNET_break (0); reschedule_connect (h); return; } ego = GNUNET_new (struct GNUNET_IDENTITY_Ego); ego->pk = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey); *ego->pk = um->private_key; ego->name = GNUNET_strdup (str); ego->id = id; GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_put (h->egos, &ego->id, ego, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); } if (NULL == str) { /* ego was deleted */ GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (h->egos, &ego->id, ego)); } else { /* ego changed name */ GNUNET_free (ego->name); ego->name = GNUNET_strdup (str); } GNUNET_CLIENT_receive (h->client, &message_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); /* inform application about change */ if (NULL != h->cb) h->cb (h->cb_cls, ego, &ego->ctx, str); if (NULL == str) { GNUNET_free (ego->pk); GNUNET_free (ego->name); GNUNET_free (ego); } break; case GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT: if (size < sizeof (struct GNUNET_IDENTITY_SetDefaultMessage)) { GNUNET_break (0); reschedule_connect (h); return; } sdm = (const struct GNUNET_IDENTITY_SetDefaultMessage *) msg; GNUNET_break (0 == ntohs (sdm->reserved)); name_len = ntohs (sdm->name_len); str = (const char *) &sdm[1]; if ( (size != name_len + sizeof (struct GNUNET_IDENTITY_SetDefaultMessage)) || ( (0 != name_len) && ('\0' != str[name_len - 1]) ) ) { GNUNET_break (0); reschedule_connect (h); return; } /* Note: we know which service this should be for, so we're not really using 'str' henceforth */ GNUNET_CRYPTO_ecdsa_key_get_public (&sdm->private_key, &pub); GNUNET_CRYPTO_hash (&pub, sizeof (pub), &id); ego = GNUNET_CONTAINER_multihashmap_get (h->egos, &id); if (NULL == ego) { GNUNET_break (0); reschedule_connect (h); return; } op = h->op_head; if (NULL == op) { GNUNET_break (0); reschedule_connect (h); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received SET_DEFAULT message from identity service\n"); GNUNET_CONTAINER_DLL_remove (h->op_head, h->op_tail, op); GNUNET_CLIENT_receive (h->client, &message_handler, h, GNUNET_TIME_UNIT_FOREVER_REL); if (NULL != op->cb) op->cb (op->cls, ego, &ego->ctx, ego->name); GNUNET_free (op); break; default: GNUNET_break (0); reschedule_connect (h); return; } }
/** * Sign name and records * * @param key the private key * @param expire block expiration * @param label the name for the records * @param rd record data * @param rd_count number of records * @return NULL on error (block too large) */ struct GNUNET_GNSRECORD_Block * GNUNET_GNSRECORD_block_create (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, struct GNUNET_TIME_Absolute expire, const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count) { size_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, rd); char payload[sizeof (uint32_t) + payload_len]; struct GNUNET_GNSRECORD_Block *block; struct GNUNET_CRYPTO_EcdsaPublicKey pkey; struct GNUNET_CRYPTO_EcdsaPrivateKey *dkey; struct GNUNET_CRYPTO_SymmetricInitializationVector iv; struct GNUNET_CRYPTO_SymmetricSessionKey skey; struct GNUNET_GNSRECORD_Data rdc[rd_count]; uint32_t rd_count_nbo; unsigned int i; struct GNUNET_TIME_Absolute now; if (payload_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE) return NULL; /* convert relative to absolute times */ now = GNUNET_TIME_absolute_get (); for (i=0;i<rd_count;i++) { rdc[i] = rd[i]; if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) { struct GNUNET_TIME_Relative t; /* encrypted blocks must never have relative expiration times, convert! */ rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; t.rel_value_us = rdc[i].expiration_time; rdc[i].expiration_time = GNUNET_TIME_absolute_add (now, t).abs_value_us; } } /* serialize */ rd_count_nbo = htonl (rd_count); memcpy (payload, &rd_count_nbo, sizeof (uint32_t)); GNUNET_assert (payload_len == GNUNET_GNSRECORD_records_serialize (rd_count, rdc, payload_len, &payload[sizeof (uint32_t)])); block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + sizeof (uint32_t) + payload_len); block->purpose.size = htonl (sizeof (uint32_t) + payload_len + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO)); block->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN); block->expiration_time = GNUNET_TIME_absolute_hton (expire); /* encrypt and sign */ dkey = GNUNET_CRYPTO_ecdsa_private_key_derive (key, label, "gns"); GNUNET_CRYPTO_ecdsa_key_get_public (dkey, &block->derived_key); GNUNET_CRYPTO_ecdsa_key_get_public (key, &pkey); derive_block_aes_key (&iv, &skey, label, &pkey); GNUNET_break (payload_len + sizeof (uint32_t) == GNUNET_CRYPTO_symmetric_encrypt (payload, payload_len + sizeof (uint32_t), &skey, &iv, &block[1])); if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (dkey, &block->purpose, &block->signature)) { GNUNET_break (0); GNUNET_free (dkey); GNUNET_free (block); return NULL; } GNUNET_free (dkey); return block; }
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { struct GNUNET_PSYCSTORE_PluginFunctions *db; ok = 1; db = load_plugin (cfg); if (NULL == db) { FPRINTF (stderr, "%s", "Failed to initialize PSYCstore. " "Database likely not setup, skipping test.\n"); ok = 77; return; } /* Store & test membership */ LOG (GNUNET_ERROR_TYPE_INFO, "MEMBERSHIP\n"); channel_key = GNUNET_CRYPTO_eddsa_key_create (); slave_key = GNUNET_CRYPTO_ecdsa_key_create (); GNUNET_CRYPTO_eddsa_key_get_public (channel_key, &channel_pub_key); GNUNET_CRYPTO_ecdsa_key_get_public (slave_key, &slave_pub_key); LOG (GNUNET_ERROR_TYPE_INFO, "membership_store()\n"); GNUNET_assert (GNUNET_OK == db->membership_store (db->cls, &channel_pub_key, &slave_pub_key, GNUNET_YES, 4, 2, 1)); LOG (GNUNET_ERROR_TYPE_INFO, "membership_test()\n"); GNUNET_assert (GNUNET_YES == db->membership_test (db->cls, &channel_pub_key, &slave_pub_key, 4)); GNUNET_assert (GNUNET_YES == db->membership_test (db->cls, &channel_pub_key, &slave_pub_key, 2)); GNUNET_assert (GNUNET_NO == db->membership_test (db->cls, &channel_pub_key, &slave_pub_key, 1)); /* Store & get messages */ LOG (GNUNET_ERROR_TYPE_INFO, "MESSAGES\n"); struct GNUNET_MULTICAST_MessageHeader *msg = GNUNET_malloc (sizeof (*msg) + sizeof (channel_pub_key)); GNUNET_assert (msg != NULL); msg->header.type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE); msg->header.size = htons (sizeof (*msg) + sizeof (channel_pub_key)); uint64_t fragment_id = INT64_MAX - 1; msg->fragment_id = GNUNET_htonll (fragment_id); uint64_t message_id = INT64_MAX - 10; msg->message_id = GNUNET_htonll (message_id); uint64_t group_generation = INT64_MAX - 3; msg->group_generation = GNUNET_htonll (group_generation); msg->hop_counter = htonl (9); msg->fragment_offset = GNUNET_htonll (0); msg->flags = htonl (GNUNET_MULTICAST_MESSAGE_LAST_FRAGMENT); GNUNET_memcpy (&msg[1], &channel_pub_key, sizeof (channel_pub_key)); msg->purpose.size = htonl (ntohs (msg->header.size) - sizeof (msg->header) - sizeof (msg->hop_counter) - sizeof (msg->signature)); msg->purpose.purpose = htonl (234); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (channel_key, &msg->purpose, &msg->signature)); LOG (GNUNET_ERROR_TYPE_INFO, "fragment_store()\n"); struct FragmentClosure fcls = { 0 }; fcls.n = 0; fcls.msg[0] = msg; fcls.flags[0] = GNUNET_PSYCSTORE_MESSAGE_STATE; GNUNET_assert ( GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg, fcls.flags[0])); LOG (GNUNET_ERROR_TYPE_INFO, "fragment_get(%" PRIu64 ")\n", fragment_id); uint64_t ret_frags = 0; GNUNET_assert ( GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key, fragment_id, fragment_id, &ret_frags, fragment_cb, &fcls)); GNUNET_assert (fcls.n == 1); LOG (GNUNET_ERROR_TYPE_INFO, "message_get_fragment()\n"); fcls.n = 0; GNUNET_assert ( GNUNET_OK == db->message_get_fragment (db->cls, &channel_pub_key, GNUNET_ntohll (msg->message_id), GNUNET_ntohll (msg->fragment_offset), fragment_cb, &fcls)); GNUNET_assert (fcls.n == 1); LOG (GNUNET_ERROR_TYPE_INFO, "message_add_flags()\n"); GNUNET_assert ( GNUNET_OK == db->message_add_flags (db->cls, &channel_pub_key, GNUNET_ntohll (msg->message_id), GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED)); LOG (GNUNET_ERROR_TYPE_INFO, "fragment_get(%" PRIu64 ")\n", fragment_id); fcls.n = 0; fcls.flags[0] |= GNUNET_PSYCSTORE_MESSAGE_STATE_APPLIED; GNUNET_assert ( GNUNET_OK == db->fragment_get (db->cls, &channel_pub_key, fragment_id, fragment_id, &ret_frags, fragment_cb, &fcls)); GNUNET_assert (fcls.n == 1); LOG (GNUNET_ERROR_TYPE_INFO, "fragment_store()\n"); struct GNUNET_MULTICAST_MessageHeader *msg1 = GNUNET_malloc (sizeof (*msg1) + sizeof (channel_pub_key)); GNUNET_memcpy (msg1, msg, sizeof (*msg1) + sizeof (channel_pub_key)); msg1->fragment_id = GNUNET_htonll (INT64_MAX); msg1->fragment_offset = GNUNET_htonll (32768); fcls.n = 0; fcls.msg[1] = msg1; fcls.flags[1] = GNUNET_PSYCSTORE_MESSAGE_STATE_HASH; GNUNET_assert (GNUNET_OK == db->fragment_store (db->cls, &channel_pub_key, msg1, fcls.flags[1])); LOG (GNUNET_ERROR_TYPE_INFO, "message_get()\n"); GNUNET_assert ( GNUNET_OK == db->message_get (db->cls, &channel_pub_key, message_id, message_id, 0, &ret_frags, fragment_cb, &fcls)); GNUNET_assert (fcls.n == 2 && ret_frags == 2); /* Message counters */ LOG (GNUNET_ERROR_TYPE_INFO, "counters_message_get()\n"); fragment_id = 0; message_id = 0; group_generation = 0; GNUNET_assert ( GNUNET_OK == db->counters_message_get (db->cls, &channel_pub_key, &fragment_id, &message_id, &group_generation) && fragment_id == GNUNET_ntohll (msg1->fragment_id) && message_id == GNUNET_ntohll (msg1->message_id) && group_generation == GNUNET_ntohll (msg1->group_generation)); /* Modify state */ LOG (GNUNET_ERROR_TYPE_INFO, "STATE\n"); LOG (GNUNET_ERROR_TYPE_INFO, "state_modify_*()\n"); message_id = GNUNET_ntohll (fcls.msg[0]->message_id) + 1; GNUNET_assert (GNUNET_OK == db->state_modify_begin (db->cls, &channel_pub_key, message_id, 0)); GNUNET_assert (GNUNET_OK == db->state_modify_op (db->cls, &channel_pub_key, GNUNET_PSYC_OP_ASSIGN, "_foo", C2ARG("one two three"))); GNUNET_assert (GNUNET_OK == db->state_modify_op (db->cls, &channel_pub_key, GNUNET_PSYC_OP_ASSIGN, "_foo_bar", slave_key, sizeof (*slave_key))); GNUNET_assert (GNUNET_OK == db->state_modify_end (db->cls, &channel_pub_key, message_id)); LOG (GNUNET_ERROR_TYPE_INFO, "state_get()\n"); struct StateClosure scls = { 0 }; scls.n = 0; scls.value[0] = "one two three"; scls.value_size[0] = strlen ("one two three"); GNUNET_assert (GNUNET_OK == db->state_get (db->cls, &channel_pub_key, "_foo", state_cb, &scls)); GNUNET_assert (scls.n == 1); LOG (GNUNET_ERROR_TYPE_INFO, "state_get_prefix()\n"); scls.n = 0; scls.value[1] = slave_key; scls.value_size[1] = sizeof (*slave_key); GNUNET_assert (GNUNET_OK == db->state_get_prefix (db->cls, &channel_pub_key, "_foo", state_cb, &scls)); GNUNET_assert (scls.n == 2); LOG (GNUNET_ERROR_TYPE_INFO, "state_get_signed()\n"); scls.n = 0; GNUNET_assert (GNUNET_NO == db->state_get_signed (db->cls, &channel_pub_key, state_cb, &scls)); GNUNET_assert (scls.n == 0); LOG (GNUNET_ERROR_TYPE_INFO, "state_update_signed()\n"); GNUNET_assert (GNUNET_OK == db->state_update_signed (db->cls, &channel_pub_key)); LOG (GNUNET_ERROR_TYPE_INFO, "state_get_signed()\n"); scls.n = 0; GNUNET_assert (GNUNET_YES == db->state_get_signed (db->cls, &channel_pub_key, state_cb, &scls)); GNUNET_assert (scls.n == 2); /* State counters */ LOG (GNUNET_ERROR_TYPE_INFO, "counters_state_get()\n"); uint64_t max_state_msg_id = 0; GNUNET_assert (GNUNET_OK == db->counters_state_get (db->cls, &channel_pub_key, &max_state_msg_id) && max_state_msg_id == message_id); /* State sync */ LOG (GNUNET_ERROR_TYPE_INFO, "state_sync_*()\n"); scls.n = 0; scls.value[0] = channel_key; scls.value_size[0] = sizeof (*channel_key); scls.value[1] = "three two one"; scls.value_size[1] = strlen ("three two one"); GNUNET_assert (GNUNET_OK == db->state_sync_begin (db->cls, &channel_pub_key)); GNUNET_assert (GNUNET_OK == db->state_sync_assign (db->cls, &channel_pub_key, "_sync_bar", scls.value[0], scls.value_size[0])); GNUNET_assert (GNUNET_OK == db->state_sync_assign (db->cls, &channel_pub_key, "_sync_foo", scls.value[1], scls.value_size[1])); GNUNET_assert (GNUNET_OK == db->state_sync_end (db->cls, &channel_pub_key, max_state_msg_id, INT64_MAX - 5)); GNUNET_assert (GNUNET_NO == db->state_get_prefix (db->cls, &channel_pub_key, "_foo", state_cb, &scls)); GNUNET_assert (scls.n == 0); GNUNET_assert (GNUNET_OK == db->state_get_prefix (db->cls, &channel_pub_key, "_sync", state_cb, &scls)); GNUNET_assert (scls.n == 2); scls.n = 0; GNUNET_assert (GNUNET_OK == db->state_get_signed (db->cls, &channel_pub_key, state_cb, &scls)); GNUNET_assert (scls.n == 2); /* Modify state after sync */ LOG (GNUNET_ERROR_TYPE_INFO, "state_modify_*()\n"); message_id = GNUNET_ntohll (fcls.msg[0]->message_id) + 6; GNUNET_assert (GNUNET_OK == db->state_modify_begin (db->cls, &channel_pub_key, message_id, message_id - max_state_msg_id)); GNUNET_assert (GNUNET_OK == db->state_modify_op (db->cls, &channel_pub_key, GNUNET_PSYC_OP_ASSIGN, "_sync_foo", C2ARG("five six seven"))); GNUNET_assert (GNUNET_OK == db->state_modify_end (db->cls, &channel_pub_key, message_id)); /* Reset state */ LOG (GNUNET_ERROR_TYPE_INFO, "state_reset()\n"); scls.n = 0; GNUNET_assert (GNUNET_OK == db->state_reset (db->cls, &channel_pub_key)); GNUNET_assert (scls.n == 0); ok = 0; if (NULL != channel_key) { GNUNET_free (channel_key); channel_key = NULL; } if (NULL != slave_key) { GNUNET_free (slave_key); slave_key = NULL; } unload_plugin (db); }