[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r8863 - in gnunet: . doc/man src/datacache src/datastore sr
From: |
gnunet |
Subject: |
[GNUnet-SVN] r8863 - in gnunet: . doc/man src/datacache src/datastore src/fs src/include src/testing src/transport src/upnp src/util |
Date: |
Thu, 27 Aug 2009 05:14:19 -0600 |
Author: grothoff
Date: 2009-08-27 05:14:19 -0600 (Thu, 27 Aug 2009)
New Revision: 8863
Modified:
gnunet/TODO
gnunet/doc/man/
gnunet/src/datacache/
gnunet/src/datastore/
gnunet/src/fs/
gnunet/src/fs/fs.h
gnunet/src/fs/fs_directory.c
gnunet/src/fs/fs_file_information.c
gnunet/src/fs/fs_publish.c
gnunet/src/include/gnunet_constants.h
gnunet/src/include/gnunet_container_lib.h
gnunet/src/include/gnunet_crypto_lib.h
gnunet/src/include/gnunet_datastore_service.h
gnunet/src/include/gnunet_fs_service.h
gnunet/src/testing/
gnunet/src/transport/
gnunet/src/upnp/
gnunet/src/util/container_meta_data.c
gnunet/src/util/crypto_hash.c
Log:
syn
Modified: gnunet/TODO
===================================================================
--- gnunet/TODO 2009-08-26 20:47:59 UTC (rev 8862)
+++ gnunet/TODO 2009-08-27 11:14:19 UTC (rev 8863)
@@ -43,14 +43,14 @@
+ getopt API -- DONE (but do more testing)
+ persistence mechanism (design done)
+ sharing API
- ~ file-information (almost done, needs testing)
- ~ insert
+ ~ file-information (needs testing)
+ ~ directory: implement new directory builder!
+ ~ insert: close, need directory builder first!
+ ~ unindex & list indexed!!!
~ search
~ download
- ~ unindex & list indexed!!!
~ namespaces
~ collection
- + directory API (builder API unclear)
- design network structs (P2P)
- datastore request queueing mechanism
- implement FS service (needs DHT)
Property changes on: gnunet/doc/man
___________________________________________________________________
Added: svn:ignore
+ Makefile.in
Property changes on: gnunet/src/datacache
___________________________________________________________________
Modified: svn:ignore
- Makefile.in
Makefile
.deps
+ test_datacache_quota
test_datacache_api_quota.gcno
test_datacache_api_quota.gcda
test_datacache_api_quota
test_datacache_api.gcno
test_datacache_api.gcda
test_datacache_api
test_datacache
perf_datacache_api.gcno
perf_datacache_api.gcda
perf_datacache_api
perf_datacache
Makefile.in
Makefile
.deps
Property changes on: gnunet/src/datastore
___________________________________________________________________
Modified: svn:ignore
- gnunet-service-datastore.gcno
perf_plugin_datastore
test_datastore_api
perf_datastore_api_iterators
perf_datastore_api
Makefile.in
Makefile
gnunet-service-datastore
.deps
+ test_datastore_api_management.gcno
test_datastore_api_management.gcda
test_datastore_api_management
test_datastore_api.gcno
test_datastore_api.gcda
plugin_datastore_template.gcno
plugin_datastore_sqlite.gcno
perf_plugin_datastore.gcno
perf_plugin_datastore.gcda
perf_datastore_api.gcno
perf_datastore_api.gcda
gnunet-service-datastore.gcda
datastore_api.gcno
gnunet-service-datastore.gcno
perf_plugin_datastore
test_datastore_api
perf_datastore_api_iterators
perf_datastore_api
Makefile.in
Makefile
gnunet-service-datastore
.deps
Property changes on: gnunet/src/fs
___________________________________________________________________
Added: svn:ignore
+ Makefile.in
Makefile
.deps
Modified: gnunet/src/fs/fs.h
===================================================================
--- gnunet/src/fs/fs.h 2009-08-26 20:47:59 UTC (rev 8862)
+++ gnunet/src/fs/fs.h 2009-08-27 11:14:19 UTC (rev 8863)
@@ -26,12 +26,34 @@
#ifndef FS_H
#define FS_H
+#include "gnunet_datastore_service.h"
+#include "gnunet_fs_service.h"
+
/**
* Size of the individual blocks used for file-sharing.
*/
#define GNUNET_FS_DBLOCK_SIZE (32*1024)
+
/**
+ * Pick a multiple of 2 here to achive 8-byte alignment!
+ * We also probably want DBlocks to have (roughly) the
+ * same size as IBlocks. With SHA-512, the optimal
+ * value is 32768 byte / 128 byte = 256
+ * (128 byte = 2 * 512 bits). DO NOT CHANGE!
+ */
+#define GNUNET_FS_CHK_PER_INODE 256
+
+
+/**
+ * Maximum size for a file to be considered for
+ * inlining in a directory.
+ */
+#define GNUNET_FS_MAX_INLINE_SIZE 65536
+
+
+
+/**
* @brief content hash key
*/
struct ContentHashKey
@@ -51,7 +73,7 @@
/**
* Total size of the file in bytes. (network byte order (!))
*/
- unsigned long long file_length;
+ uint64_t file_length;
/**
* Query and key of the top GNUNET_EC_IBlock.
@@ -187,6 +209,12 @@
struct GNUNET_FS_Uri *keywords;
/**
+ * CHK for this file or directory. NULL if
+ * we have not yet computed it.
+ */
+ struct GNUNET_FS_Uri *chk_uri;
+
+ /**
* At what time should the content expire?
*/
struct GNUNET_TIME_Absolute expirationTime;
@@ -198,6 +226,31 @@
char *serialization;
/**
+ * In-memory cache of the current CHK tree.
+ * This struct will contain the CHK values
+ * from the root to the currently processed
+ * node in the tree as identified by
+ * "current_depth" and "publish_offset".
+ * The "chktree" will be initially NULL,
+ * then allocated to a sufficient number of
+ * entries for the size of the file and
+ * finally freed once the upload is complete.
+ */
+ struct ContentHashKey *chk_tree;
+
+ /**
+ * Number of entries in "chk_tree".
+ */
+ unsigned int chk_tree_depth;
+
+ /**
+ * Depth in the CHK-tree at which we are
+ * currently publishing. 0 is the root
+ * of the tree.
+ */
+ unsigned int current_depth;
+
+ /**
* How many bytes of this file or directory have been
* published so far?
*/
@@ -257,6 +310,12 @@
*/
uint64_t dir_size;
+ /**
+ * Pointer to the data for the directory (or NULL if not
+ * available).
+ */
+ char *dir_data;
+
} dir;
} data;
@@ -358,6 +417,23 @@
* if the upload has completed.
*/
GNUNET_SCHEDULER_TaskIdentifier upload_task;
+
+ /**
+ * Current position in the file-tree for the
+ * upload.
+ */
+ struct GNUNET_FS_FileInformation *fi_pos;
+
+ /**
+ * Connection to the datastore service.
+ */
+ struct GNUNET_DATASTORE_Handle *dsh;
+
+ /**
+ * Space reservation ID with datastore service
+ * for this upload.
+ */
+ int rid;
};
Modified: gnunet/src/fs/fs_directory.c
===================================================================
--- gnunet/src/fs/fs_directory.c 2009-08-26 20:47:59 UTC (rev 8862)
+++ gnunet/src/fs/fs_directory.c 2009-08-27 11:14:19 UTC (rev 8863)
@@ -25,7 +25,6 @@
*
* TODO:
* - add support for embedded file data (use padding room!)
- * - add directory builder API to gnunet_fs_service
* - modify directory builder API to support incremental
* generation of directories (to allow directories that
* would not fit into memory to be created)
@@ -38,6 +37,9 @@
#include "gnunet_fs_service.h"
#include "fs.h"
+#ifndef EXTRACTOR_GNUNET_FULL_DATA
+#define EXTRACTOR_GNUNET_FULL_DATA 137
+#endif
/**
* Does the meta-data claim that this is a directory?
@@ -215,6 +217,7 @@
return; /* malformed ! */
}
pos += mdSize;
+ // EXTRACTOR_GNUNET_FULL_DATA
/* FIXME: add support for embedded data */
filename = GNUNET_CONTAINER_meta_data_get_by_type (md,
EXTRACTOR_FILENAME);
@@ -231,26 +234,162 @@
}
}
+/**
+ * Entries in the directory (builder).
+ */
+struct BuilderEntry
+{
+ /**
+ * This is a linked list.
+ */
+ struct BuilderEntry *next;
+
+ /**
+ * Length of this entry.
+ */
+ size_t len;
+};
-void
-GNUNET_FS_directory_create ()
+/**
+ * Internal state of a directory builder.
+ */
+struct GNUNET_FS_DirectoryBuilder
{
+ /**
+ * Meta-data for the directory itself.
+ */
+ struct GNUNET_CONTAINER_MetaData *meta;
+
+ /**
+ * Head of linked list of entries.
+ */
+ struct BuilderEntry *head;
+
+ /**
+ * Number of entires in the directory.
+ */
+ unsigned int count;
+};
+
+
+/**
+ * Create a directory builder.
+ *
+ * @param mdir metadata for the directory
+ */
+struct GNUNET_FS_DirectoryBuilder *
+GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData
*mdir)
+{
+ struct GNUNET_FS_DirectoryBuilder *ret;
+
+ ret = GNUNET_malloc(sizeof(struct GNUNET_FS_DirectoryBuilder));
+ ret->meta = GNUNET_CONTAINER_meta_data_duplicate (mdir);
+ GNUNET_FS_meta_data_make_directory (ret->meta);
+ return ret;
}
-#if 0
+/**
+ * Add an entry to a directory.
+ *
+ * @param bld directory to extend
+ * @param uri uri of the entry (must not be a KSK)
+ * @param md metadata of the entry
+ * @param data raw data of the entry, can be NULL, otherwise
+ * data must point to exactly the number of bytes specified
+ * by the uri which must be of type LOC or CHK
+ */
+void
+GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld,
+ const struct GNUNET_FS_Uri *uri,
+ const struct GNUNET_CONTAINER_MetaData *md,
+ const void *data)
+{
+ struct BuilderEntry *e;
+ uint64_t fsize;
+ uint32_t big;
+ size_t mds;
+ size_t mdxs;
+ char *uris;
+ char *ser;
+ size_t slen;
+ struct GNUNET_CONTAINER_MetaData *meta;
+ const struct GNUNET_CONTAINER_MetaData *meta_use;
+ GNUNET_assert (! GNUNET_FS_uri_ksk_test (uri));
+ if (NULL != data)
+ if (GNUNET_FS_uri_chk_test (uri))
+ fsize = GNUNET_FS_uri_chk_get_size (uri);
+ else
+ fsize = GNUNET_FS_uri_chk_get_size (GNUNET_FS_uri_loc_get_uri (uri));
+ else
+ fsize = 0; /* not given */
+ if (fsize > GNUNET_FS_MAX_INLINE_SIZE)
+ fsize = 0; /* too large */
+ if (memchr (data, fsize, '\0')) // FIXME: check memchr args!
+ fsize = 0; /* must not have 0's in data! */
+ uris = GNUNET_FS_uri_to_string (uri);
+ slen = strlen (uris) + 1;
+ mds =
+ GNUNET_CONTAINER_meta_data_get_serialized_size (md,
+
GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
+ meta_use = md;
+ meta = NULL;
+ if (fsize > 0)
+ {
+ meta = GNUNET_CONTAINER_meta_data_duplicate (md);
+ GNUNET_CONTAINER_meta_data_insert (meta,
+ EXTRACTOR_GNUNET_FULL_DATA,
+ data);
+ mdxs =
+ GNUNET_CONTAINER_meta_data_get_serialized_size (meta,
+
GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL);
+ if ( (slen + sizeof (uint32_t) + mdxs - 1) / GNUNET_FS_DBLOCK_SIZE ==
+ (slen + sizeof (uint32_t) + mds - 1) / GNUNET_FS_DBLOCK_SIZE)
+ {
+ /* adding full data would not cause us to cross
+ additional blocks, so add it! */
+ meta_use = meta;
+ mds = mdxs;
+ }
+ }
+ if (mds > GNUNET_MAX_MALLOC_CHECKED / 2)
+ mds = GNUNET_MAX_MALLOC_CHECKED / 2;
+ e = GNUNET_malloc (sizeof(struct BuilderEntry) +
+ slen + mds + sizeof (uint32_t));
+ ser = (char*) &e[1];
+ memcpy (ser, uris, slen);
+ GNUNET_free (uris);
+ ret = GNUNET_CONTAINER_meta_data_serialize (meta_use,
+ &ser[slen + sizeof(uint32_t)],
+ mds,
+
GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
+ if (NULL != meta)
+ GNUNET_CONTAINER_meta_data_destroy (meta);
+ if (ret == -1)
+ mds = 0;
+ else
+ mds = ret;
+ big = htonl (mds);
+ memcpy (&ser[slen], &big, sizeof (uint32_t));
+ e->len = slen + sizeof (uint32_t) + mds;
+ e->next = bld->head;
+ bld->head = e;
+ bld->count++;
+}
+
+
/**
* Given the start and end position of a block of
* data, return the end position of that data
* after alignment to the GNUNET_FS_DBLOCK_SIZE.
*/
-static uint64_t
-do_align (uint64_t start_position,
- uint64_t end_position)
+static size_t
+do_align (size_t start_position,
+ size_t end_position)
{
- uint64_t align;
+ size_t align;
align = (end_position / GNUNET_FS_DBLOCK_SIZE) * GNUNET_FS_DBLOCK_SIZE;
if ((start_position < align) && (end_position > align))
@@ -269,19 +408,19 @@
* @param perm the permutation of the blocks (updated)
*/
static void
-block_align (uint64_t start,
+block_align (size_t start,
unsigned int count,
- const uint64_t *sizes,
+ const size_t *sizes,
unsigned int *perm)
{
unsigned int i;
unsigned int j;
unsigned int tmp;
unsigned int best;
- int64_t badness;
- uint64_t cpos;
- uint64_t cend;
- int64_t cbad;
+ ssize_t badness;
+ size_t cpos;
+ size_t cend;
+ ssize_t cbad;
unsigned int cval;
cpos = start;
@@ -334,135 +473,94 @@
/**
- * Create a directory. We allow packing more than one variable
- * size entry into one block (and an entry could also span more
- * than one block), but an entry that is smaller than a single
- * block will never cross the block boundary. This is done to
- * allow processing entries of a directory already even if the
- * download is still partial.<p>
+ * Finish building the directory. Frees the
+ * builder context and returns the directory
+ * in-memory.
*
- * The first block begins with the directories MAGIC signature,
- * followed by the meta-data about the directory itself.<p>
- *
- * After that, the directory consists of block-aligned pairs
- * of URIs (0-terminated strings) and serialized meta-data.
- *
- * @param data pointer set to the beginning of the directory
- * @param len set to number of bytes in data
- * @param count number of entries in uris and mds
- * @param uris URIs of the files in the directory
- * @param mds meta-data for the files (must match
- * respective values at same offset in in uris)
- * @param mdir meta-data for the directory
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ * @param bld directory to finish
+ * @param rsize set to the number of bytes needed
+ * @param rdata set to the encoded directory
*/
-int
-GNUNET_FS_directory_create (char **data,
- size_t *len,
- unsigned int count,
- const struct GNUNET_FS_Uri **uris,
- const struct GNUNET_CONTAINER_MetaData **mds,
- const struct GNUNET_CONTAINER_MetaData *mdir)
+void
+GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld,
+ size_t *rsize,
+ void **rdata)
{
+ char *data;
+ size_t *sizes;
+ unsigned int *perm;
unsigned int i;
unsigned int j;
- uint64_t psize;
- uint64_t size;
- uint64_t pos;
- char **ucs;
- int ret;
- uint64_t *sizes;
- unsigned int *perm;
+ struct BuilderEntry *pos;
+ struct BuilderEntry **bes;
+ size_t size;
+ size_t psize;
+ size_t off;
+ ssize_t ret;
+ uint32_t big;
- for (i = 0; i < count; i++)
+ size = 8 + sizeof (uint32_t);
+ size += GNUNET_meta_data_get_serialized_size (bld->meta,
+ GNUNET_SERIALIZE_FULL);
+ if (bld->count > 0)
{
- if (GNUNET_FS_uri_test_ksk (fis[i].uri))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR; /* illegal in directory! */
- }
- }
- ucs = GNUNET_malloc (sizeof (char *) * count);
- size = 8 + sizeof (unsigned int);
- size += GNUNET_meta_data_get_serialized_size (meta, GNUNET_SERIALIZE_FULL);
- sizes = GNUNET_malloc (count * sizeof (unsigned long long));
- perm = GNUNET_malloc (count * sizeof (int));
- for (i = 0; i < count; i++)
- {
- perm[i] = i;
- ucs[i] = GNUNET_FS_uri_to_string (fis[i].uri);
- GNUNET_assert (ucs[i] != NULL);
- psize =
- GNUNET_meta_data_get_serialized_size (fis[i].meta,
- GNUNET_SERIALIZE_FULL);
- if (psize == -1)
- {
- GNUNET_break (0);
- GNUNET_free (sizes);
- GNUNET_free (perm);
- while (i >= 0)
- GNUNET_free (ucs[i--]);
- GNUNET_free (ucs);
- return GNUNET_SYSERR;
- }
- sizes[i] = psize + sizeof (unsigned int) + strlen (ucs[i]) + 1;
- }
- /* permutate entries to minimize alignment cost */
- block_align (size, count, sizes, perm);
+ sizes = GNUNET_malloc (bld->count * sizeof (size_t));
+ perm = GNUNET_malloc (bld->count * sizeof (unsigned int));
+ bes = GNUNET_malloc (bld->count * sizeof (struct BuilderEntry *));
+ pos = bld->head;
+ for (i = 0; i < bld->count; i++)
+ {
+ perm[i] = i;
+ bes[i] = pos;
+ sizes[i] = pos->size;
+ pos = pos->next;
+ }
+ }
+ block_align (size,
+ bld->count,
+ sizes,
+ perm);
/* compute final size with alignment */
- for (i = 0; i < count; i++)
+ for (i = 0; i < bld->count; i++)
{
psize = size;
size += sizes[perm[i]];
size = do_align (psize, size);
}
- *len = size;
- *data = GNUNET_malloc (size);
- memset (*data, 0, size);
+ *rsize = size;
+ data = GNUNET_malloc (size);
+ *rdata = data;
+ memcpy (data, GNUNET_DIRECTORY_MAGIC, 8);
+ off = 8;
- pos = 8;
- memcpy (*data, GNUNET_DIRECTORY_MAGIC, 8);
-
ret = GNUNET_CONTAINER_meta_data_serialize (meta,
- &(*data)[pos +
- sizeof (unsigned int)],
- size - pos - sizeof (unsigned
int),
+ &(*data)[off +
+ sizeof (uint32_t)],
+ size - pos - sizeof (uint32_t),
GNUNET_SERIALIZE_FULL);
- GNUNET_assert (ret != GNUNET_SYSERR);
- ret = htonl (ret);
- memcpy (&(*data)[pos], &ret, sizeof (unsigned int));
- pos += ntohl (ret) + sizeof (unsigned int);
-
+ GNUNET_assert (ret != -1);
+ big = htonl (ret);
+ memcpy (&(*data)[8], &big, sizeof (uint32_t));
+ pos += sizeof (uint32_t) + ret;
for (j = 0; j < count; j++)
{
i = perm[j];
psize = pos;
pos += sizes[i];
pos = do_align (psize, pos);
- pos -= sizes[i]; /* go back to beginning */
- memcpy (&(*data)[pos], ucs[i], strlen (ucs[i]) + 1);
- pos += strlen (ucs[i]) + 1;
- GNUNET_free (ucs[i]);
- ret = GNUNET_CONTAINER_meta_data_serialize (mds[i],
- &(*data)[pos +
- sizeof (unsigned
int)],
- size - pos -
- sizeof (unsigned int),
- GNUNET_SERIALIZE_FULL);
- GNUNET_assert (ret != GNUNET_SYSERR);
- ret = htonl (ret);
- memcpy (&(*data)[pos], &ret, sizeof (unsigned int));
- pos += ntohl (ret) + sizeof (unsigned int);
+ memcpy (&data[pos - sizes[i]],
+ &(bes[i])[1],
+ sizes[i]);
+ GNUNET_free (bes[i]);
}
GNUNET_free (sizes);
GNUNET_free (perm);
- GNUNET_free (ucs);
- GNUNET_assert (pos == size);
- return GNUNET_OK;
+ GNUNET_free (bes);
+ GNUNET_assert (pos == size);
+ GNUNET_CONTAINER_meta_data_destroy (bld->meta);
+ GNUNET_free (bld);
}
-#endif
-
/* end of fs_directory.c */
Modified: gnunet/src/fs/fs_file_information.c
===================================================================
--- gnunet/src/fs/fs_file_information.c 2009-08-26 20:47:59 UTC (rev 8862)
+++ gnunet/src/fs/fs_file_information.c 2009-08-27 11:14:19 UTC (rev 8863)
@@ -804,6 +804,7 @@
&fi->priority,
&fi->expirationTime,
&fi->client_info);
+ GNUNET_free_non_null (fi->data.dir.dir_data);
GNUNET_free (fi->data.dir.dirname);
}
else
@@ -821,7 +822,7 @@
&fi->expirationTime,
&fi->client_info);
}
-
+ GNUNET_free_non_null (fi->chk_tree);
/* clean up serialization */
if (0 != UNLINK (fi->serialization))
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
Modified: gnunet/src/fs/fs_publish.c
===================================================================
--- gnunet/src/fs/fs_publish.c 2009-08-26 20:47:59 UTC (rev 8862)
+++ gnunet/src/fs/fs_publish.c 2009-08-27 11:14:19 UTC (rev 8863)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 Christian Grothoff (and
other contributing authors)
+ (C) 2009 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -24,17 +24,396 @@
* @see http://gnunet.org/encoding.php3
* @author Krista Bennett
* @author Christian Grothoff
+ *
+ * TODO:
+ * - directory creation
+ * - KBlocks
+ * - SBlocks
+ * - indexing support
+ * - calling of progress function
+ * - handling of IO errors (emsg)
+ * - code-sharing with unindex
+ * - datastore reservation support
+ * - persistence support
*/
#include "platform.h"
+#include "gnunet_constants.h"
#include "gnunet_util_lib.h"
#include "gnunet_fs_service.h"
#include "fs.h"
#define DEBUG_PUBLISH GNUNET_YES
+/**
+ * Main function that performs the upload.
+ * @param cls "struct GNUNET_FS_PublishContext" identifies the upload
+ * @param tc task context
+ */
+static void
+do_upload (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc);
+
/**
+ * Context for "ds_put_cont".
+ */
+struct PutContCtx
+{
+ /**
+ * Publishing context for which the datastore
+ * PUT request was executed.
+ */
+ struct GNUNET_FS_PublishContext *sc;
+
+ /**
+ * Specific file with the block.
+ */
+ struct GNUNET_FS_FileInformation *p;
+
+ /**
+ * Function to run next, if any (can be NULL).
+ */
+ GNUNET_SCHEDULER_Task cont;
+};
+
+/**
+ * Function called by the datastore API with
+ * the result from the PUT request.
+ *
+ * @param cls our closure
+ * @param success GNUNET_OK on success
+ * @param msg error message (or NULL)
+ */
+static void
+ds_put_cont (void *cls,
+ int success,
+ const char *msg)
+{
+ struct PutContCtx *pcc = cls;
+
+ if (GNUNET_OK != success)
+ {
+ // FIXME: call progress CB with error
+ // FIXME: update pcc->p to indicate abort
+ GNUNET_FS_file_information_sync (pcc->p);
+ return;
+ }
+ GNUNET_FS_file_information_sync (pcc->p);
+ if (NULL != pcc->cont)
+ pcc->sc->upload_task
+ = GNUNET_SCHEDULER_add_delayed (pcc->sc->h->sched,
+ GNUNET_NO,
+ GNUNET_SCHEDULER_PRIORITY_BACKGROUND,
+ GNUNET_SCHEDULER_NO_TASK,
+ GNUNET_TIME_UNIT_ZERO,
+ pcc->cont,
+ pcc->sc);
+ 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 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 void* blk,
+ uint16_t blk_size,
+ uint32_t blk_type,
+ GNUNET_SCHEDULER_Task cont)
+{
+ struct GNUNET_HashCode key;
+
+ // FIXME: GNUNET_FS_get_key (blk_type, blk, blk_size, &key);
+ // (or add "key" as argument to reduce hashing?)
+ dpc_cls = GNUNET_malloc(sizeof(struct PutContCtx));
+ dpc_cls->cont = cont;
+ dpc_cls->sc = sc;
+ dpc_cls->p = p;
+ // FIXME: need to do something to "sc" to mark
+ // that "sc" can not be freed right now due to this
+ // pending, scheduled operation for which we don't have
+ // a task ID!
+ GNUNET_DATASTORE_put (sc->dsh,
+ sc->rid,
+ &key,
+ blk_size,
+ blk_type,
+ p->priority,
+ p->anonymity,
+ p->expirationTime,
+ GNUNET_CONSTANTS_SERVICE_TIMEOUT,
+ &ds_put_cont,
+ dpc_cls);
+}
+
+
+/**
+ * We are almost done publishing the structure,
+ * add SBlocks (if needed).
+ *
+ * @param sc overall upload data
+ */
+static void
+publish_sblock (struct GNUNET_FS_PublishContext *sc)
+{
+ struct GNUNET_FS_FileInformation *p;
+ p = sc->fi;
+
+ // FIXME: build sblock & call publish_block!
+
+ // FIXME: continuation should
+ // be releasing the datastore reserve
+ // (once implemented)
+}
+
+
+/**
+ * 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.
+ *
+ * @param sc overall upload data
+ * @param p specific file or directory for which kblocks
+ * should be created
+ */
+static void
+publish_kblocks (struct GNUNET_FS_PublishContext *sc,
+ struct GNUNET_FS_FileInformation *p)
+{
+ // FIXME: build all kblocks
+ // call publish_kblock on each
+ // last continuation should then call the main continuation again
+}
+
+
+/**
+ * Compute the depth of the CHK tree.
+ *
+ * @param flen file length for which to compute the depth
+ * @return depth of the tree
+ */
+static unsigned int
+compute_depth (uint64_t flen)
+{
+ unsigned int treeDepth;
+ uint64_t fl;
+
+ treeDepth = 1;
+ fl = GNUNET_FS_DBLOCK_SIZE;
+ while (fl < flen)
+ {
+ treeDepth++;
+ if (fl * GNUNET_FS_CHK_PER_INODE < fl)
+ {
+ /* integer overflow, this is a HUGE file... */
+ return treeDepth;
+ }
+ fl = fl * GNUNET_FS_CHK_PER_INODE;
+ }
+ return treeDepth;
+}
+
+
+/**
+ * Compute the size of the current IBlock.
+ *
+ * @param height height of the IBlock in the tree (aka overall
+ * number of tree levels minus depth); 0 == DBlock
+ * @param offset current offset in the overall file
+ * @return size of the corresponding IBlock
+ */
+static uint16_t
+compute_iblock_size (unsigned int height,
+ uint64_t offset)
+{
+ unsigned int ret;
+ unsigned int i;
+ uint64_t mod;
+ uint64_t bds;
+
+ GNUNET_assert (height > 0);
+ bds = GNUNET_FS_DBLOCK_SIZE; /* number of bytes each CHK at level "i"
+ corresponds to */
+ for (i=0;i<height;i++)
+ bds *= GNUNET_FS_CHK_PER_INODE;
+ mod = offset % bds;
+ if (0 == mod)
+ {
+ /* we were triggered at the end of a full block */
+ ret = GNUNET_FS_CHK_PER_INODE;
+ }
+ else
+ {
+ /* we were triggered at the end of the file */
+ bds /= GNUNET_FS_CHK_PER_INODE;
+ ret = mod / bds;
+ if (0 != mod % bds)
+ ret++;
+ }
+ return (uint16_t) (ret * sizeof(struct ContentHashKey));
+}
+
+
+/**
+ * Compute the offset of the CHK for the
+ * current block in the IBlock above.
+ *
+ * @param height height of the IBlock in the tree (aka overall
+ * number of tree levels minus depth); 0 == DBlock
+ * @param offset current offset in the overall file
+ * @return (array of CHKs') offset in the above IBlock
+ */
+static unsigned int
+compute_chk_offset (unsigned int height,
+ uint64_t offset)
+{
+ uint64_t bds;
+ unsigned int ret;
+
+ bds = GNUNET_FS_DBLOCK_SIZE; /* number of bytes each CHK at level "i"
+ corresponds to */
+ for (i=0;i<height;i++)
+ bds *= GNUNET_FS_CHK_PER_INODE;
+ GNUNET_assert (0 == (offset % bds));
+ ret = offset / bds;
+ return ret % GNUNET_FS_CHK_PER_INODE;
+}
+
+
+/**
+ * We are uploading a file or directory; load (if necessary) the next
+ * block into memory, encrypt it and send it to the FS service. Then
+ * continue with the main task.
+ *
+ * @param sc overall upload data
+ * @param p specific file or directory for which kblocks
+ * should be created
+ */
+static void
+publish_content (struct GNUNET_FS_PublishContext *sc,
+ struct GNUNET_FS_FileInformation *p)
+{
+ struct ContentHashKey *chk;
+ const void *pt_block;
+ uint16_t pt_size;
+ char *emsg;
+ char iob[GNUNET_FS_DBLOCK_SIZE];
+ char enc[GNUNET_FS_DBLOCK_SIZE];
+ struct GNUNET_CRYPTO_AesSessionKey sk;
+ struct GNUNET_CRYPTO_AesInitializationVector iv;
+ uint64_t size;
+ unsigned int off;
+
+ // FIXME: figure out how to share this code
+ // with unindex!
+ size = (p->is_directory) ? p->data.dir.dir_size : p->data.file.file_size;
+ if (NULL == p->chk_tree)
+ {
+ if (p->is_directory)
+ {
+ /* FIXME: create function to create directory
+ and use that API here! */
+ GNUNET_FS_directory_create (&p->data.dir.dir_size,
+ &p->data.dir.dir_data,
+ p->meta,
+ &directory_entry_lister,
+ p->data.dir.entries);
+ size = p->data.dir.data_size;
+ }
+ p->chk_tree_depth = compute_depth (size);
+ p->chk_tree = GNUNET_malloc (p->chk_tree_depth *
+ sizeof (struct ContentHashKey) *
+ GNUNET_FS_CHK_PER_INODE);
+ p->current_depth = p->chk_tree_depth;
+ }
+ if (p->current_depth == p->chk_tree_depth)
+ {
+ if (p->is_directory)
+ {
+ pt_size = GNUNET_MIN(GNUNET_FS_DBLOCK_SIZE,
+ p->data.dir.dir_size - p->publish_offset);
+ pt_block = &p->data.dir.dir_data[p->publish_offset];
+ }
+ else
+ {
+ pt_size = GNUNET_MIN(GNUNET_FS_DBLOCK_SIZE,
+ p->data.file.file_size - p->publish_offset);
+ p->data.file.reader (p->data.file.reader_cls,
+ p->publish_offset,
+ pt_size,
+ iob,
+ &emsg);
+ pt_block = iob;
+ }
+ }
+ else
+ {
+ pt_size = compute_iblock_size (p->chk_tree_depth - p->current_depth,
+ p->publish_offset);
+ pt_block = &p->chk_tree[p->current_depth *
+ GNUNET_FS_CHK_PER_INODE];
+ }
+ off = compute_chk_offset (p->chk_tree_depth - p->current_depth,
+ p->publish_offset);
+ chk = &p->chk_tree[(p->current_depth-1)*GNUNET_FS_CHK_PER_INODE+off];
+ GNUNET_CRYPTO_hash (pt_block, pt_size, &chk->key);
+ GNUNET_CRYPTO_hash_to_aes_key (&chk->key, &sk, &iv);
+ GNUNET_CRYPTO_aes_encrypt (pt_block,
+ pt_size,
+ &sk,
+ &iv,
+ enc);
+ // NOTE: this call (and progress 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, enc, pt_size,
+ (p->current_depth == p->chk_tree_depth)
+ ? GNUNET_DATASTORE_BLOCKTYPE_DBLOCK
+ : GNUNET_DATASTORE_BLOCKTYPE_IBLOCK,
+ &do_upload);
+ // FIXME: should call progress function somewhere here!
+ GNUNET_CRYPTO_hash (enc, pt_size, &chk->query);
+ if (p->current_depth == p->chk_tree_depth)
+ {
+ p->publish_offset += pt_size;
+ if ( (p->publish_offset == size) ||
+ (0 == p->publish_offset % (GNUNET_FS_CHK_PER_INODE *
GNUNET_FS_DBLOCK_SIZE) ) )
+ p->current_depth--;
+ }
+ else
+ {
+ if ( (off == GNUNET_FS_CHK_PER_INODE) ||
+ (p->publish_offset == size) )
+ p->current_depth--;
+ else
+ p->current_depth = p->chk_tree_depth;
+ }
+ if (0 == p->current_depth)
+ {
+ p->chk_uri = GNUNET_malloc (sizeof(struct GNUNET_FS_Uri));
+ p->chk_uri.type = chk;
+ p->chk_uri.data.chk.chk = p->chk_tree[0];
+ p->chk_uri.data.chk.file_length = size;
+ GNUNET_free (p->chk_tree);
+ p->chk_tree = NULL;
+ }
+}
+
+
+/**
* Main function that performs the upload.
* @param cls "struct GNUNET_FS_PublishContext" identifies the upload
* @param tc task context
@@ -44,11 +423,36 @@
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_FS_PublishContext *sc = cls;
+ struct GNUNET_FS_FileInformation *p;
sc->upload_task = GNUNET_SCHEDULER_NO_TASK;
-
- // FIXME: find next block, process, schedule
- // transmission to FS service
+ p = sc->fi_pos;
+ if (NULL == p)
+ {
+ /* upload of entire hierarchy complete,
+ publish namespace entries */
+ publish_sblock (sc);
+ return;
+ }
+ 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);
+ return;
+ }
+ if (p->do_index)
+ {
+ // FIXME: need to pre-compute hash over
+ // the entire file and ask FS to prepare
+ // for indexing!
+ return;
+ }
+ publish_content (sc, p);
}
@@ -75,8 +479,15 @@
const char *nuid)
{
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;
ret = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishContext));
+ ret->dsh = dsh;
ret->h = h;
ret->client_ctx = ctx;
ret->fi = fi;
@@ -90,6 +501,17 @@
ret->nuid = GNUNET_strdup (nuid);
}
// FIXME: make upload persistent!
+
+ /* 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;
+
+ // FIXME: calculate space needed for "fi"
+ // and reserve as first task (then trigger
+ // "do_upload" from that continuation)!
ret->upload_task
= GNUNET_SCHEDULER_add_delayed (h->sched,
GNUNET_NO,
@@ -120,429 +542,8 @@
GNUNET_FS_namespace_delete (sc->namespace, GNUNET_NO);
GNUNET_free_non_null (sc->nid);
GNUNET_free_non_null (sc->nuid);
+ GNUNET_DATASTORE_disconnect (sc->dsh);
GNUNET_free (sc);
}
-
-#if 0
-
-/**
- * Append the given key and query to the iblock[level]. If
- * iblock[level] is already full, compute its chk and push it to
- * level+1 and clear the level. iblocks is guaranteed to be big
- * enough.
- */
-static int
-pushBlock (struct GNUNET_ClientServerConnection *sock,
- const GNUNET_EC_ContentHashKey * chk,
- unsigned int level,
- GNUNET_DatastoreValue ** iblocks,
- unsigned int prio, GNUNET_CronTime expirationTime)
-{
- unsigned int size;
- unsigned int present;
- GNUNET_DatastoreValue *value;
- GNUNET_EC_DBlock *db;
- GNUNET_EC_ContentHashKey ichk;
-
- size = ntohl (iblocks[level]->size);
- GNUNET_GE_ASSERT (NULL, size > sizeof (GNUNET_DatastoreValue));
- size -= sizeof (GNUNET_DatastoreValue);
- GNUNET_GE_ASSERT (NULL,
- size - sizeof (GNUNET_EC_DBlock) <=
- GNUNET_ECRS_IBLOCK_SIZE);
- present =
- (size - sizeof (GNUNET_EC_DBlock)) / sizeof (GNUNET_EC_ContentHashKey);
- db = (GNUNET_EC_DBlock *) & iblocks[level][1];
- if (present == GNUNET_ECRS_CHK_PER_INODE)
- {
- GNUNET_EC_file_block_get_key (db, size, &ichk.key);
- GNUNET_EC_file_block_get_query (db, size, &ichk.query);
- if (GNUNET_OK != pushBlock (sock,
- &ichk, level + 1, iblocks, prio,
- expirationTime))
- return GNUNET_SYSERR;
- GNUNET_EC_file_block_encode (db, size, &ichk.query, &value);
- if (value == NULL)
- {
- GNUNET_GE_BREAK (NULL, 0);
- return GNUNET_SYSERR;
- }
- value->priority = htonl (prio);
- value->expiration_time = GNUNET_htonll (expirationTime);
- if (GNUNET_OK != GNUNET_FS_insert (sock, value))
- {
- GNUNET_free (value);
- return GNUNET_SYSERR;
- }
- GNUNET_free (value);
- size = sizeof (GNUNET_EC_DBlock); /* type */
- }
- /* append GNUNET_EC_ContentHashKey */
- memcpy (&((char *) db)[size], chk, sizeof (GNUNET_EC_ContentHashKey));
- size += sizeof (GNUNET_EC_ContentHashKey) + sizeof (GNUNET_DatastoreValue);
- GNUNET_GE_ASSERT (NULL, size < GNUNET_MAX_BUFFER_SIZE);
- iblocks[level]->size = htonl (size);
-
- return GNUNET_OK;
-}
-
-/**
- * Index or insert a file.
- *
- * @param priority what is the priority for OUR node to
- * keep this file available? Use 0 for maximum anonymity and
- * minimum reliability...
- * @param doIndex GNUNET_YES for index, GNUNET_NO for insertion,
- * GNUNET_SYSERR for simulation
- * @param uri set to the URI of the uploaded file
- * @return GNUNET_SYSERR if the upload failed (i.e. not enough space
- * or gnunetd not running)
- */
-int
-GNUNET_ECRS_file_upload (struct GNUNET_GE_Context *ectx,
- struct GNUNET_GC_Configuration *cfg,
- const char *filename,
- int doIndex,
- unsigned int anonymityLevel,
- unsigned int priority,
- GNUNET_CronTime expirationTime,
- GNUNET_ECRS_UploadProgressCallback upcb,
- void *upcbClosure,
- GNUNET_ECRS_TestTerminate tt,
- void *ttClosure, struct GNUNET_ECRS_URI **uri)
-{
- unsigned long long filesize;
- unsigned long long pos;
- unsigned int treedepth;
- int fd;
- int i;
- int ret;
- unsigned int size;
- GNUNET_DatastoreValue **iblocks;
- GNUNET_DatastoreValue *dblock;
- GNUNET_EC_DBlock *db;
- GNUNET_DatastoreValue *value;
- struct GNUNET_ClientServerConnection *sock;
- GNUNET_HashCode fileId;
- GNUNET_EC_ContentHashKey mchk;
- GNUNET_CronTime eta;
- GNUNET_CronTime start;
- GNUNET_CronTime now;
- GNUNET_EC_FileIdentifier fid;
-#if DEBUG_UPLOAD
- GNUNET_EncName enc;
-#endif
-
- GNUNET_GE_ASSERT (ectx, cfg != NULL);
- start = GNUNET_get_time ();
- memset (&mchk, 0, sizeof (GNUNET_EC_ContentHashKey));
- if (GNUNET_YES != GNUNET_disk_file_test (ectx, filename))
- {
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
- _("`%s' is not a file.\n"), filename);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- GNUNET_disk_file_size (ectx, filename, &filesize, GNUNET_YES))
- {
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
- _("Cannot get size of file `%s'"), filename);
-
- return GNUNET_SYSERR;
- }
- sock = GNUNET_client_connection_create (ectx, cfg);
- if (sock == NULL)
- {
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
- _("Failed to connect to gnunetd."));
- return GNUNET_SYSERR;
- }
- eta = 0;
- if (upcb != NULL)
- upcb (filesize, 0, eta, upcbClosure);
- if (doIndex == GNUNET_YES)
- {
- if (GNUNET_SYSERR == GNUNET_hash_file (ectx, filename, &fileId))
- {
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
- _("Cannot hash `%s'.\n"), filename);
-
- GNUNET_client_connection_destroy (sock);
- return GNUNET_SYSERR;
- }
- if (GNUNET_YES == GNUNET_FS_test_indexed (sock, &fileId))
- {
- /* file already indexed; simulate only to get the URI! */
- doIndex = GNUNET_SYSERR;
- }
- }
- if (doIndex == GNUNET_YES)
- {
- now = GNUNET_get_time ();
- eta = now + 2 * (now - start);
- /* very rough estimate: GNUNET_hash reads once through the file,
- we'll do that once more and write it. But of course
- the second read may be cached, and we have the encryption,
- so a factor of two is really, really just a rough estimate */
- start = now;
- /* reset the counter since the formula later does not
- take the time for GNUNET_hash_file into account */
-
- switch (GNUNET_FS_prepare_to_index (sock, &fileId, filename))
- {
- case GNUNET_SYSERR:
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
- _("Initialization for indexing file `%s' failed.\n"),
- filename);
- GNUNET_client_connection_destroy (sock);
- return GNUNET_SYSERR;
- case GNUNET_NO:
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
- _
- ("Indexing file `%s' failed. Suggestion: try to
insert the file.\n"),
- filename);
- GNUNET_client_connection_destroy (sock);
- return GNUNET_SYSERR;
- default:
- break;
- }
- }
- treedepth = GNUNET_ECRS_compute_depth (filesize);
- fd = GNUNET_disk_file_open (ectx, filename, O_RDONLY | O_LARGEFILE);
- if (fd == -1)
- {
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
- _("Cannot open file `%s': `%s'"), filename,
- STRERROR (errno));
-
- GNUNET_client_connection_destroy (sock);
- return GNUNET_SYSERR;
- }
-
- dblock =
- GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + GNUNET_ECRS_DBLOCK_SIZE +
- sizeof (GNUNET_EC_DBlock));
- dblock->size =
- htonl (sizeof (GNUNET_DatastoreValue) + GNUNET_ECRS_DBLOCK_SIZE +
- sizeof (GNUNET_EC_DBlock));
- dblock->anonymity_level = htonl (anonymityLevel);
- dblock->priority = htonl (priority);
- dblock->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
- dblock->expiration_time = GNUNET_htonll (expirationTime);
- db = (GNUNET_EC_DBlock *) & dblock[1];
- db->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
- iblocks =
- GNUNET_malloc (sizeof (GNUNET_DatastoreValue *) * (treedepth + 1));
- for (i = 0; i <= treedepth; i++)
- {
- iblocks[i] =
- GNUNET_malloc (sizeof (GNUNET_DatastoreValue) +
- GNUNET_ECRS_IBLOCK_SIZE + sizeof (GNUNET_EC_DBlock));
- iblocks[i]->size =
- htonl (sizeof (GNUNET_DatastoreValue) + sizeof (GNUNET_EC_DBlock));
- iblocks[i]->anonymity_level = htonl (anonymityLevel);
- iblocks[i]->priority = htonl (priority);
- iblocks[i]->type = htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
- iblocks[i]->expiration_time = GNUNET_htonll (expirationTime);
- ((GNUNET_EC_DBlock *) & iblocks[i][1])->type =
- htonl (GNUNET_ECRS_BLOCKTYPE_DATA);
- }
-
- pos = 0;
- while (pos < filesize)
- {
- if (upcb != NULL)
- upcb (filesize, pos, eta, upcbClosure);
- if (tt != NULL)
- if (GNUNET_OK != tt (ttClosure))
- goto FAILURE;
- size = GNUNET_ECRS_DBLOCK_SIZE;
- if (size > filesize - pos)
- {
- size = filesize - pos;
- memset (&db[1], 0, GNUNET_ECRS_DBLOCK_SIZE);
- }
- GNUNET_GE_ASSERT (ectx,
- sizeof (GNUNET_DatastoreValue) + size +
- sizeof (GNUNET_EC_DBlock) < GNUNET_MAX_BUFFER_SIZE);
- dblock->size =
- htonl (sizeof (GNUNET_DatastoreValue) + size +
- sizeof (GNUNET_EC_DBlock));
- if (size != READ (fd, &db[1], size))
- {
- GNUNET_GE_LOG_STRERROR_FILE (ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK |
- GNUNET_GE_ADMIN | GNUNET_GE_USER,
- "READ", filename);
- goto FAILURE;
- }
- if (tt != NULL)
- if (GNUNET_OK != tt (ttClosure))
- goto FAILURE;
- GNUNET_EC_file_block_get_key (db, size + sizeof (GNUNET_EC_DBlock),
- &mchk.key);
- GNUNET_EC_file_block_get_query (db, size + sizeof (GNUNET_EC_DBlock),
- &mchk.query);
-#if DEBUG_UPLOAD
- GNUNET_hash_to_enc (&mchk.query, &enc);
- fprintf (stderr,
- "Query for current block of size %u is `%s'\n", size,
- (const char *) &enc);
-#endif
- if (doIndex == GNUNET_YES)
- {
- if (GNUNET_SYSERR == GNUNET_FS_index (sock, &fileId, dblock, pos))
- {
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_ERROR | GNUNET_GE_BULK |
- GNUNET_GE_USER,
- _
- ("Indexing data of file `%s' failed at position
%llu.\n"),
- filename, pos);
- goto FAILURE;
- }
- }
- else
- {
- value = NULL;
- if (GNUNET_OK !=
- GNUNET_EC_file_block_encode (db,
- size + sizeof (GNUNET_EC_DBlock),
- &mchk.query, &value))
- {
- GNUNET_GE_BREAK (ectx, 0);
- goto FAILURE;
- }
- GNUNET_GE_ASSERT (ectx, value != NULL);
- *value = *dblock; /* copy options! */
- if ((doIndex == GNUNET_NO) &&
- (GNUNET_OK != (ret = GNUNET_FS_insert (sock, value))))
- {
- GNUNET_GE_BREAK (ectx, ret == GNUNET_NO);
- GNUNET_free (value);
- goto FAILURE;
- }
- GNUNET_free (value);
- }
- pos += size;
- now = GNUNET_get_time ();
- if (pos > 0)
- {
- eta = (GNUNET_CronTime) (start +
- (((double) (now - start) / (double) pos))
- * (double) filesize);
- }
- if (GNUNET_OK != pushBlock (sock, &mchk, 0, /* dblocks are on
level 0 */
- iblocks, priority, expirationTime))
- goto FAILURE;
- }
- if (tt != NULL)
- if (GNUNET_OK != tt (ttClosure))
- goto FAILURE;
-#if DEBUG_UPLOAD
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
- "Tree depth is %u, walking up tree.\n", treedepth);
-#endif
- for (i = 0; i < treedepth; i++)
- {
- size = ntohl (iblocks[i]->size) - sizeof (GNUNET_DatastoreValue);
- GNUNET_GE_ASSERT (ectx, size < GNUNET_MAX_BUFFER_SIZE);
- if (size == sizeof (GNUNET_EC_DBlock))
- {
-#if DEBUG_UPLOAD
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
- "Level %u is empty\n", i);
-#endif
- continue;
- }
- db = (GNUNET_EC_DBlock *) & iblocks[i][1];
- GNUNET_EC_file_block_get_key (db, size, &mchk.key);
-#if DEBUG_UPLOAD
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
- "Computing query for %u bytes content.\n", size);
-#endif
- GNUNET_EC_file_block_get_query (db, size, &mchk.query);
-#if DEBUG_UPLOAD
- IF_GELOG (ectx,
- GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
- GNUNET_hash_to_enc (&mchk.query, &enc));
- GNUNET_GE_LOG (ectx,
- GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
- "Query for current block at level %u is `%s'.\n", i,
- &enc);
-#endif
- if (GNUNET_OK != pushBlock (sock,
- &mchk, i + 1, iblocks, priority,
- expirationTime))
- {
- GNUNET_GE_BREAK (ectx, 0);
- goto FAILURE;
- }
- GNUNET_EC_file_block_encode (db, size, &mchk.query, &value);
- if (value == NULL)
- {
- GNUNET_GE_BREAK (ectx, 0);
- goto FAILURE;
- }
- value->expiration_time = GNUNET_htonll (expirationTime);
- value->priority = htonl (priority);
- if ((doIndex != GNUNET_SYSERR) &&
- (GNUNET_SYSERR == GNUNET_FS_insert (sock, value)))
- {
- GNUNET_GE_BREAK (ectx, 0);
- GNUNET_free (value);
- goto FAILURE;
- }
- GNUNET_free (value);
- GNUNET_free (iblocks[i]);
- iblocks[i] = NULL;
- }
-#if DEBUG_UPLOAD
- IF_GELOG (ectx,
- GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
- GNUNET_hash_to_enc (&mchk.query, &enc));
- GNUNET_GE_LOG (ectx, GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
- "Query for top block is %s\n", &enc);
-#endif
- /* build URI */
- fid.file_length = GNUNET_htonll (filesize);
- db = (GNUNET_EC_DBlock *) & iblocks[treedepth][1];
-
- fid.chk = *(GNUNET_EC_ContentHashKey *) & (db[1]);
- *uri = GNUNET_malloc (sizeof (URI));
- (*uri)->type = chk;
- (*uri)->data.fi = fid;
-
- /* free resources */
- GNUNET_free_non_null (iblocks[treedepth]);
- GNUNET_free (iblocks);
- GNUNET_free (dblock);
- if (upcb != NULL)
- upcb (filesize, filesize, eta, upcbClosure);
- CLOSE (fd);
- GNUNET_client_connection_destroy (sock);
- return GNUNET_OK;
-FAILURE:
- for (i = 0; i <= treedepth; i++)
- GNUNET_free_non_null (iblocks[i]);
- GNUNET_free (iblocks);
- GNUNET_free (dblock);
- CLOSE (fd);
- GNUNET_client_connection_destroy (sock);
- return GNUNET_SYSERR;
-}
-
-#endif
-
/* end of fs_publish.c */
Modified: gnunet/src/include/gnunet_constants.h
===================================================================
--- gnunet/src/include/gnunet_constants.h 2009-08-26 20:47:59 UTC (rev
8862)
+++ gnunet/src/include/gnunet_constants.h 2009-08-27 11:14:19 UTC (rev
8863)
@@ -55,7 +55,14 @@
*/
#define GNUNET_CONSTANTS_EXEC_WAIT GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_MILLISECONDS, 100)
+/**
+ * After how long do we consider a service irresponsive
+ * even if we assume that the service commonly does not
+ * respond instantly (DNS, Database, etc.).
+ */
+#define GNUNET_CONSTANTS_SERVICE_TIMEOUT GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_MINUTES, 10)
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
Modified: gnunet/src/include/gnunet_container_lib.h
===================================================================
--- gnunet/src/include/gnunet_container_lib.h 2009-08-26 20:47:59 UTC (rev
8862)
+++ gnunet/src/include/gnunet_container_lib.h 2009-08-27 11:14:19 UTC (rev
8863)
@@ -305,8 +305,8 @@
enum GNUNET_CONTAINER_MetaDataSerializationOptions
{
- GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL = GNUNET_NO,
- GNUNET_CONTAINER_META_DATA_SERIALIZE_PART = GNUNET_YES,
+ GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL = 0,
+ GNUNET_CONTAINER_META_DATA_SERIALIZE_PART = 1,
GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS = 2
};
@@ -323,10 +323,11 @@
* GNUNET_SYSERR on error (typically: not enough
* space)
*/
-int GNUNET_CONTAINER_meta_data_serialize (const struct
- GNUNET_CONTAINER_MetaData *md,
- char *target, unsigned int size,
- enum
+ssize_t GNUNET_CONTAINER_meta_data_serialize (const struct
+ GNUNET_CONTAINER_MetaData *md,
+ char *target,
+ size_t size,
+ enum
GNUNET_CONTAINER_MetaDataSerializationOptions
opt);
@@ -337,12 +338,12 @@
* meta-data to match the size constraint,
* possibly discarding some data?
*/
-unsigned int GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
-
GNUNET_CONTAINER_MetaData
- *md,
- enum
-
GNUNET_CONTAINER_MetaDataSerializationOptions
- opt);
+ssize_t GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
+
GNUNET_CONTAINER_MetaData
+ *md,
+ enum
+
GNUNET_CONTAINER_MetaDataSerializationOptions
+ opt);
/**
* Deserialize meta-data. Initializes md.
@@ -352,7 +353,7 @@
*/
struct GNUNET_CONTAINER_MetaData
*GNUNET_CONTAINER_meta_data_deserialize (const char *input,
- unsigned int size);
+ size_t size);
/**
* Does the meta-data claim that this is a directory?
Modified: gnunet/src/include/gnunet_crypto_lib.h
===================================================================
--- gnunet/src/include/gnunet_crypto_lib.h 2009-08-26 20:47:59 UTC (rev
8862)
+++ gnunet/src/include/gnunet_crypto_lib.h 2009-08-27 11:14:19 UTC (rev
8863)
@@ -394,7 +394,7 @@
/**
* Convert a hashcode into a key.
*/
-void GNUNET_CRYPTO_hash_to_AES_key (const GNUNET_HashCode * hc,
+void GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc,
struct GNUNET_CRYPTO_AesSessionKey *skey,
struct
GNUNET_CRYPTO_AesInitializationVector
Modified: gnunet/src/include/gnunet_datastore_service.h
===================================================================
--- gnunet/src/include/gnunet_datastore_service.h 2009-08-26 20:47:59 UTC
(rev 8862)
+++ gnunet/src/include/gnunet_datastore_service.h 2009-08-27 11:14:19 UTC
(rev 8863)
@@ -41,6 +41,12 @@
#endif
#endif
+#define GNUNET_DATASTORE_BLOCKTYPE_ANY 0
+#define GNUNET_DATASTORE_BLOCKTYPE_DBLOCK 1
+#define GNUNET_DATASTORE_BLOCKTYPE_IBLOCK 2
+#define GNUNET_DATASTORE_BLOCKTYPE_KBLOCK 3
+#define GNUNET_DATASTORE_BLOCKTYPE_SBLOCK 4
+#define GNUNET_DATASTORE_BLOCKTYPE_SKBLOCK 5
/**
* Handle to the datastore service.
Modified: gnunet/src/include/gnunet_fs_service.h
===================================================================
--- gnunet/src/include/gnunet_fs_service.h 2009-08-26 20:47:59 UTC (rev
8862)
+++ gnunet/src/include/gnunet_fs_service.h 2009-08-27 11:14:19 UTC (rev
8863)
@@ -2169,6 +2169,52 @@
void *dep_cls);
+/**
+ * Opaque handle to a directory builder.
+ */
+struct GNUNET_FS_DirectoryBuilder;
+
+/**
+ * Create a directory builder.
+ *
+ * @param mdir metadata for the directory
+ */
+struct GNUNET_FS_DirectoryBuilder *
+GNUNET_FS_directory_builder_create (const struct GNUNET_CONTAINER_MetaData
*mdir);
+
+
+/**
+ * Add an entry to a directory.
+ *
+ * @param bld directory to extend
+ * @param uri uri of the entry (must not be a KSK)
+ * @param md metadata of the entry
+ * @param data raw data of the entry, can be NULL, otherwise
+ * data must point to exactly the number of bytes specified
+ * by the uri
+ */
+void
+GNUNET_FS_directory_builder_add (struct GNUNET_FS_DirectoryBuilder *bld,
+ const struct GNUNET_FS_Uri *uri,
+ const struct GNUNET_CONTAINER_MetaData *md,
+ const void *data);
+
+
+/**
+ * Finish building the directory. Frees the
+ * builder context and returns the directory
+ * in-memory.
+ *
+ * @param bld directory to finish
+ * @param size set to the number of bytes needed
+ * @param data set to the encoded directory
+ */
+void
+GNUNET_FS_directory_builder_finish (struct GNUNET_FS_DirectoryBuilder *bld,
+ size_t *size,
+ void **data);
+
+
#if 0 /* keep Emacsens' auto-indent happy */
{
#endif
Property changes on: gnunet/src/testing
___________________________________________________________________
Modified: svn:ignore
- Makefile.in
Makefile
.deps
+ test_testing.gcno
test_testing.gcda
test_testing
Makefile.in
Makefile
.deps
Property changes on: gnunet/src/transport
___________________________________________________________________
Modified: svn:ignore
- test_plugin_transport
transport_api.gcno
transport_api.gcda
plugin_transport_template.gcno
plugin_transport_tcp.gcno
plugin_transport_tcp.gcda
test_transport_api.gcda
gnunet-service-transport.gcda
test_transport_api.gcno
test_transport_api
Makefile.in
Makefile
gnunet-transport.gcno
gnunet-transport
gnunet-service-transport.gcno
gnunet-service-transport
core
.deps
+ test_plugin_transport.gcno
test_plugin_transport.gcda
test_plugin_transport
transport_api.gcno
transport_api.gcda
plugin_transport_template.gcno
plugin_transport_tcp.gcno
plugin_transport_tcp.gcda
test_transport_api.gcda
gnunet-service-transport.gcda
test_transport_api.gcno
test_transport_api
Makefile.in
Makefile
gnunet-transport.gcno
gnunet-transport
gnunet-service-transport.gcno
gnunet-service-transport
core
.deps
Property changes on: gnunet/src/upnp
___________________________________________________________________
Added: svn:ignore
+ Makefile.in
Modified: gnunet/src/util/container_meta_data.c
===================================================================
--- gnunet/src/util/container_meta_data.c 2009-08-26 20:47:59 UTC (rev
8862)
+++ gnunet/src/util/container_meta_data.c 2009-08-27 11:14:19 UTC (rev
8863)
@@ -442,9 +442,9 @@
* GNUNET_SYSERR on error (typically: not enough
* space)
*/
-int
+ssize_t
GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData
- *md, char *target, unsigned int max,
+ *md, char *target, size_t max,
enum
GNUNET_CONTAINER_MetaDataSerializationOptions
part)
@@ -463,7 +463,7 @@
while (1)
{
size = sizeof (struct MetaDataHeader);
- size += sizeof (unsigned int) * ic;
+ size += sizeof (uint32_t) * ic;
for (i = 0; i < ic; i++)
size += 1 + strlen (md->items[i].data);
while (size % 8 != 0)
@@ -472,8 +472,8 @@
hdr->version = htonl (md == NULL ? 1 : 0);
hdr->entries = htonl (ic);
for (i = 0; i < ic; i++)
- ((unsigned int *) &hdr[1])[i] =
- htonl ((unsigned int) md->items[i].type);
+ ((uint32_t *) &hdr[1])[i] =
+ htonl ((uint32_t) md->items[i].type);
pos = sizeof (struct MetaDataHeader);
pos += sizeof (unsigned int) * ic;
for (i = 0; i < ic; i++)
@@ -533,7 +533,7 @@
* serialized form. The estimate MAY be higher
* than what is strictly needed.
*/
-unsigned int
+ssize_t
GNUNET_CONTAINER_meta_data_get_serialized_size (const struct
GNUNET_CONTAINER_MetaData *md,
enum
@@ -549,7 +549,7 @@
ic = md ? md->itemCount : 0;
size = sizeof (struct MetaDataHeader);
- size += sizeof (unsigned int) * ic;
+ size += sizeof (uint32_t) * ic;
for (i = 0; i < ic; i++)
size += 1 + strlen (md->items[i].data);
while (size % 8 != 0)
@@ -558,9 +558,9 @@
hdr->version = htonl (md == NULL ? 1 : 0);
hdr->entries = htonl (ic);
for (i = 0; i < ic; i++)
- ((unsigned int *) &hdr[1])[i] = htonl ((unsigned int) md->items[i].type);
+ ((uint32_t *) &hdr[1])[i] = htonl ((uint32_t) md->items[i].type);
pos = sizeof (struct MetaDataHeader);
- pos += sizeof (unsigned int) * ic;
+ pos += sizeof (uint32_t) * ic;
for (i = 0; i < ic; i++)
{
len = strlen (md->items[i].data) + 1;
@@ -590,7 +590,7 @@
* bad format)
*/
struct GNUNET_CONTAINER_MetaData *
-GNUNET_CONTAINER_meta_data_deserialize (const char *input, unsigned int size)
+GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size)
{
struct GNUNET_CONTAINER_MetaData *md;
const struct MetaDataHeader *hdr;
@@ -599,9 +599,9 @@
const char *cdata;
uint32_t dataSize;
int compressed;
- int i;
- unsigned int pos;
- int len;
+ uint32_t i;
+ size_t pos;
+ size_t len;
uint32_t version;
if (size < sizeof (struct MetaDataHeader))
@@ -651,7 +651,7 @@
}
}
- if ((sizeof (unsigned int) * ic + ic) > dataSize)
+ if ((sizeof (uint32_t) * ic + ic) > dataSize)
{
GNUNET_break (0);
goto FAILURE;
@@ -665,12 +665,12 @@
md = GNUNET_CONTAINER_meta_data_create ();
GNUNET_array_grow (md->items, md->itemCount, ic);
i = 0;
- pos = sizeof (unsigned int) * ic;
+ pos = sizeof (uint32_t) * ic;
while ((pos < dataSize) && (i < ic))
{
len = strlen (&cdata[pos]) + 1;
md->items[i].type = (EXTRACTOR_KeywordType)
- ntohl (MAKE_UNALIGNED (((const unsigned int *) cdata)[i]));
+ ntohl (MAKE_UNALIGNED (((const uint32_t *) cdata)[i]));
md->items[i].data = GNUNET_strdup (&cdata[pos]);
pos += len;
i++;
Modified: gnunet/src/util/crypto_hash.c
===================================================================
--- gnunet/src/util/crypto_hash.c 2009-08-26 20:47:59 UTC (rev 8862)
+++ gnunet/src/util/crypto_hash.c 2009-08-27 11:14:19 UTC (rev 8863)
@@ -709,7 +709,7 @@
* Convert a hashcode into a key.
*/
void
-GNUNET_CRYPTO_hash_to_AES_key (const GNUNET_HashCode * hc,
+GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc,
struct GNUNET_CRYPTO_AesSessionKey *skey,
struct GNUNET_CRYPTO_AesInitializationVector
*iv)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r8863 - in gnunet: . doc/man src/datacache src/datastore src/fs src/include src/testing src/transport src/upnp src/util,
gnunet <=