[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r8894 - gnunet/src/fs
From: |
gnunet |
Subject: |
[GNUnet-SVN] r8894 - gnunet/src/fs |
Date: |
Sun, 30 Aug 2009 07:46:28 -0600 |
Author: grothoff
Date: 2009-08-30 07:46:28 -0600 (Sun, 30 Aug 2009)
New Revision: 8894
Modified:
gnunet/src/fs/fs.h
gnunet/src/fs/fs_publish.c
gnunet/src/fs/gnunet-publish.c
Log:
kblocks
Modified: gnunet/src/fs/fs.h
===================================================================
--- gnunet/src/fs/fs.h 2009-08-29 22:06:43 UTC (rev 8893)
+++ gnunet/src/fs/fs.h 2009-08-30 13:46:28 UTC (rev 8894)
@@ -445,6 +445,11 @@
int in_network_wait;
/**
+ * Options for publishing.
+ */
+ enum GNUNET_FS_PublishOptions options;
+
+ /**
* Current position in the file-tree for the
* upload.
*/
@@ -495,4 +500,33 @@
};
+/**
+ * @brief keyword block (advertising data under a keyword)
+ */
+struct GNUNET_FS_KBlock
+{
+
+ /**
+ * GNUNET_RSA_Signature using RSA-key generated from search keyword.
+ */
+ struct GNUNET_CRYPTO_RsaSignature signature;
+
+ /**
+ * What is being signed and why?
+ */
+ struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
+
+ /**
+ * Key generated (!) from the H(keyword) as the seed!
+ */
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded keyspace;
+
+ /* 0-terminated URI here */
+
+ /* variable-size Meta-Data follows here */
+
+};
+
#endif
+
+/* end of fs.h */
Modified: gnunet/src/fs/fs_publish.c
===================================================================
--- gnunet/src/fs/fs_publish.c 2009-08-29 22:06:43 UTC (rev 8893)
+++ gnunet/src/fs/fs_publish.c 2009-08-30 13:46:28 UTC (rev 8894)
@@ -26,7 +26,6 @@
* @author Christian Grothoff
*
* TODO:
- * - KBlocks
* - SBlocks
* - indexing support
* - code-sharing with unindex (can wait)
@@ -36,12 +35,15 @@
#include "platform.h"
#include "gnunet_constants.h"
+#include "gnunet_signatures.h"
#include "gnunet_util_lib.h"
#include "gnunet_fs_service.h"
#include "fs.h"
#define DEBUG_PUBLISH GNUNET_YES
+#define MAX_KBLOCK_SIZE 60000
+
/**
* Main function that performs the upload.
* @param cls "struct GNUNET_FS_PublishContext" identifies the upload
@@ -58,8 +60,7 @@
struct PutContCtx
{
/**
- * Publishing context for which the datastore
- * PUT request was executed.
+ * Current publishing context.
*/
struct GNUNET_FS_PublishContext *sc;
@@ -72,6 +73,11 @@
* Function to run next, if any (can be NULL).
*/
GNUNET_SCHEDULER_Task cont;
+
+ /**
+ * Closure for cont.
+ */
+ void *cont_cls;
};
@@ -173,56 +179,12 @@
GNUNET_SCHEDULER_NO_TASK,
GNUNET_TIME_UNIT_ZERO,
pcc->cont,
- pcc->sc);
+ pcc->cont_cls);
GNUNET_free (pcc);
}
/**
- * We need to publish a specific block. Do it. Then continue with
- * the main task.
- *
- * @param sc overall upload data
- * @param p file that the block belongs to (needed for options!)
- * @param query what the block should be indexed under
- * @param blk encoded block to publish
- * @param blk_size size of the block
- * @param blk_type type of the block
- * @param cont function to run when done
- */
-static void
-publish_block (struct GNUNET_FS_PublishContext *sc,
- struct GNUNET_FS_FileInformation *p,
- const GNUNET_HashCode *query,
- const void* blk,
- uint16_t blk_size,
- uint32_t blk_type,
- GNUNET_SCHEDULER_Task cont)
-{
- struct PutContCtx * dpc_cls;
-
- dpc_cls = GNUNET_malloc(sizeof(struct PutContCtx));
- dpc_cls->cont = cont;
- dpc_cls->sc = sc;
- dpc_cls->p = p;
- GNUNET_assert (GNUNET_NO == sc->in_network_wait);
- sc->in_network_wait = GNUNET_YES;
- GNUNET_DATASTORE_put (sc->dsh,
- sc->rid,
- query,
- blk_size,
- blk,
- blk_type,
- p->priority,
- p->anonymity,
- p->expirationTime,
- GNUNET_CONSTANTS_SERVICE_TIMEOUT,
- &ds_put_cont,
- dpc_cls);
-}
-
-
-/**
* Generate the callback that signals clients
* that a file (or directory) has been completely
* published.
@@ -247,6 +209,59 @@
/**
+ * Generate the callback that signals clients
+ * that a file (or directory) has encountered
+ * a problem during publication.
+ *
+ * @param p the upload that had trouble
+ * @param sc context of the publication
+ * @param emsg error message
+ */
+static void
+signal_publish_error (struct GNUNET_FS_FileInformation *p,
+ struct GNUNET_FS_PublishContext *sc,
+ const char *emsg)
+{
+ struct GNUNET_FS_ProgressInfo pi;
+
+ p->emsg = GNUNET_strdup (emsg);
+ pi.status = GNUNET_FS_STATUS_PUBLISH_ERROR;
+ make_publish_status (&pi, sc, p);
+ pi.value.publish.eta = GNUNET_TIME_UNIT_FOREVER_REL;
+ pi.value.publish.specifics.error.message =emsg;
+ p->client_info
+ = sc->h->upcb (sc->h->upcb_cls,
+ &pi);
+}
+
+
+/**
+ * We've finished publishing the SBlock as part of a larger upload.
+ * Check the result and complete the larger upload.
+ *
+ * @param cls the "struct GNUNET_FS_PublishContext*" of the larger upload
+ * @param uri URI of the published SBlock
+ * @param emsg NULL on success, otherwise error message
+ */
+static void
+publish_sblocks_cont (void *cls,
+ const struct GNUNET_FS_Uri *uri,
+ const char *emsg)
+{
+ struct GNUNET_FS_PublishContext *sc = cls;
+ if (NULL != emsg)
+ {
+ signal_publish_error (sc->fi,
+ sc,
+ emsg);
+ return;
+ }
+ // FIXME: release the datastore reserve here!
+ signal_publish_completion (sc->fi, sc);
+}
+
+
+/**
* We are almost done publishing the structure,
* add SBlocks (if needed).
*
@@ -255,52 +270,63 @@
static void
publish_sblock (struct GNUNET_FS_PublishContext *sc)
{
- struct GNUNET_FS_FileInformation *p;
- p = sc->fi;
-
if (NULL != sc->namespace)
GNUNET_FS_publish_sks (sc->h,
sc->namespace,
sc->nid,
sc->nuid,
- p->meta,
- p->chk_uri,
- p->expirationTime,
- p->anonymity,
- p->priority);
- // FIXME: release the datastore reserve here!
- signal_publish_completion (p, sc);
+ sc->fi->meta,
+ sc->fi->chk_uri,
+ sc->fi->expirationTime,
+ sc->fi->anonymity,
+ sc->fi->priority,
+ sc->options,
+ &publish_sblocks_cont,
+ sc);
+ else
+ publish_sblocks_cont (sc, NULL, NULL);
}
/**
- * We have uploaded a file or directory; now publish
- * the KBlocks in the global keyword space so that
- * it can be found. Then continue with the
- * main task.
+ * We've finished publishing a KBlock
+ * as part of a larger upload. Check
+ * the result and continue the larger
+ * upload.
*
- * @param sc overall upload data
- * @param p specific file or directory for which kblocks
- * should be created
+ * @param cls the "struct GNUNET_FS_PublishContext*" of the larger upload
+ * @param uri URI of the published blocks
+ * @param emsg NULL on success, otherwise error message
*/
static void
-publish_kblocks (struct GNUNET_FS_PublishContext *sc,
- struct GNUNET_FS_FileInformation *p)
+publish_kblocks_cont (void *cls,
+ const struct GNUNET_FS_Uri *uri,
+ const char *emsg)
{
- unsigned int i;
+ struct GNUNET_FS_PublishContext *sc = cls;
+ struct GNUNET_FS_FileInformation *p = sc->fi_pos;
- // FIXME: use cps here instead...
- for (i=0;i<p->keywords->data.ksk.keywordCount;i++)
- GNUNET_FS_publish_ksk (sc->h,
- p->keywords->data.ksk.keywords[i],
- p->meta,
- p->chk_uri,
- p->expirationTime,
- p->anonymity,
- p->priority);
+ if (NULL != emsg)
+ {
+ signal_publish_error (p, sc, emsg);
+ sc->upload_task
+ = GNUNET_SCHEDULER_add_delayed (sc->h->sched,
+ GNUNET_NO,
+ GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
+ GNUNET_SCHEDULER_NO_TASK,
+ GNUNET_TIME_UNIT_ZERO,
+ &do_upload,
+ sc);
+ return;
+ }
GNUNET_FS_file_information_sync (p);
if (NULL != p->dir)
signal_publish_completion (p, sc);
+ /* move on to next file */
+ if (NULL != p->next)
+ sc->fi_pos = p->next;
+ else
+ sc->fi_pos = p->dir;
sc->upload_task
= GNUNET_SCHEDULER_add_delayed (sc->h->sched,
GNUNET_NO,
@@ -435,6 +461,7 @@
struct GNUNET_FS_FileInformation *dirpos;
void *raw_data;
char *dd;
+ struct PutContCtx * dpc_cls;
// FIXME: figure out how to share this code
// with unindex!
@@ -473,7 +500,7 @@
}
}
}
- GNUNET_FS_directory_builder_add (db,
+ GNUNET_FS_directory_builder_add (db,
dirpos->chk_uri,
dirpos->meta,
raw_data);
@@ -555,18 +582,44 @@
&sk,
&iv,
enc);
- // NOTE: this call (and progress below) is all that really differs
+ // NOTE: this block below is all that really differs
// between publish/unindex! Parameterize & move this code!
// FIXME: something around here would need to change
// for indexing!
- publish_block (sc, p,
- &mychk->query,
- enc,
- pt_size,
- (p->current_depth == p->chk_tree_depth)
- ? GNUNET_DATASTORE_BLOCKTYPE_DBLOCK
- : GNUNET_DATASTORE_BLOCKTYPE_IBLOCK,
- &do_upload);
+ if (NULL == sc->dsh)
+ {
+ sc->upload_task
+ = GNUNET_SCHEDULER_add_delayed (sc->h->sched,
+ GNUNET_NO,
+ GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
+ GNUNET_SCHEDULER_NO_TASK,
+ GNUNET_TIME_UNIT_ZERO,
+ &do_upload,
+ sc);
+ }
+ else
+ {
+ GNUNET_assert (GNUNET_NO == sc->in_network_wait);
+ sc->in_network_wait = GNUNET_YES;
+ dpc_cls = GNUNET_malloc(sizeof(struct PutContCtx));
+ dpc_cls->cont = &do_upload;
+ dpc_cls->cont_cls = sc;
+ dpc_cls->p = p;
+ GNUNET_DATASTORE_put (sc->dsh,
+ sc->rid,
+ &mychk->query,
+ pt_size,
+ enc,
+ (p->current_depth == p->chk_tree_depth)
+ ? GNUNET_DATASTORE_BLOCKTYPE_DBLOCK
+ : GNUNET_DATASTORE_BLOCKTYPE_IBLOCK,
+ p->priority,
+ p->anonymity,
+ p->expirationTime,
+ GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+ &ds_put_cont,
+ dpc_cls);
+ }
if (p->current_depth == p->chk_tree_depth)
{
pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS;
@@ -629,6 +682,16 @@
publish_sblock (sc);
return;
}
+ /* find starting position */
+ while ( (p->is_directory) &&
+ (NULL != p->data.dir.entries) &&
+ (NULL == p->emsg) &&
+ (NULL == p->data.dir.entries->chk_uri) )
+ {
+ p = p->data.dir.entries;
+ sc->fi_pos = p;
+ }
+ /* abort on error */
if (NULL != p->emsg)
{
/* error with current file, abort all
@@ -653,15 +716,20 @@
}
return;
}
+ /* handle completion */
if (NULL != p->chk_uri)
{
- /* move on to next file */
- if (NULL != p->next)
- sc->fi_pos = p->next;
- else
- sc->fi_pos = p->dir;
/* upload of "p" complete, publish KBlocks! */
- publish_kblocks (sc, p);
+ GNUNET_FS_publish_ksk (sc->h,
+ p->keywords,
+ p->meta,
+ p->chk_uri,
+ p->expirationTime,
+ p->anonymity,
+ p->priority,
+ sc->options,
+ &publish_kblocks_cont,
+ sc);
return;
}
if ( (!p->is_directory) &&
@@ -725,6 +793,7 @@
* (can be NULL, must be NULL if namespace is NULL)
* @param nuid update-identifier that will be used for future updates
* (can be NULL, must be NULL if namespace or nid is NULL)
+ * @param options options for the publication
* @return context that can be used to control the publish operation
*/
struct GNUNET_FS_PublishContext *
@@ -733,16 +802,23 @@
struct GNUNET_FS_FileInformation *fi,
struct GNUNET_FS_Namespace *namespace,
const char *nid,
- const char *nuid)
+ const char *nuid,
+ enum GNUNET_FS_PublishOptions options)
{
struct GNUNET_FS_PublishContext *ret;
- struct GNUNET_FS_FileInformation *p;
struct GNUNET_DATASTORE_Handle *dsh;
- dsh = GNUNET_DATASTORE_connect (h->cfg,
- h->sched);
- if (NULL == dsh)
- return NULL;
+ if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
+ {
+ dsh = GNUNET_DATASTORE_connect (h->cfg,
+ h->sched);
+ if (NULL == dsh)
+ return NULL;
+ }
+ else
+ {
+ dsh = NULL;
+ }
ret = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext));
ret->dsh = dsh;
ret->h = h;
@@ -763,12 +839,7 @@
GNUNET_FS_file_information_inspect (ret->fi,
&fip_signal_start,
ret);
- /* find first leaf, DFS */
- p = ret->fi;
- while ( (p->is_directory) &&
- (NULL != p->data.dir.entries) )
- p = p->data.dir.entries;
- ret->fi_pos = p;
+ ret->fi_pos = ret->fi;
// FIXME: calculate space needed for "fi"
// and reserve as first task (then trigger
@@ -851,31 +922,295 @@
/**
- * Publish a KBlock on GNUnet.
+ * Context for the KSK publication.
+ */
+struct PublishKskContext
+{
+
+ /**
+ * Keywords to use.
+ */
+ struct GNUNET_FS_Uri *ksk_uri;
+
+ /**
+ * Global FS context.
+ */
+ struct GNUNET_FS_Handle *h;
+
+ /**
+ * The master block that we are sending
+ * (in plaintext), has "mdsize+slen" more
+ * bytes than the struct would suggest.
+ */
+ struct GNUNET_FS_KBlock *kb;
+
+ /**
+ * Buffer of the same size as "kb" for
+ * the encrypted version.
+ */
+ struct GNUNET_FS_KBlock *cpy;
+
+ /**
+ * Handle to the datastore, NULL if we are just
+ * simulating.
+ */
+ struct GNUNET_DATASTORE_Handle *dsh;
+
+ /**
+ * Function to call once we're done.
+ */
+ GNUNET_FS_PublishContinuation cont;
+
+ /**
+ * Closure for cont.
+ */
+ void *cont_cls;
+
+ /**
+ * When should the KBlocks expire?
+ */
+ struct GNUNET_TIME_Absolute expirationTime;
+
+ /**
+ * Size of the serialized metadata.
+ */
+ ssize_t mdsize;
+
+ /**
+ * Size of the (CHK) URI as a string.
+ */
+ size_t slen;
+
+ /**
+ * Keyword that we are currently processing.
+ */
+ unsigned int i;
+
+ /**
+ * Anonymity level for the KBlocks.
+ */
+ unsigned int anonymity;
+
+ /**
+ * Priority for the KBlocks.
+ */
+ unsigned int priority;
+};
+
+
+/**
+ * Continuation of "GNUNET_FS_publish_ksk" that performs
+ * the actual publishing operation (iterating over all
+ * of the keywords).
*
+ * @param cls closure of type "struct PublishKskContext*"
+ * @param tc unused
+ */
+static void
+publish_ksk_cont (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
+/**
+ * Function called by the datastore API with
+ * the result from the PUT request.
+ *
+ * @param cls closure of type "struct PublishKskContext*"
+ * @param success GNUNET_OK on success
+ * @param msg error message (or NULL)
+ */
+static void
+kb_put_cont (void *cls,
+ int success,
+ const char *msg)
+{
+ struct PublishKskContext *pkc = cls;
+
+ if (GNUNET_OK != success)
+ {
+ GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
+ GNUNET_free (pkc->cpy);
+ GNUNET_free (pkc->kb);
+ pkc->cont (pkc->cont_cls,
+ NULL,
+ msg);
+ GNUNET_FS_uri_destroy (pkc->ksk_uri);
+ GNUNET_free (pkc);
+ return;
+ }
+ GNUNET_SCHEDULER_add_continuation (pkc->h->sched,
+ GNUNET_NO,
+ &publish_ksk_cont,
+ pkc,
+ GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+}
+
+
+/**
+ * Continuation of "GNUNET_FS_publish_ksk" that performs
+ * the actual publishing operation (iterating over all
+ * of the keywords).
+ *
+ * @param cls closure of type "struct PublishKskContext*"
+ * @param tc unused
+ */
+static void
+publish_ksk_cont (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct 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;
+
+
+ if ( (pkc->i == pkc->ksk_uri->data.ksk.keywordCount) ||
+ (NULL == pkc->dsh) )
+ {
+ if (NULL != pkc->dsh)
+ GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
+ GNUNET_free (pkc->cpy);
+ GNUNET_free (pkc->kb);
+ pkc->cont (pkc->cont_cls,
+ pkc->ksk_uri,
+ NULL);
+ GNUNET_FS_uri_destroy (pkc->ksk_uri);
+ GNUNET_free (pkc);
+ return;
+ }
+ keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++];
+ /* 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_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);
+ GNUNET_DATASTORE_put (pkc->dsh,
+ 0,
+ &query,
+ pkc->mdsize +
+ sizeof (struct GNUNET_FS_KBlock) +
+ pkc->slen,
+ pkc->cpy,
+ GNUNET_DATASTORE_BLOCKTYPE_KBLOCK,
+ pkc->priority,
+ pkc->anonymity,
+ pkc->expirationTime,
+ GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+ &kb_put_cont,
+ pkc);
+}
+
+
+/**
+ * Publish a CHK under various keywords on GNUnet.
+ *
* @param h handle to the file sharing subsystem
- * @param keyword keyword to use
+ * @param ksk_uri keywords to use
* @param meta metadata to use
* @param uri URI to refer to in the KBlock
* @param expirationTime when the KBlock expires
* @param anonymity anonymity level for the KBlock
* @param priority priority for the KBlock
+ * @param options publication options
+ * @param cont continuation
+ * @param cont_cls closure for cont
*/
-// FIXME: cps this one
void
GNUNET_FS_publish_ksk (struct GNUNET_FS_Handle *h,
- const char *keyword,
+ struct GNUNET_FS_Uri *ksk_uri,
struct GNUNET_CONTAINER_MetaData *meta,
struct GNUNET_FS_Uri *uri,
struct GNUNET_TIME_Absolute expirationTime,
unsigned int anonymity,
- unsigned int priority)
+ unsigned int priority,
+ enum GNUNET_FS_PublishOptions options,
+ GNUNET_FS_PublishContinuation cont,
+ void *cont_cls)
{
- // FIXME!
+ struct PublishKskContext *pkc;
+ char *uris;
+ size_t size;
+ char *kbe;
+
+ pkc = GNUNET_malloc (sizeof (struct PublishKskContext));
+ pkc->h = h;
+ pkc->expirationTime = expirationTime;
+ pkc->anonymity = anonymity;
+ pkc->priority = priority;
+ pkc->cont = cont;
+ pkc->cont_cls = cont_cls;
+ if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
+ {
+ pkc->dsh = GNUNET_DATASTORE_connect (h->cfg,
+ h->sched);
+ if (pkc->dsh == NULL)
+ {
+ cont (cont_cls, NULL, _("Could not connect to datastore."));
+ GNUNET_free (pkc);
+ return;
+ }
+ }
+ pkc->mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta,
+
GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
+ GNUNET_assert (pkc->mdsize >= 0);
+ uris = GNUNET_FS_uri_to_string (uri);
+ pkc->slen = strlen (uris) + 1;
+ size = pkc->mdsize + sizeof (struct GNUNET_FS_KBlock) + pkc->slen;
+ if (size > MAX_KBLOCK_SIZE)
+ {
+ size = MAX_KBLOCK_SIZE;
+ pkc->mdsize = size - sizeof (struct GNUNET_FS_KBlock) - pkc->slen;
+ }
+ pkc->kb = GNUNET_malloc (size);
+ kbe = (char *) &pkc->kb[1];
+ memcpy (kbe, uris, pkc->slen);
+ GNUNET_free (uris);
+ pkc->mdsize = GNUNET_CONTAINER_meta_data_serialize (meta,
+ &kbe[pkc->slen],
+ pkc->mdsize,
+
GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
+ if (pkc->mdsize == -1)
+ {
+ GNUNET_break (0);
+ GNUNET_free (uris);
+ GNUNET_free (pkc->kb);
+ if (pkc->dsh != NULL)
+ GNUNET_DATASTORE_disconnect (pkc->dsh, GNUNET_NO);
+ cont (cont_cls, NULL, _("Internal error."));
+ GNUNET_free (pkc);
+ return;
+ }
+ size = sizeof (struct GNUNET_FS_KBlock) + pkc->slen + pkc->mdsize;
+
+ pkc->cpy = GNUNET_malloc (size);
+ pkc->cpy->purpose.size = htonl (sizeof (struct
GNUNET_CRYPTO_RsaSignaturePurpose) + pkc->mdsize + pkc->slen);
+ pkc->cpy->purpose.purpose = htonl(GNUNET_SIGNATURE_PURPOSE_FS_KBLOCK);
+ pkc->ksk_uri = GNUNET_FS_uri_dup (ksk_uri);
+ GNUNET_SCHEDULER_add_continuation (h->sched,
+ GNUNET_NO,
+ &publish_ksk_cont,
+ pkc,
+ GNUNET_SCHEDULER_REASON_PREREQ_DONE);
}
-
/**
* Publish an SBlock on GNUnet.
*
@@ -888,8 +1223,10 @@
* @param expirationTime when the SBlock expires
* @param anonymity anonymity level for the SBlock
* @param priority priority for the SBlock
+ * @param options publication options
+ * @param cont continuation
+ * @param cont_cls closure for cont
*/
-// FIXME: cps this one
void
GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h,
struct GNUNET_FS_Namespace *namespace,
@@ -899,9 +1236,104 @@
struct GNUNET_FS_Uri *uri,
struct GNUNET_TIME_Absolute expirationTime,
unsigned int anonymity,
- unsigned int priority)
+ unsigned int priority,
+ enum GNUNET_FS_PublishOptions options,
+ GNUNET_FS_PublishContinuation cont,
+ void *cont_cls)
{
- // FIXME
+#if 0
+ struct GNUNET_ECRS_URI *uri;
+ struct GNUNET_ClientServerConnection *sock;
+ GNUNET_DatastoreValue *value;
+ unsigned int size;
+ unsigned int mdsize;
+ struct GNUNET_RSA_PrivateKey *hk;
+ GNUNET_EC_SBlock *sb;
+ char *dstURI;
+ char *destPos;
+ GNUNET_HashCode hc; /* hash of thisId = key */
+ GNUNET_HashCode hc2; /* hash of hc = identifier */
+ int ret;
+ unsigned int nidlen;
+
+ hk = read_namespace_key (cfg, pid);
+ if (hk == NULL)
+ return NULL;
+
+ /* THEN: construct GNUNET_EC_SBlock */
+ dstURI = GNUNET_ECRS_uri_to_string (dstU);
+ mdsize = GNUNET_meta_data_get_serialized_size (md, GNUNET_SERIALIZE_PART);
+ if (nextId == NULL)
+ nextId = "";
+ nidlen = strlen (nextId) + 1;
+ size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen;
+ if (size > MAX_SBLOCK_SIZE)
+ {
+ size = MAX_SBLOCK_SIZE;
+ mdsize =
+ size - (sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen);
+ }
+ value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
+ sb = (GNUNET_EC_SBlock *) & value[1];
+ sb->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
+ destPos = (char *) &sb[1];
+ memcpy (destPos, nextId, nidlen);
+ destPos += nidlen;
+ memcpy (destPos, dstURI, strlen (dstURI) + 1);
+ destPos += strlen (dstURI) + 1;
+ mdsize = GNUNET_meta_data_serialize (ectx,
+ md,
+ destPos,
+ mdsize, GNUNET_SERIALIZE_PART);
+ if (mdsize == -1)
+ {
+ GNUNET_GE_BREAK (ectx, 0);
+ GNUNET_free (dstURI);
+ GNUNET_RSA_free_key (hk);
+ GNUNET_free (value);
+ return NULL;
+ }
+ size = sizeof (GNUNET_EC_SBlock) + mdsize + strlen (dstURI) + 1 + nidlen;
+ value->size = htonl (sizeof (GNUNET_DatastoreValue) + size);
+ value->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
+ value->priority = htonl (priority);
+ value->anonymity_level = htonl (anonymityLevel);
+ value->expiration_time = GNUNET_htonll (expiration);
+ GNUNET_hash (thisId, strlen (thisId), &hc);
+ GNUNET_hash (&hc, sizeof (GNUNET_HashCode), &hc2);
+ uri = GNUNET_malloc (sizeof (URI));
+ uri->type = sks;
+ GNUNET_RSA_get_public_key (hk, &sb->subspace);
+ GNUNET_hash (&sb->subspace,
+ sizeof (GNUNET_RSA_PublicKey), &uri->data.sks.namespace);
+ GNUNET_GE_BREAK (ectx, 0 == memcmp (&uri->data.sks.namespace,
+ pid, sizeof (GNUNET_HashCode)));
+ uri->data.sks.identifier = GNUNET_strdup (thisId);
+ GNUNET_hash_xor (&hc2, &uri->data.sks.namespace, &sb->identifier);
+ GNUNET_ECRS_encryptInPlace (&hc, &sb[1], size - sizeof (GNUNET_EC_SBlock));
+ GNUNET_GE_ASSERT (ectx,
+ GNUNET_OK == GNUNET_RSA_sign (hk,
+ size
+ -
+ sizeof
+ (GNUNET_RSA_Signature) -
+ sizeof
+ (GNUNET_RSA_PublicKey) -
+ sizeof (unsigned int),
+ &sb->identifier,
+ &sb->signature));
+ GNUNET_RSA_free_key (hk);
+ sock = GNUNET_client_connection_create (ectx, cfg);
+ ret = GNUNET_FS_insert (sock, value);
+ if (ret != GNUNET_OK)
+ {
+ GNUNET_free (uri);
+ uri = NULL;
+ }
+ GNUNET_client_connection_destroy (sock);
+ GNUNET_free (value);
+ GNUNET_free (dstURI);
+#endif
}
/* end of fs_publish.c */
Modified: gnunet/src/fs/gnunet-publish.c
===================================================================
--- gnunet/src/fs/gnunet-publish.c 2009-08-29 22:06:43 UTC (rev 8893)
+++ gnunet/src/fs/gnunet-publish.c 2009-08-30 13:46:28 UTC (rev 8894)
@@ -26,7 +26,7 @@
* @author Igor Wronsky
*
* TODO:
- * - support for some options is still missing (uri argument, simulate)
+ * - support for some options is still missing (uri argument)
* - progress callbacks not implemented (and need verbosity option)
* - clean shutdown is not implemented (stop ctx, etc.)
*/
@@ -385,7 +385,10 @@
fi,
namespace,
this_id,
- next_id);
+ next_id,
+ (do_simulate)
+ ? GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY
+ : GNUNET_FS_PUBLISH_OPTION_NONE);
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r8894 - gnunet/src/fs,
gnunet <=