aboutsummaryrefslogtreecommitdiff
path: root/src/fs
diff options
context:
space:
mode:
authorBertrand Marc <beberking@gmail.com>2012-06-06 20:47:48 +0200
committerBertrand Marc <beberking@gmail.com>2012-06-06 20:47:48 +0200
commit740b30688bd745a527f96f9116c19acb3480971a (patch)
tree2709a3f4dba11c174aa9e1ba3612e30c578e76a9 /src/fs
parent2b81464a43485fcc8ce079fafdee7b7a171835f4 (diff)
Imported Upstream version 0.9.3upstream/0.9.3
Diffstat (limited to 'src/fs')
-rw-r--r--src/fs/Makefile.am14
-rw-r--r--src/fs/Makefile.in33
-rw-r--r--src/fs/fs.conf.in13
-rw-r--r--src/fs/fs_api.c134
-rw-r--r--src/fs/fs_api.h154
-rw-r--r--src/fs/fs_dirmetascan.c26
-rw-r--r--src/fs/fs_download.c577
-rw-r--r--src/fs/fs_file_information.c10
-rw-r--r--src/fs/fs_list_indexed.c2
-rw-r--r--src/fs/fs_publish.c34
-rw-r--r--src/fs/fs_publish_ksk.c2
-rw-r--r--src/fs/fs_search.c266
-rw-r--r--src/fs/fs_tree.c7
-rw-r--r--src/fs/fs_unindex.c349
-rw-r--r--src/fs/fs_uri.c16
-rw-r--r--src/fs/gnunet-directory.c2
-rw-r--r--src/fs/gnunet-download.c3
-rw-r--r--src/fs/gnunet-helper-fs-publish.c55
-rw-r--r--src/fs/gnunet-pseudonym.c22
-rw-r--r--src/fs/gnunet-publish.c6
-rw-r--r--src/fs/gnunet-service-fs.h2
-rw-r--r--src/fs/gnunet-service-fs_indexing.c2
-rw-r--r--src/fs/gnunet-service-fs_lc.c6
-rw-r--r--src/fs/gnunet-service-fs_pr.c4
-rw-r--r--src/fs/gnunet-service-fs_put.c74
-rw-r--r--src/fs/perf_gnunet_service_fs_p2p.c2
-rw-r--r--src/fs/test_fs_defaults.conf3
-rw-r--r--src/fs/test_fs_download.c4
-rw-r--r--src/fs/test_fs_download_indexed.c20
-rw-r--r--src/fs/test_fs_download_persistence.c4
-rw-r--r--src/fs/test_fs_list_indexed.c2
-rw-r--r--src/fs/test_fs_namespace.c19
-rw-r--r--src/fs/test_fs_namespace_list_updateable.c2
-rw-r--r--src/fs/test_fs_publish.c2
-rw-r--r--src/fs/test_fs_publish_persistence.c2
-rw-r--r--src/fs/test_fs_search.c12
-rw-r--r--src/fs/test_fs_search_persistence.c2
-rw-r--r--src/fs/test_fs_search_probes.c268
-rw-r--r--src/fs/test_fs_start_stop.c2
-rw-r--r--src/fs/test_fs_test_lib.c7
-rw-r--r--src/fs/test_fs_unindex.c2
-rw-r--r--src/fs/test_fs_unindex_persistence.c2
-rw-r--r--[-rwxr-xr-x]src/fs/test_gnunet_fs_idx.py.in0
-rw-r--r--[-rwxr-xr-x]src/fs/test_gnunet_fs_ns.py.in0
-rw-r--r--[-rwxr-xr-x]src/fs/test_gnunet_fs_psd.py.in0
-rw-r--r--[-rwxr-xr-x]src/fs/test_gnunet_fs_rec.py.in0
-rw-r--r--src/fs/test_gnunet_service_fs_migration.c4
-rw-r--r--src/fs/test_gnunet_service_fs_p2p.c2
48 files changed, 1600 insertions, 574 deletions
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index 0de739d..b916e4e 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -50,7 +50,7 @@ libgnunetfs_la_LIBADD = \
libgnunetfs_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) $(WINFLAGS) \
- -version-info 2:0:0
+ -version-info 2:1:0
libgnunetfstest_a_SOURCES = \
@@ -206,6 +206,7 @@ check_PROGRAMS = \
test_fs_publish \
test_fs_publish_persistence \
test_fs_search \
+ test_fs_search_probes \
test_fs_search_persistence \
test_fs_start_stop \
test_fs_test_lib \
@@ -225,6 +226,11 @@ check_SCRIPTS = \
test_gnunet_fs_ns.py
endif
+if ENABLE_MONKEY
+ TESTS_ENVIRONMENT = @MONKEYPREFIX@
+ AM_LDFLAGS = -no-install
+endif
+
if ENABLE_TEST_RUN
TESTS = \
@@ -239,6 +245,7 @@ TESTS = \
test_fs_publish \
test_fs_publish_persistence \
test_fs_search \
+ test_fs_search_probes \
test_fs_search_persistence \
test_fs_start_stop \
test_fs_unindex \
@@ -329,6 +336,11 @@ test_fs_search_SOURCES = \
test_fs_search_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \
$(top_builddir)/src/util/libgnunetutil.la
+test_fs_search_probes_SOURCES = \
+ test_fs_search_probes.c
+test_fs_search_probes_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
test_fs_search_persistence_SOURCES = \
test_fs_search_persistence.c
test_fs_search_persistence_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \
diff --git a/src/fs/Makefile.in b/src/fs/Makefile.in
index cbc844e..1dc8dba 100644
--- a/src/fs/Makefile.in
+++ b/src/fs/Makefile.in
@@ -51,7 +51,8 @@ check_PROGRAMS = test_fs_directory$(EXEEXT) test_fs_download$(EXEEXT) \
test_fs_list_indexed$(EXEEXT) test_fs_namespace$(EXEEXT) \
test_fs_namespace_list_updateable$(EXEEXT) \
test_fs_publish$(EXEEXT) test_fs_publish_persistence$(EXEEXT) \
- test_fs_search$(EXEEXT) test_fs_search_persistence$(EXEEXT) \
+ test_fs_search$(EXEEXT) test_fs_search_probes$(EXEEXT) \
+ test_fs_search_persistence$(EXEEXT) \
test_fs_start_stop$(EXEEXT) test_fs_test_lib$(EXEEXT) \
test_fs_unindex$(EXEEXT) test_fs_unindex_persistence$(EXEEXT) \
test_fs_uri$(EXEEXT) test_gnunet_service_fs_migration$(EXEEXT) \
@@ -67,6 +68,7 @@ check_PROGRAMS = test_fs_directory$(EXEEXT) test_fs_download$(EXEEXT) \
@ENABLE_TEST_RUN_TRUE@ test_fs_publish$(EXEEXT) \
@ENABLE_TEST_RUN_TRUE@ test_fs_publish_persistence$(EXEEXT) \
@ENABLE_TEST_RUN_TRUE@ test_fs_search$(EXEEXT) \
+@ENABLE_TEST_RUN_TRUE@ test_fs_search_probes$(EXEEXT) \
@ENABLE_TEST_RUN_TRUE@ test_fs_search_persistence$(EXEEXT) \
@ENABLE_TEST_RUN_TRUE@ test_fs_start_stop$(EXEEXT) \
@ENABLE_TEST_RUN_TRUE@ test_fs_unindex$(EXEEXT) \
@@ -310,6 +312,11 @@ test_fs_search_persistence_OBJECTS = \
test_fs_search_persistence_DEPENDENCIES = \
$(top_builddir)/src/fs/libgnunetfs.la \
$(top_builddir)/src/util/libgnunetutil.la
+am_test_fs_search_probes_OBJECTS = test_fs_search_probes.$(OBJEXT)
+test_fs_search_probes_OBJECTS = $(am_test_fs_search_probes_OBJECTS)
+test_fs_search_probes_DEPENDENCIES = \
+ $(top_builddir)/src/fs/libgnunetfs.la \
+ $(top_builddir)/src/util/libgnunetutil.la
am_test_fs_start_stop_OBJECTS = test_fs_start_stop.$(OBJEXT)
test_fs_start_stop_OBJECTS = $(am_test_fs_start_stop_OBJECTS)
test_fs_start_stop_DEPENDENCIES = \
@@ -401,8 +408,8 @@ SOURCES = $(libgnunetfstest_a_SOURCES) \
$(test_fs_publish_persistence_SOURCES) \
$(test_fs_search_SOURCES) \
$(test_fs_search_persistence_SOURCES) \
- $(test_fs_start_stop_SOURCES) $(test_fs_test_lib_SOURCES) \
- $(test_fs_unindex_SOURCES) \
+ $(test_fs_search_probes_SOURCES) $(test_fs_start_stop_SOURCES) \
+ $(test_fs_test_lib_SOURCES) $(test_fs_unindex_SOURCES) \
$(test_fs_unindex_persistence_SOURCES) $(test_fs_uri_SOURCES) \
$(test_gnunet_service_fs_migration_SOURCES) \
$(test_gnunet_service_fs_p2p_SOURCES)
@@ -428,8 +435,8 @@ DIST_SOURCES = $(libgnunetfstest_a_SOURCES) \
$(test_fs_publish_persistence_SOURCES) \
$(test_fs_search_SOURCES) \
$(test_fs_search_persistence_SOURCES) \
- $(test_fs_start_stop_SOURCES) $(test_fs_test_lib_SOURCES) \
- $(test_fs_unindex_SOURCES) \
+ $(test_fs_search_probes_SOURCES) $(test_fs_start_stop_SOURCES) \
+ $(test_fs_test_lib_SOURCES) $(test_fs_unindex_SOURCES) \
$(test_fs_unindex_persistence_SOURCES) $(test_fs_uri_SOURCES) \
$(test_gnunet_service_fs_migration_SOURCES) \
$(test_gnunet_service_fs_p2p_SOURCES)
@@ -494,6 +501,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INTLLIBS = @INTLLIBS@
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+JAVAPORT = @JAVAPORT@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBADD_DL = @LIBADD_DL@
@@ -527,6 +535,7 @@ LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+MONKEYPREFIX = @MONKEYPREFIX@
MSGFMT = @MSGFMT@
MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
@@ -683,7 +692,7 @@ libgnunetfs_la_LIBADD = \
libgnunetfs_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) $(WINFLAGS) \
- -version-info 2:0:0
+ -version-info 2:1:0
libgnunetfstest_a_SOURCES = \
fs_test_lib.c fs_test_lib.h
@@ -836,6 +845,8 @@ libgnunet_plugin_block_fs_la_DEPENDENCIES = \
@HAVE_PYTHON_PEXPECT_TRUE@ test_gnunet_fs_idx.py \
@HAVE_PYTHON_PEXPECT_TRUE@ test_gnunet_fs_ns.py
+@ENABLE_MONKEY_TRUE@TESTS_ENVIRONMENT = @MONKEYPREFIX@
+@ENABLE_MONKEY_TRUE@AM_LDFLAGS = -no-install
test_fs_directory_SOURCES = \
test_fs_directory.c
@@ -921,6 +932,12 @@ test_fs_search_SOURCES = \
test_fs_search_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \
$(top_builddir)/src/util/libgnunetutil.la
+test_fs_search_probes_SOURCES = \
+ test_fs_search_probes.c
+
+test_fs_search_probes_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
test_fs_search_persistence_SOURCES = \
test_fs_search_persistence.c
@@ -1288,6 +1305,9 @@ test_fs_search$(EXEEXT): $(test_fs_search_OBJECTS) $(test_fs_search_DEPENDENCIES
test_fs_search_persistence$(EXEEXT): $(test_fs_search_persistence_OBJECTS) $(test_fs_search_persistence_DEPENDENCIES)
@rm -f test_fs_search_persistence$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_fs_search_persistence_OBJECTS) $(test_fs_search_persistence_LDADD) $(LIBS)
+test_fs_search_probes$(EXEEXT): $(test_fs_search_probes_OBJECTS) $(test_fs_search_probes_DEPENDENCIES)
+ @rm -f test_fs_search_probes$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_fs_search_probes_OBJECTS) $(test_fs_search_probes_LDADD) $(LIBS)
test_fs_start_stop$(EXEEXT): $(test_fs_start_stop_OBJECTS) $(test_fs_start_stop_DEPENDENCIES)
@rm -f test_fs_start_stop$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(test_fs_start_stop_OBJECTS) $(test_fs_start_stop_LDADD) $(LIBS)
@@ -1400,6 +1420,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_publish_persistence.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_search.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_search_persistence.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_search_probes.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_start_stop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_test_lib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_unindex.Po@am__quote@
diff --git a/src/fs/fs.conf.in b/src/fs/fs.conf.in
index 48c8b52..a908b1f 100644
--- a/src/fs/fs.conf.in
+++ b/src/fs/fs.conf.in
@@ -1,10 +1,10 @@
[fs]
AUTOSTART = YES
-INDEXDB = $SERVICEHOME/idxinfo.lst
-TRUST = $SERVICEHOME/data/credit/
-IDENTITY_DIR = $SERVICEHOME/identities/
-STATE_DIR = $SERVICEHOME/persistence/
-UPDATE_DIR = $SERVICEHOME/updates/
+INDEXDB = $SERVICEHOME/fs/idxinfo.lst
+TRUST = $SERVICEHOME/fs/credit/
+IDENTITY_DIR = $SERVICEHOME/fs/identities/
+STATE_DIR = $SERVICEHOME/fs/persistence/
+UPDATE_DIR = $SERVICEHOME/fs/updates/
@UNIXONLY@ PORT = 2094
HOSTNAME = localhost
HOME = $SERVICEHOME
@@ -20,7 +20,6 @@ CONTENT_PUSHING = YES
UNIXPATH = /tmp/gnunet-service-fs.sock
UNIX_MATCH_UID = NO
UNIX_MATCH_GID = YES
-# DISABLE_SOCKET_FORWARDING = NO
# DEBUG = YES
MAX_PENDING_REQUESTS = 65536
# Maximum frequency we're allowed to poll the datastore
@@ -29,4 +28,6 @@ MAX_PENDING_REQUESTS = 65536
MIN_MIGRATION_DELAY = 100 ms
EXPECTED_NEIGHBOUR_COUNT = 128
+# Enable monkey?
+PREFIX = @MONKEYPREFIX@
diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c
index 1df9b2e..651c174 100644
--- a/src/fs/fs_api.c
+++ b/src/fs/fs_api.c
@@ -30,6 +30,15 @@
#include "fs_api.h"
#include "fs_tree.h"
+/**
+ * How many block requests can we have outstanding in parallel at a time by default?
+ */
+#define DEFAULT_MAX_PARALLEL_REQUESTS (1024 * 10)
+
+/**
+ * How many downloads can we have outstanding in parallel at a time by default?
+ */
+#define DEFAULT_MAX_PARALLEL_DOWNLOADS 16
/**
* Start the given job (send signal, remove from pending queue, update
@@ -99,6 +108,8 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
struct GNUNET_TIME_Absolute end_time;
h->queue_job = GNUNET_SCHEDULER_NO_TASK;
+ restart_at = GNUNET_TIME_UNIT_FOREVER_REL;
+ /* first, see if we can start all the jobs */
next = h->pending_head;
while (NULL != (qe = next))
{
@@ -109,7 +120,7 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
continue;
}
if ((qe->blocks + h->active_blocks <= h->max_parallel_requests) &&
- (h->active_downloads + 1 <= h->max_parallel_downloads))
+ (h->active_downloads < h->max_parallel_downloads))
{
start_job (qe);
continue;
@@ -117,7 +128,7 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
}
if (h->pending_head == NULL)
return; /* no need to stop anything */
- restart_at = GNUNET_TIME_UNIT_FOREVER_REL;
+ /* then, check if we should stop some jobs */
next = h->running_head;
while (NULL != (qe = next))
{
@@ -125,6 +136,22 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
run_time =
GNUNET_TIME_relative_multiply (h->avg_block_latency,
qe->blocks * qe->start_times);
+ switch (qe->priority)
+ {
+ case GNUNET_FS_QUEUE_PRIORITY_PROBE:
+ /* run probes for at most 1s * number-of-restarts; note that
+ as the total runtime of a probe is limited to 2m, we don't
+ need to additionally limit the total time of a probe to
+ strictly limit its lifetime. */
+ run_time = GNUNET_TIME_relative_min (run_time,
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
+ 1 + qe->start_times));
+ break;
+ case GNUNET_FS_QUEUE_PRIORITY_NORMAL:
+ break;
+ default:
+ GNUNET_break (0);
+ }
end_time = GNUNET_TIME_absolute_add (qe->start_time, run_time);
rst = GNUNET_TIME_absolute_get_remaining (end_time);
restart_at = GNUNET_TIME_relative_min (rst, restart_at);
@@ -132,6 +159,18 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
continue;
stop_job (qe);
}
+ /* finally, start some more tasks if we now have empty slots */
+ next = h->pending_head;
+ while (NULL != (qe = next))
+ {
+ next = qe->next;
+ if ((qe->blocks + h->active_blocks <= h->max_parallel_requests) &&
+ (h->active_downloads < h->max_parallel_downloads))
+ {
+ start_job (qe);
+ continue;
+ }
+ }
h->queue_job =
GNUNET_SCHEDULER_add_delayed (restart_at, &process_job_queue, h);
}
@@ -145,11 +184,13 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
* @param stop function to call to pause the job, or on dequeue (if the job was running)
* @param cls closure for start and stop
* @param blocks number of blocks this jobs uses
+ * @param priority how important is this download
* @return queue handle
*/
struct GNUNET_FS_QueueEntry *
GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, GNUNET_FS_QueueStart start,
- GNUNET_FS_QueueStop stop, void *cls, unsigned int blocks)
+ GNUNET_FS_QueueStop stop, void *cls, unsigned int blocks,
+ enum GNUNET_FS_QueuePriority priority)
{
struct GNUNET_FS_QueueEntry *qe;
@@ -160,6 +201,7 @@ GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, GNUNET_FS_QueueStart start,
qe->cls = cls;
qe->queue_time = GNUNET_TIME_absolute_get ();
qe->blocks = blocks;
+ qe->priority = priority;
GNUNET_CONTAINER_DLL_insert_after (h->pending_head, h->pending_tail,
h->pending_tail, qe);
if (h->queue_job != GNUNET_SCHEDULER_NO_TASK)
@@ -249,7 +291,11 @@ struct FileInfo
* @param cls closure (points to the file information)
* @param offset offset to read from; it is possible
* that the caller might need to go backwards
- * a bit at times
+ * a bit at times; set to UINT64_MAX to tell
+ * the reader that we won't be reading for a while
+ * (used to close the file descriptor but NOT fully
+ * clean up the reader's state); in this case,
+ * a value of '0' for max should be ignored
* @param max maximum number of bytes that should be
* copied to buf; readers are not allowed
* to provide less data unless there is an error;
@@ -266,20 +312,29 @@ GNUNET_FS_data_reader_file_ (void *cls, uint64_t offset, size_t max, void *buf,
struct FileInfo *fi = cls;
ssize_t ret;
- if (max == 0)
+ if (UINT64_MAX == offset)
{
- if (fi->fd != NULL)
+ if (NULL != fi->fd)
+ {
+ GNUNET_DISK_file_close (fi->fd);
+ fi->fd = NULL;
+ }
+ return 0;
+ }
+ if (0 == max)
+ {
+ if (NULL != fi->fd)
GNUNET_DISK_file_close (fi->fd);
GNUNET_free (fi->filename);
GNUNET_free (fi);
return 0;
}
- if (fi->fd == NULL)
+ if (NULL == fi->fd)
{
fi->fd =
GNUNET_DISK_file_open (fi->filename, GNUNET_DISK_OPEN_READ,
GNUNET_DISK_PERM_NONE);
- if (fi->fd == NULL)
+ if (NULL == fi->fd)
{
GNUNET_asprintf (emsg, _("Could not open file `%s': %s"), fi->filename,
STRERROR (errno));
@@ -288,7 +343,7 @@ GNUNET_FS_data_reader_file_ (void *cls, uint64_t offset, size_t max, void *buf,
}
GNUNET_DISK_file_seek (fi->fd, offset, GNUNET_DISK_SEEK_SET);
ret = GNUNET_DISK_file_read (fi->fd, buf, max);
- if (ret == -1)
+ if (-1 == ret)
{
GNUNET_asprintf (emsg, _("Could not read file `%s': %s"), fi->filename,
STRERROR (errno));
@@ -332,7 +387,11 @@ GNUNET_FS_make_file_reader_context_ (const char *filename)
* @param cls closure (points to the buffer)
* @param offset offset to read from; it is possible
* that the caller might need to go backwards
- * a bit at times
+ * a bit at times; set to UINT64_MAX to tell
+ * the reader that we won't be reading for a while
+ * (used to close the file descriptor but NOT fully
+ * clean up the reader's state); in this case,
+ * a value of '0' for max should be ignored
* @param max maximum number of bytes that should be
* copied to buf; readers are not allowed
* to provide less data unless there is an error;
@@ -348,6 +407,8 @@ GNUNET_FS_data_reader_copy_ (void *cls, uint64_t offset, size_t max, void *buf,
{
char *data = cls;
+ if (UINT64_MAX == offset)
+ return 0;
if (max == 0)
{
GNUNET_free_non_null (data);
@@ -1482,6 +1543,7 @@ void
GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc)
{
struct GNUNET_BIO_WriteHandle *wh;
+ char *uris;
if (NULL == uc->serialization)
uc->serialization =
@@ -1496,10 +1558,18 @@ GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc)
GNUNET_break (0);
goto cleanup;
}
+ if (NULL != uc->ksk_uri)
+ uris = GNUNET_FS_uri_to_string (uc->ksk_uri);
+ else
+ uris = NULL;
if ((GNUNET_OK != GNUNET_BIO_write_string (wh, uc->filename)) ||
(GNUNET_OK != GNUNET_BIO_write_int64 (wh, uc->file_size)) ||
(GNUNET_OK != write_start_time (wh, uc->start_time)) ||
(GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) uc->state)) ||
+ (GNUNET_OK !=
+ GNUNET_BIO_write (wh, &uc->chk, sizeof (struct ContentHashKey))) ||
+ (GNUNET_OK != GNUNET_BIO_write_string (wh, uris)) ||
+ (GNUNET_OK != GNUNET_BIO_write_int32 (wh, (uint32_t) uc->ksk_offset)) ||
((uc->state == UNINDEX_STATE_FS_NOTIFY) &&
(GNUNET_OK !=
GNUNET_BIO_write (wh, &uc->file_id, sizeof (GNUNET_HashCode)))) ||
@@ -1637,9 +1707,8 @@ get_download_sync_filename (struct GNUNET_FS_DownloadContext *dc,
if (dc->parent == NULL)
return get_serialization_file_name (dc->h,
- (dc->search !=
- NULL) ?
- GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD :
+ (dc->search != NULL) ?
+ GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD :
GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD,
uni);
if (dc->parent->serialization == NULL)
@@ -1669,6 +1738,8 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc)
char *fn;
char *dir;
+ if (0 != (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE))
+ return; /* we don't sync probes */
if (NULL == dc->serialization)
{
dir = get_download_sync_filename (dc, "", "");
@@ -1920,6 +1991,7 @@ deserialize_unindex_file (void *cls, const char *filename)
struct GNUNET_FS_UnindexContext *uc;
struct GNUNET_FS_ProgressInfo pi;
char *emsg;
+ char *uris;
uint32_t state;
uc = GNUNET_malloc (sizeof (struct GNUNET_FS_UnindexContext));
@@ -1931,15 +2003,37 @@ deserialize_unindex_file (void *cls, const char *filename)
GNUNET_break (0);
goto cleanup;
}
+ uris = NULL;
if ((GNUNET_OK !=
GNUNET_BIO_read_string (rh, "unindex-fn", &uc->filename, 10 * 1024)) ||
(GNUNET_OK != GNUNET_BIO_read_int64 (rh, &uc->file_size)) ||
(GNUNET_OK != read_start_time (rh, &uc->start_time)) ||
- (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &state)))
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &state)) ||
+ (GNUNET_OK != GNUNET_BIO_read (rh, "uri", &uc->chk, sizeof (struct ContentHashKey))) ||
+ (GNUNET_OK != GNUNET_BIO_read_string (rh, "unindex-kskuri", &uris, 10 * 1024)) ||
+ (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &uc->ksk_offset)) )
{
+ GNUNET_free_non_null (uris);
GNUNET_break (0);
goto cleanup;
}
+ if (NULL != uris)
+ {
+ uc->ksk_uri = GNUNET_FS_uri_parse (uris, &emsg);
+ GNUNET_free (uris);
+ if (NULL == uc->ksk_uri)
+ {
+ GNUNET_break (0);
+ goto cleanup;
+ }
+ }
+ if ( (uc->ksk_offset > 0) &&
+ ( (NULL == uc->ksk_uri) ||
+ (uc->ksk_offset > uc->ksk_uri->data.ksk.keywordCount) ) )
+ {
+ GNUNET_break (0);
+ goto cleanup;
+ }
uc->state = (enum UnindexState) state;
switch (state)
{
@@ -1955,6 +2049,8 @@ deserialize_unindex_file (void *cls, const char *filename)
}
break;
case UNINDEX_STATE_DS_REMOVE:
+ case UNINDEX_STATE_EXTRACT_KEYWORDS:
+ case UNINDEX_STATE_DS_REMOVE_KBLOCKS:
break;
case UNINDEX_STATE_COMPLETE:
break;
@@ -1991,6 +2087,12 @@ deserialize_unindex_file (void *cls, const char *filename)
case UNINDEX_STATE_DS_REMOVE:
GNUNET_FS_unindex_do_remove_ (uc);
break;
+ case UNINDEX_STATE_EXTRACT_KEYWORDS:
+ GNUNET_FS_unindex_do_extract_keywords_ (uc);
+ break;
+ case UNINDEX_STATE_DS_REMOVE_KBLOCKS:
+ GNUNET_FS_unindex_do_remove_kblocks_ (uc);
+ break;
case UNINDEX_STATE_COMPLETE:
case UNINDEX_STATE_ERROR:
/* no need to resume any operation, we were done */
@@ -2762,8 +2864,8 @@ GNUNET_FS_start (const struct GNUNET_CONFIGURATION_Handle *cfg,
ret->upcb = upcb;
ret->upcb_cls = upcb_cls;
ret->flags = flags;
- ret->max_parallel_downloads = 1;
- ret->max_parallel_requests = 1;
+ ret->max_parallel_downloads = DEFAULT_MAX_PARALLEL_DOWNLOADS;
+ ret->max_parallel_requests = DEFAULT_MAX_PARALLEL_REQUESTS;
ret->avg_block_latency = GNUNET_TIME_UNIT_MINUTES; /* conservative starting point */
va_start (ap, flags);
while (GNUNET_FS_OPTIONS_END != (opt = va_arg (ap, enum GNUNET_FS_OPTIONS)))
diff --git a/src/fs/fs_api.h b/src/fs/fs_api.h
index de66ac6..e75b75f 100644
--- a/src/fs/fs_api.h
+++ b/src/fs/fs_api.h
@@ -417,6 +417,24 @@ typedef void (*GNUNET_FS_QueueStart) (void *cls,
typedef void (*GNUNET_FS_QueueStop) (void *cls);
+
+/**
+ * Priorities for the queue.
+ */
+enum GNUNET_FS_QueuePriority
+ {
+ /**
+ * This is a probe (low priority).
+ */
+ GNUNET_FS_QUEUE_PRIORITY_PROBE,
+
+ /**
+ * Default priority.
+ */
+ GNUNET_FS_QUEUE_PRIORITY_NORMAL
+ };
+
+
/**
* Entry in the job queue.
*/
@@ -479,6 +497,11 @@ struct GNUNET_FS_QueueEntry
unsigned int blocks;
/**
+ * How important is this download?
+ */
+ enum GNUNET_FS_QueuePriority priority;
+
+ /**
* How often have we (re)started this download?
*/
unsigned int start_times;
@@ -599,11 +622,13 @@ struct GNUNET_FS_SearchResult
* @param stop function to call to pause the job, or on dequeue (if the job was running)
* @param cls closure for start and stop
* @param blocks number of blocks this download has
+ * @param priority how important is this download
* @return queue handle
*/
struct GNUNET_FS_QueueEntry *
GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, GNUNET_FS_QueueStart start,
- GNUNET_FS_QueueStop stop, void *cls, unsigned int blocks);
+ GNUNET_FS_QueueStop stop, void *cls, unsigned int blocks,
+ enum GNUNET_FS_QueuePriority priority);
/**
@@ -709,6 +734,24 @@ GNUNET_FS_unindex_process_hash_ (void *cls, const GNUNET_HashCode * file_id);
/**
+ * Extract the keywords for KBlock removal
+ *
+ * @param uc context for the unindex operation.
+ */
+void
+GNUNET_FS_unindex_do_extract_keywords_ (struct GNUNET_FS_UnindexContext *uc);
+
+
+/**
+ * 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);
+
+
+/**
* Fill in all of the generic fields for a publish event and call the
* callback.
*
@@ -1219,32 +1262,42 @@ struct GNUNET_FS_PublishContext
*/
enum UnindexState
{
- /**
- * We're currently hashing the file.
- */
+ /**
+ * We're currently hashing the file.
+ */
UNINDEX_STATE_HASHING = 0,
- /**
- * We're telling the datastore to delete
- * the respective entries.
- */
+ /**
+ * We're telling the datastore to delete
+ * the respective DBlocks and IBlocks.
+ */
UNINDEX_STATE_DS_REMOVE = 1,
+
+ /**
+ * Find out which keywords apply.
+ */
+ UNINDEX_STATE_EXTRACT_KEYWORDS = 2,
- /**
- * We're notifying the FS service about
- * the unindexing.
- */
- UNINDEX_STATE_FS_NOTIFY = 2,
-
- /**
- * We're done.
- */
- UNINDEX_STATE_COMPLETE = 3,
+ /**
+ * We're telling the datastore to remove KBlocks.
+ */
+ UNINDEX_STATE_DS_REMOVE_KBLOCKS = 3,
- /**
- * We've encountered a fatal error.
- */
- UNINDEX_STATE_ERROR = 4
+ /**
+ * We're notifying the FS service about
+ * the unindexing.
+ */
+ UNINDEX_STATE_FS_NOTIFY = 4,
+
+ /**
+ * We're done.
+ */
+ UNINDEX_STATE_COMPLETE = 5,
+
+ /**
+ * We've encountered a fatal error.
+ */
+ UNINDEX_STATE_ERROR = 6
};
@@ -1255,6 +1308,12 @@ struct GNUNET_FS_UnindexContext
{
/**
+ * The content hash key of the last block we processed, will in the
+ * end be set to the CHK from the URI. Used to remove the KBlocks.
+ */
+ struct ContentHashKey chk;
+
+ /**
* Global FS context.
*/
struct GNUNET_FS_Handle *h;
@@ -1265,6 +1324,21 @@ struct GNUNET_FS_UnindexContext
struct TopLevelActivity *top;
/**
+ * Directory scanner to find keywords (KBlock removal).
+ */
+ struct GNUNET_FS_DirScanner *dscan;
+
+ /**
+ * Keywords found (telling us which KBlocks to remove).
+ */
+ struct GNUNET_FS_Uri *ksk_uri;
+
+ /**
+ * Current offset in KSK removal.
+ */
+ uint32_t ksk_offset;
+
+ /**
* Name of the file that we are unindexing.
*/
char *filename;
@@ -1302,6 +1376,27 @@ struct GNUNET_FS_UnindexContext
struct GNUNET_DISK_FileHandle *fh;
/**
+ * Handle to datastore 'get_key' operation issued for
+ * obtaining KBlocks.
+ */
+ struct GNUNET_DATASTORE_QueueEntry *dqe;
+
+ /**
+ * Current key for decrypting KBLocks from 'get_key' operation.
+ */
+ GNUNET_HashCode key;
+
+ /**
+ * Current query of 'get_key' operation.
+ */
+ GNUNET_HashCode query;
+
+ /**
+ * First content UID, 0 for none.
+ */
+ uint64_t first_uid;
+
+ /**
* Error message, NULL on success.
*/
char *emsg;
@@ -1317,6 +1412,11 @@ struct GNUNET_FS_UnindexContext
uint64_t file_size;
/**
+ * Random offset given to 'GNUNET_DATASTORE_get_key'.
+ */
+ uint64_t roff;
+
+ /**
* When did we start?
*/
struct GNUNET_TIME_Absolute start_time;
@@ -1591,6 +1691,11 @@ struct DownloadRequest
unsigned int depth;
/**
+ * Offset of the CHK for this block in the parent block
+ */
+ unsigned int chk_idx;
+
+ /**
* State in the FSM.
*/
enum BlockRequestState state;
@@ -1821,6 +1926,11 @@ struct GNUNET_FS_DownloadContext
*/
int in_receive;
+ /**
+ * Are we ready to issue requests (reconstructions are finished)?
+ */
+ int issue_requests;
+
};
diff --git a/src/fs/fs_dirmetascan.c b/src/fs/fs_dirmetascan.c
index 4e5354e..6dac690 100644
--- a/src/fs/fs_dirmetascan.c
+++ b/src/fs/fs_dirmetascan.c
@@ -248,7 +248,7 @@ finish_scan (void *cls,
* @param client always NULL
* @param msg message from the helper process
*/
-static void
+static int
process_helper_msgs (void *cls,
void *client,
const struct GNUNET_MessageHeader *msg)
@@ -257,6 +257,11 @@ process_helper_msgs (void *cls,
const char *filename;
size_t left;
+#if 0
+ fprintf (stderr, "DMS parses %u-byte message of type %u\n",
+ (unsigned int) ntohs (msg->size),
+ (unsigned int) ntohs (msg->type));
+#endif
left = ntohs (msg->size) - sizeof (struct GNUNET_MessageHeader);
filename = (const char*) &msg[1];
switch (ntohs (msg->type))
@@ -276,7 +281,7 @@ process_helper_msgs (void *cls,
else
(void) expand_tree (ds->pos,
filename, GNUNET_NO);
- return;
+ return GNUNET_OK;
case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY:
if (filename[left-1] != '\0')
{
@@ -291,7 +296,7 @@ process_helper_msgs (void *cls,
break;
}
ds->pos = ds->pos->parent;
- return;
+ return GNUNET_OK;
}
ds->progress_callback (ds->progress_callback_cls,
filename, GNUNET_YES,
@@ -300,16 +305,16 @@ process_helper_msgs (void *cls,
filename, GNUNET_YES);
if (NULL == ds->toplevel)
ds->toplevel = ds->pos;
- return;
+ return GNUNET_OK;
case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR:
break;
case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE:
- if (filename[left-1] != '\0')
+ if ('\0' != filename[left-1])
break;
ds->progress_callback (ds->progress_callback_cls,
filename, GNUNET_SYSERR,
GNUNET_FS_DIRSCANNER_FILE_IGNORED);
- return;
+ return GNUNET_OK;
case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_COUNTING_DONE:
if (0 != left)
{
@@ -325,9 +330,9 @@ process_helper_msgs (void *cls,
NULL, GNUNET_SYSERR,
GNUNET_FS_DIRSCANNER_ALL_COUNTED);
ds->pos = ds->toplevel;
- if (ds->pos->is_directory == GNUNET_YES)
+ if (GNUNET_YES == ds->pos->is_directory)
ds->pos = advance (ds->pos);
- return;
+ return GNUNET_OK;
case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA:
{
size_t nlen;
@@ -377,7 +382,7 @@ process_helper_msgs (void *cls,
}
ds->pos->ksk_uri = GNUNET_FS_uri_ksk_create_from_meta_data (ds->pos->meta);
ds->pos = advance (ds->pos);
- return;
+ return GNUNET_OK;
}
case GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_FINISHED:
if (NULL != ds->pos)
@@ -397,7 +402,7 @@ process_helper_msgs (void *cls,
}
ds->stop_task = GNUNET_SCHEDULER_add_now (&finish_scan,
ds);
- return;
+ return GNUNET_OK;
default:
GNUNET_break (0);
break;
@@ -405,6 +410,7 @@ process_helper_msgs (void *cls,
ds->progress_callback (ds->progress_callback_cls,
NULL, GNUNET_SYSERR,
GNUNET_FS_DIRSCANNER_INTERNAL_ERROR);
+ return GNUNET_OK;
}
diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c
index b23d14b..7c4dccb 100644
--- a/src/fs/fs_download.c
+++ b/src/fs/fs_download.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001-2011 Christian Grothoff (and other contributing authors)
+ (C) 2001-2012 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
@@ -21,9 +21,6 @@
* @file fs/fs_download.c
* @brief download methods
* @author Christian Grothoff
- *
- * TODO:
- * - different priority for scheduling probe downloads?
*/
#include "platform.h"
#include "gnunet_constants.h"
@@ -41,7 +38,7 @@ is_recursive_download (struct GNUNET_FS_DownloadContext *dc)
{
return (0 != (dc->options & GNUNET_FS_DOWNLOAD_OPTION_RECURSIVE)) &&
((GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (dc->meta)) ||
- ((dc->meta == NULL) &&
+ ((NULL == dc->meta) &&
((NULL == dc->filename) ||
((strlen (dc->filename) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
(NULL !=
@@ -75,7 +72,7 @@ compute_disk_offset (uint64_t fsize, uint64_t off, unsigned int depth)
uint64_t loff; /* where do IBlocks for depth "i" start? */
unsigned int ioff; /* which IBlock corresponds to "off" at depth "i"? */
- if (depth == 0)
+ if (0 == depth)
return off;
/* first IBlocks start at the end of file, rounded up
* to full DBLOCK_SIZE */
@@ -111,9 +108,9 @@ GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi,
pi->value.download.dc = dc;
pi->value.download.cctx = dc->client_info;
pi->value.download.pctx =
- (dc->parent == NULL) ? NULL : dc->parent->client_info;
+ (NULL == dc->parent) ? NULL : dc->parent->client_info;
pi->value.download.sctx =
- (dc->search == NULL) ? NULL : dc->search->client_info;
+ (NULL == dc->search) ? NULL : dc->search->client_info;
pi->value.download.uri = dc->uri;
pi->value.download.filename = dc->filename;
pi->value.download.size = dc->length;
@@ -124,7 +121,7 @@ GNUNET_FS_download_make_status_ (struct GNUNET_FS_ProgressInfo *pi,
pi->value.download.anonymity = dc->anonymity;
pi->value.download.eta =
GNUNET_TIME_calculate_eta (dc->start_time, dc->completed, dc->length);
- pi->value.download.is_active = (dc->client == NULL) ? GNUNET_NO : GNUNET_YES;
+ pi->value.download.is_active = (NULL == dc->client) ? GNUNET_NO : GNUNET_YES;
if (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE))
dc->client_info = dc->h->upcb (dc->h->upcb_cls, pi);
else
@@ -183,6 +180,9 @@ struct ProcessResultClosure
*/
int do_store;
+ /**
+ * When did we last transmit the request?
+ */
struct GNUNET_TIME_Absolute last_transmission;
};
@@ -240,7 +240,8 @@ encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc,
return GNUNET_SYSERR;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Matching block for `%s' at offset %llu already present, no need for download!\n",
+ "Matching %u byte block for `%s' at offset %llu already present, no need for download!\n",
+ (unsigned int) len,
dc->filename, (unsigned long long) dr->offset);
/* already got it! */
prc.dc = dc;
@@ -310,21 +311,21 @@ full_recursive_download (struct GNUNET_FS_DownloadContext *dc)
("Recursive downloads of directories larger than 4 GB are not supported on 32-bit systems\n"));
return;
}
- if (dc->filename != NULL)
+ if (NULL != dc->filename)
{
h = GNUNET_DISK_file_open (dc->filename, GNUNET_DISK_OPEN_READ,
GNUNET_DISK_PERM_NONE);
}
else
{
- GNUNET_assert (dc->temp_filename != NULL);
+ GNUNET_assert (NULL != dc->temp_filename);
h = GNUNET_DISK_file_open (dc->temp_filename, GNUNET_DISK_OPEN_READ,
GNUNET_DISK_PERM_NONE);
}
- if (h == NULL)
+ if (NULL == h)
return; /* oops */
data = GNUNET_DISK_file_map (h, &m, GNUNET_DISK_MAP_TYPE_READ, size);
- if (data == NULL)
+ if (NULL == data)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Directory too large for system address space\n"));
@@ -336,7 +337,7 @@ full_recursive_download (struct GNUNET_FS_DownloadContext *dc)
GNUNET_DISK_file_unmap (m);
}
GNUNET_DISK_file_close (h);
- if (dc->filename == NULL)
+ if (NULL == dc->filename)
{
if (0 != UNLINK (dc->temp_filename))
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink",
@@ -364,25 +365,33 @@ check_completed (struct GNUNET_FS_DownloadContext *dc)
struct GNUNET_FS_DownloadContext *pos;
/* first, check if we need to download children */
- if ((dc->child_head == NULL) && (is_recursive_download (dc)))
+ if ((NULL == dc->child_head) && (is_recursive_download (dc)))
full_recursive_download (dc);
/* then, check if children are done already */
- pos = dc->child_head;
- while (pos != NULL)
+ for (pos = dc->child_head; NULL != pos; pos = pos->next)
{
if ((pos->emsg == NULL) && (pos->completed < pos->length))
return; /* not done yet */
if ((pos->child_head != NULL) && (pos->has_finished != GNUNET_YES))
return; /* not transitively done yet */
- pos = pos->next;
}
/* All of our children are done, so mark this download done */
dc->has_finished = GNUNET_YES;
- if (dc->job_queue != NULL)
+ if (NULL != dc->job_queue)
{
GNUNET_FS_dequeue_ (dc->job_queue);
dc->job_queue = NULL;
}
+ if (GNUNET_SCHEDULER_NO_TASK != dc->task)
+ {
+ GNUNET_SCHEDULER_cancel (dc->task);
+ dc->task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (NULL != dc->rfh)
+ {
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (dc->rfh));
+ dc->rfh = NULL;
+ }
GNUNET_FS_download_sync_ (dc);
/* signal completion */
@@ -390,7 +399,7 @@ check_completed (struct GNUNET_FS_DownloadContext *dc)
GNUNET_FS_download_make_status_ (&pi, dc);
/* let parent know */
- if (dc->parent != NULL)
+ if (NULL != dc->parent)
check_completed (dc->parent);
}
@@ -473,7 +482,7 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc,
break;
}
/* write block to disk */
- fn = dc->filename != NULL ? dc->filename : dc->temp_filename;
+ fn = (NULL != dc->filename) ? dc->filename : dc->temp_filename;
fh = GNUNET_DISK_file_open (fn,
GNUNET_DISK_OPEN_READWRITE |
GNUNET_DISK_OPEN_CREATE |
@@ -482,7 +491,7 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc,
GNUNET_DISK_PERM_USER_WRITE |
GNUNET_DISK_PERM_GROUP_READ |
GNUNET_DISK_PERM_OTHER_READ);
- if (fh == NULL)
+ if (NULL == fh)
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", fn);
GNUNET_asprintf (&dc->emsg, _("Failed to open file `%s' for writing"),
@@ -517,6 +526,7 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc,
pi.value.download.specifics.progress.data_len = dlen;
pi.value.download.specifics.progress.depth = 0;
pi.value.download.specifics.progress.trust_offered = 0;
+ pi.value.download.specifics.progress.block_download_duration = GNUNET_TIME_UNIT_ZERO;
GNUNET_FS_download_make_status_ (&pi, dc);
if ((NULL != dc->filename) &&
(0 !=
@@ -559,7 +569,7 @@ match_full_data (void *cls, const char *plugin_name,
{
struct GNUNET_FS_DownloadContext *dc = cls;
- if (type != EXTRACTOR_METATYPE_GNUNET_FULL_DATA)
+ if (EXTRACTOR_METATYPE_GNUNET_FULL_DATA != type)
return 0;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u bytes of FD!\n",
(unsigned int) data_len);
@@ -588,7 +598,7 @@ propagate_up (struct DownloadRequest *dr)
{
dr->state = BRS_DOWNLOAD_UP;
dr = dr->parent;
- if (dr == NULL)
+ if (NULL == dr)
break;
for (i = 0; i < dr->num_children; i++)
if (dr->children[i]->state != BRS_DOWNLOAD_UP)
@@ -618,14 +628,13 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc,
uint64_t total;
size_t len;
unsigned int i;
- unsigned int chk_off;
struct DownloadRequest *drc;
uint64_t child_block_size;
const struct ContentHashKey *chks;
int up_done;
- GNUNET_assert (dc->rfh != NULL);
- GNUNET_assert (dr->state == BRS_CHK_SET);
+ GNUNET_assert (NULL != dc->rfh);
+ GNUNET_assert (BRS_CHK_SET == dr->state);
total = GNUNET_FS_uri_chk_get_file_size (dc->uri);
GNUNET_assert (dr->depth < dc->treedepth);
len = GNUNET_FS_tree_calculate_block_size (total, dr->offset, dr->depth);
@@ -652,7 +661,7 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc,
/* hash matches but encrypted block does not, really bad */
dr->state = BRS_ERROR;
/* propagate up */
- while (dr->parent != NULL)
+ while (NULL != dr->parent)
{
dr = dr->parent;
dr->state = BRS_ERROR;
@@ -670,18 +679,17 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc,
drc = dr->children[i];
GNUNET_assert (drc->offset >= dr->offset);
child_block_size = GNUNET_FS_tree_compute_tree_size (drc->depth);
- GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size);
- chk_off = (drc->offset - dr->offset) / child_block_size;
- if (drc->state == BRS_INIT)
+ GNUNET_assert (0 == (drc->offset - dr->offset) % child_block_size);
+ if (BRS_INIT == drc->state)
{
drc->state = BRS_CHK_SET;
- drc->chk = chks[chk_off];
+ drc->chk = chks[drc->chk_idx];
try_top_down_reconstruction (dc, drc);
}
- if (drc->state != BRS_DOWNLOAD_UP)
+ if (BRS_DOWNLOAD_UP != drc->state)
up_done = GNUNET_NO; /* children not all done */
}
- if (up_done == GNUNET_YES)
+ if (GNUNET_YES == up_done)
propagate_up (dr); /* children all done (or no children...) */
}
@@ -736,7 +744,7 @@ schedule_block_download (struct GNUNET_FS_DownloadContext *dc,
return; /* already active */
GNUNET_CONTAINER_multihashmap_put (dc->active, &dr->chk.query, dr,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- if (dc->client == NULL)
+ if (NULL == dc->client)
return; /* download not active */
GNUNET_CONTAINER_DLL_insert (dc->pending_head, dc->pending_tail, dr);
dr->is_pending = GNUNET_YES;
@@ -783,26 +791,26 @@ trigger_recursive_download (void *cls, const char *filename,
if (NULL == uri)
return; /* entry for the directory itself */
cpos = dc->child_head;
- while (cpos != NULL)
+ while (NULL != cpos)
{
if ((GNUNET_FS_uri_test_equal (uri, cpos->uri)) ||
- ((filename != NULL) && (0 == strcmp (cpos->filename, filename))))
+ ((NULL != filename) && (0 == strcmp (cpos->filename, filename))))
break;
cpos = cpos->next;
}
- if (cpos != NULL)
+ if (NULL != cpos)
return; /* already exists */
fn = NULL;
if (NULL == filename)
{
fn = GNUNET_FS_meta_data_suggest_filename (meta);
- if (fn == NULL)
+ if (NULL == fn)
{
us = GNUNET_FS_uri_to_string (uri);
fn = GNUNET_strdup (&us[strlen (GNUNET_FS_URI_CHK_PREFIX)]);
GNUNET_free (us);
}
- else if (fn[0] == '.')
+ else if ('.' == fn[0])
{
ext = fn;
us = GNUNET_FS_uri_to_string (uri);
@@ -827,7 +835,7 @@ trigger_recursive_download (void *cls, const char *filename,
}
filename = fn;
}
- if (dc->filename == NULL)
+ if (NULL == dc->filename)
{
full_name = NULL;
}
@@ -839,7 +847,7 @@ trigger_recursive_download (void *cls, const char *filename,
strstr (dn + strlen (dn) - strlen (GNUNET_FS_DIRECTORY_EXT),
GNUNET_FS_DIRECTORY_EXT)));
sfn = GNUNET_strdup (filename);
- while ((strlen (sfn) > 0) && (filename[strlen (sfn) - 1] == '/'))
+ while ((strlen (sfn) > 0) && ('/' == filename[strlen (sfn) - 1]))
sfn[strlen (sfn) - 1] = '\0';
if ((strlen (dn) >= strlen (GNUNET_FS_DIRECTORY_EXT)) &&
(NULL !=
@@ -862,7 +870,7 @@ trigger_recursive_download (void *cls, const char *filename,
GNUNET_free (sfn);
GNUNET_free (dn);
}
- if ((full_name != NULL) &&
+ if ((NULL != full_name) &&
(GNUNET_OK != GNUNET_DISK_directory_create_for_file (full_name)))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -899,7 +907,7 @@ GNUNET_FS_free_download_request_ (struct DownloadRequest *dr)
{
unsigned int i;
- if (dr == NULL)
+ if (NULL == dr)
return;
for (i = 0; i < dr->num_children; i++)
GNUNET_FS_free_download_request_ (dr->children[i]);
@@ -937,7 +945,8 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
struct ContentHashKey *chkarr;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received block `%s' matching pending request at depth %u and offset %llu/%llu\n",
+ "Received %u byte block `%s' matching pending request at depth %u and offset %llu/%llu\n",
+ (unsigned int) prc->size,
GNUNET_h2s (key), dr->depth, (unsigned long long) dr->offset,
(unsigned long long) GNUNET_ntohll (dc->uri->data.
chk.file_length));
@@ -948,13 +957,13 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
{
GNUNET_asprintf (&dc->emsg,
_
- ("Internal error or bogus download URI (expected %u bytes at depth %u and offset %llu/%llu, got %u bytes)\n"),
+ ("Internal error or bogus download URI (expected %u bytes at depth %u and offset %llu/%llu, got %u bytes)"),
bs, dr->depth, (unsigned long long) dr->offset,
(unsigned long long) GNUNET_ntohll (dc->uri->data.
chk.file_length),
prc->size);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s", dc->emsg);
- while (dr->parent != NULL)
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", dc->emsg);
+ while (NULL != dr->parent)
{
dr->state = BRS_ERROR;
dr = dr->parent;
@@ -982,12 +991,12 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
dr->offset, dr->depth);
/* save to disk */
if ((GNUNET_YES == prc->do_store) &&
- ((dc->filename != NULL) || (is_recursive_download (dc))) &&
+ ((NULL != dc->filename) || (is_recursive_download (dc))) &&
((dr->depth == dc->treedepth) ||
(0 == (dc->options & GNUNET_FS_DOWNLOAD_NO_TEMPORARIES))))
{
- fh = GNUNET_DISK_file_open (dc->filename !=
- NULL ? dc->filename : dc->temp_filename,
+ fh = GNUNET_DISK_file_open (NULL != dc->filename
+ ? dc->filename : dc->temp_filename,
GNUNET_DISK_OPEN_READWRITE |
GNUNET_DISK_OPEN_CREATE,
GNUNET_DISK_PERM_USER_READ |
@@ -997,7 +1006,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
if (NULL == fh)
{
GNUNET_asprintf (&dc->emsg,
- _("Download failed: could not open file `%s': %s\n"),
+ _("Download failed: could not open file `%s': %s"),
dc->filename, STRERROR (errno));
goto signal_error;
}
@@ -1007,7 +1016,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
if ((off != GNUNET_DISK_file_seek (fh, off, GNUNET_DISK_SEEK_SET)))
{
GNUNET_asprintf (&dc->emsg,
- _("Failed to seek to offset %llu in file `%s': %s\n"),
+ _("Failed to seek to offset %llu in file `%s': %s"),
(unsigned long long) off, dc->filename,
STRERROR (errno));
goto signal_error;
@@ -1016,7 +1025,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
{
GNUNET_asprintf (&dc->emsg,
_
- ("Failed to write block of %u bytes at offset %llu in file `%s': %s\n"),
+ ("Failed to write block of %u bytes at offset %llu in file `%s': %s"),
(unsigned int) prc->size, (unsigned long long) off,
dc->filename, STRERROR (errno));
goto signal_error;
@@ -1025,7 +1034,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
fh = NULL;
}
- if (dr->depth == 0)
+ if (0 == dr->depth)
{
/* DBLOCK, update progress and try recursion if applicable */
app = prc->size;
@@ -1052,7 +1061,6 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
if (is_recursive_download (dc))
GNUNET_FS_directory_list_contents (prc->size, pt, off,
&trigger_recursive_download, dc);
-
}
GNUNET_assert (dc->completed <= dc->length);
dr->state = BRS_DOWNLOAD_DOWN;
@@ -1063,13 +1071,13 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
pi.value.download.specifics.progress.depth = dr->depth;
pi.value.download.specifics.progress.trust_offered = 0;
if (prc->last_transmission.abs_value != GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
- pi.value.download.specifics.progress.block_download_duration =
- GNUNET_TIME_absolute_get_duration (prc->last_transmission);
+ pi.value.download.specifics.progress.block_download_duration
+ = GNUNET_TIME_absolute_get_duration (prc->last_transmission);
else
- pi.value.download.specifics.progress.block_download_duration.rel_value =
- GNUNET_TIME_UNIT_FOREVER_REL.rel_value;
+ pi.value.download.specifics.progress.block_download_duration
+ = GNUNET_TIME_UNIT_ZERO; /* found locally */
GNUNET_FS_download_make_status_ (&pi, dc);
- if (dr->depth == 0)
+ if (0 == dr->depth)
propagate_up (dr);
if (dc->completed == dc->length)
@@ -1080,7 +1088,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
(unsigned long long) GNUNET_ntohll (dc->uri->data.
chk.file_length));
/* truncate file to size (since we store IBlocks at the end) */
- if (dc->filename != NULL)
+ if (NULL != dc->filename)
{
if (0 !=
truncate (dc->filename,
@@ -1088,10 +1096,10 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "truncate",
dc->filename);
}
- GNUNET_assert (dr->depth == 0);
+ GNUNET_assert (0 == dr->depth);
check_completed (dc);
}
- if (dr->depth == 0)
+ if (0 == dr->depth)
{
/* bottom of the tree, no child downloads possible, just sync */
GNUNET_FS_download_sync_ (dc);
@@ -1103,15 +1111,24 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
dr->depth, (unsigned long long) dr->offset);
GNUNET_assert (0 == (prc->size % sizeof (struct ContentHashKey)));
chkarr = (struct ContentHashKey *) pt;
- for (i = (prc->size / sizeof (struct ContentHashKey)) - 1; i >= 0; i--)
+ for (i = dr->num_children - 1; i >= 0; i--)
{
drc = dr->children[i];
switch (drc->state)
{
case BRS_INIT:
- drc->chk = chkarr[i];
+ if ((drc->chk_idx + 1) * sizeof (struct ContentHashKey) > prc->size)
+ {
+ /* 'chkarr' does not have enough space for this chk_idx;
+ internal error! */
+ GNUNET_break (0);
+ dc->emsg = GNUNET_strdup (_("internal error decoding tree"));
+ goto signal_error;
+ }
+ drc->chk = chkarr[drc->chk_idx];
drc->state = BRS_CHK_SET;
- schedule_block_download (dc, drc);
+ if (GNUNET_YES == dc->issue_requests)
+ schedule_block_download (dc, drc);
break;
case BRS_RECONSTRUCT_DOWN:
GNUNET_assert (0);
@@ -1143,7 +1160,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key,
return GNUNET_YES;
signal_error:
- if (fh != NULL)
+ if (NULL != fh)
GNUNET_DISK_file_close (fh);
pi.status = GNUNET_FS_STATUS_DOWNLOAD_ERROR;
pi.value.download.specifics.error.message = dc->emsg;
@@ -1154,7 +1171,7 @@ signal_error:
GNUNET_CLIENT_notify_transmit_ready_cancel (dc->th);
dc->th = NULL;
}
- GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (dc->client);
dc->in_receive = GNUNET_NO;
dc->client = NULL;
GNUNET_FS_free_download_request_ (dc->top_request);
@@ -1218,7 +1235,7 @@ receive_results (void *cls, const struct GNUNET_MessageHeader *msg)
if ((NULL == msg) || (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_FS_PUT) ||
(sizeof (struct ClientPutMessage) > ntohs (msg->size)))
{
- GNUNET_break (msg == NULL);
+ GNUNET_break (NULL == msg);
try_reconnect (dc);
return;
}
@@ -1227,7 +1244,7 @@ receive_results (void *cls, const struct GNUNET_MessageHeader *msg)
process_result (dc, ntohl (cm->type),
GNUNET_TIME_absolute_ntoh (cm->last_transmission), &cm[1],
msize - sizeof (struct ClientPutMessage));
- if (dc->client == NULL)
+ if (NULL == dc->client)
return; /* fatal error */
/* continue receiving */
GNUNET_CLIENT_receive (dc->client, &receive_results, dc,
@@ -1235,7 +1252,6 @@ receive_results (void *cls, const struct GNUNET_MessageHeader *msg)
}
-
/**
* We're ready to transmit a search request to the
* file-sharing service. Do it. If there is
@@ -1279,7 +1295,7 @@ transmit_download_request (void *cls, size_t size, void *buf)
sm->options = htonl (GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY);
else
sm->options = htonl (GNUNET_FS_SEARCH_OPTION_NONE);
- if (dr->depth == 0)
+ if (0 == dr->depth)
sm->type = htonl (GNUNET_BLOCK_TYPE_FS_DBLOCK);
else
sm->type = htonl (GNUNET_BLOCK_TYPE_FS_IBLOCK);
@@ -1291,7 +1307,7 @@ transmit_download_request (void *cls, size_t size, void *buf)
msize += sizeof (struct SearchMessage);
sm++;
}
- if (dc->pending_head != NULL)
+ if (NULL != dc->pending_head)
{
dc->th =
GNUNET_CLIENT_notify_transmit_ready (dc->client,
@@ -1299,7 +1315,7 @@ transmit_download_request (void *cls, size_t size, void *buf)
GNUNET_CONSTANTS_SERVICE_TIMEOUT,
GNUNET_NO,
&transmit_download_request, dc);
- GNUNET_assert (dc->th != NULL);
+ GNUNET_assert (NULL != dc->th);
}
if (GNUNET_NO == dc->in_receive)
{
@@ -1333,7 +1349,7 @@ do_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
return;
}
dc->client = client;
- if (dc->pending_head != NULL)
+ if (NULL != dc->pending_head)
{
dc->th =
GNUNET_CLIENT_notify_transmit_ready (client,
@@ -1341,7 +1357,7 @@ do_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_CONSTANTS_SERVICE_TIMEOUT,
GNUNET_NO,
&transmit_download_request, dc);
- GNUNET_assert (dc->th != NULL);
+ GNUNET_assert (NULL != dc->th);
}
}
@@ -1392,7 +1408,7 @@ try_reconnect (struct GNUNET_FS_DownloadContext *dc)
dc->pending_head = NULL;
dc->pending_tail = NULL;
GNUNET_CONTAINER_multihashmap_iterate (dc->active, &retry_entry, dc);
- GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (dc->client);
dc->in_receive = GNUNET_NO;
dc->client = NULL;
}
@@ -1417,8 +1433,8 @@ activate_fs_download (void *cls, struct GNUNET_CLIENT_Connection *client)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download activated\n");
GNUNET_assert (NULL != client);
- GNUNET_assert (dc->client == NULL);
- GNUNET_assert (dc->th == NULL);
+ GNUNET_assert (NULL == dc->client);
+ GNUNET_assert (NULL == dc->th);
dc->client = client;
pi.status = GNUNET_FS_STATUS_DOWNLOAD_ACTIVE;
GNUNET_FS_download_make_status_ (&pi, dc);
@@ -1427,7 +1443,7 @@ activate_fs_download (void *cls, struct GNUNET_CLIENT_Connection *client)
GNUNET_CONTAINER_multihashmap_iterate (dc->active, &retry_entry, dc);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Asking for transmission to FS service\n");
- if (dc->pending_head != NULL)
+ if (NULL != dc->pending_head)
{
dc->th =
GNUNET_CLIENT_notify_transmit_ready (dc->client,
@@ -1435,7 +1451,7 @@ activate_fs_download (void *cls, struct GNUNET_CLIENT_Connection *client)
GNUNET_CONSTANTS_SERVICE_TIMEOUT,
GNUNET_NO,
&transmit_download_request, dc);
- GNUNET_assert (dc->th != NULL);
+ GNUNET_assert (NULL != dc->th);
}
}
@@ -1459,7 +1475,7 @@ deactivate_fs_download (void *cls)
}
if (NULL != dc->client)
{
- GNUNET_CLIENT_disconnect (dc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (dc->client);
dc->in_receive = GNUNET_NO;
dc->client = NULL;
}
@@ -1474,6 +1490,7 @@ deactivate_fs_download (void *cls)
* (recursively) Create a download request structure.
*
* @param parent parent of the current entry
+ * @param chk_idx index of the chk for this block in the parent block
* @param depth depth of the current entry, 0 are the DBLOCKs,
* top level block is 'dc->treedepth - 1'
* @param dr_offset offset in the original file this block maps to
@@ -1489,7 +1506,9 @@ deactivate_fs_download (void *cls)
* the specified depth
*/
static struct DownloadRequest *
-create_download_request (struct DownloadRequest *parent, unsigned int depth,
+create_download_request (struct DownloadRequest *parent,
+ unsigned int chk_idx,
+ unsigned int depth,
uint64_t dr_offset, uint64_t file_start_offset,
uint64_t desired_length)
{
@@ -1502,40 +1521,45 @@ create_download_request (struct DownloadRequest *parent, unsigned int depth,
dr->parent = parent;
dr->depth = depth;
dr->offset = dr_offset;
- if (depth > 0)
- {
- child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1);
-
- /* calculate how many blocks at this level are not interesting
- * from the start (rounded down), either because of the requested
- * file offset or because this IBlock is further along */
- if (dr_offset < file_start_offset)
- head_skip = file_start_offset / child_block_size;
- else
- head_skip = dr_offset / child_block_size;
-
- /* calculate index of last block at this level that is interesting (rounded up) */
- dr->num_children = file_start_offset + desired_length / child_block_size;
- if (dr->num_children * child_block_size <
- file_start_offset + desired_length)
- dr->num_children++; /* round up */
-
- /* now we can get the total number of children for this block */
- dr->num_children -= head_skip;
- if (dr->num_children > CHK_PER_INODE)
- dr->num_children = CHK_PER_INODE; /* cap at max */
-
- /* why else would we have gotten here to begin with? (that'd be a bad logic error) */
- GNUNET_assert (dr->num_children > 0);
-
- dr->children =
- GNUNET_malloc (dr->num_children * sizeof (struct DownloadRequest *));
- for (i = 0; i < dr->num_children; i++)
- dr->children[i] =
- create_download_request (dr, depth - 1,
- dr_offset + i * child_block_size,
- file_start_offset, desired_length);
- }
+ dr->chk_idx = chk_idx;
+ if (0 == depth)
+ return dr;
+ child_block_size = GNUNET_FS_tree_compute_tree_size (depth - 1);
+
+ /* calculate how many blocks at this level are not interesting
+ * from the start (rounded down), either because of the requested
+ * file offset or because this IBlock is further along */
+ if (dr_offset < file_start_offset)
+ head_skip = file_start_offset / child_block_size;
+ else
+ head_skip = 0;
+
+ /* calculate index of last block at this level that is interesting (rounded up) */
+ dr->num_children = (file_start_offset + desired_length - dr_offset) / child_block_size;
+ if (dr->num_children * child_block_size <
+ file_start_offset + desired_length - dr_offset)
+ dr->num_children++; /* round up */
+ dr->num_children -= head_skip;
+ if (dr->num_children > CHK_PER_INODE)
+ dr->num_children = CHK_PER_INODE; /* cap at max */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Block at offset %llu and depth %u has %u children\n",
+ (unsigned long long) dr_offset,
+ depth,
+ dr->num_children);
+
+ /* now we can get the total number of *interesting* children for this block */
+
+ /* why else would we have gotten here to begin with? (that'd be a bad logic error) */
+ GNUNET_assert (dr->num_children > 0);
+
+ dr->children =
+ GNUNET_malloc (dr->num_children * sizeof (struct DownloadRequest *));
+ for (i = 0; i < dr->num_children; i++)
+ dr->children[i] =
+ create_download_request (dr, i + head_skip, depth - 1,
+ dr_offset + (i + head_skip) * child_block_size,
+ file_start_offset, desired_length);
return dr;
}
@@ -1552,23 +1576,21 @@ reconstruct_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_FS_DownloadContext *dc = cls;
- /* clean up state from tree encoder */
- if (dc->te != NULL)
- {
- GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL);
- dc->te = NULL;
- }
+ /* clean up state from tree encoder */
if (dc->task != GNUNET_SCHEDULER_NO_TASK)
{
GNUNET_SCHEDULER_cancel (dc->task);
dc->task = GNUNET_SCHEDULER_NO_TASK;
}
- if (dc->rfh != NULL)
+ if (NULL != dc->rfh)
{
GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (dc->rfh));
dc->rfh = NULL;
}
/* start "normal" download */
+ dc->issue_requests = GNUNET_YES;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Starting normal download\n");
schedule_block_download (dc, dc->top_request);
}
@@ -1589,7 +1611,6 @@ get_next_block (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
}
-
/**
* Function called asking for the current (encoded)
* block to be processed. After processing the
@@ -1622,11 +1643,34 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
dr = dc->top_request;
while (dr->depth > depth)
{
- blen = GNUNET_FS_tree_compute_tree_size (dr->depth);
+ GNUNET_assert (dr->num_children > 0);
+ blen = GNUNET_FS_tree_compute_tree_size (dr->depth - 1);
chld = (offset - dr->offset) / blen;
- GNUNET_assert (chld < dr->num_children);
- dr = dr->children[chld];
+ if (chld < dr->children[0]->chk_idx)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Block %u < %u irrelevant for our range\n",
+ chld,
+ dr->children[0]->chk_idx);
+ dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
+ return; /* irrelevant block */
+ }
+ if (chld > dr->children[dr->num_children-1]->chk_idx)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Block %u > %u irrelevant for our range\n",
+ chld,
+ dr->children[dr->num_children-1]->chk_idx);
+ dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
+ return; /* irrelevant block */
+ }
+ dr = dr->children[chld - dr->children[0]->chk_idx];
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Matched TE block with request at offset %llu and depth %u in state %d\n",
+ (unsigned long long) dr->offset,
+ dr->depth,
+ dr->state);
/* FIXME: this code needs more testing and might
need to handle more states... */
switch (dr->state)
@@ -1642,11 +1686,14 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
case BRS_CHK_SET:
if (0 == memcmp (chk, &dr->chk, sizeof (struct ContentHashKey)))
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Reconstruction succeeded, can use block at offset %llu, depth %u\n",
+ (unsigned long long) offset,
+ depth);
/* block matches, hence tree below matches;
* this request is done! */
dr->state = BRS_DOWNLOAD_UP;
- GNUNET_break (GNUNET_NO ==
- GNUNET_CONTAINER_multihashmap_remove (dc->active, &dr->chk.query, dr));
+ (void) GNUNET_CONTAINER_multihashmap_remove (dc->active, &dr->chk.query, dr);
if (GNUNET_YES == dr->is_pending)
{
GNUNET_break (0); /* how did we get here? */
@@ -1666,6 +1713,7 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
pi.value.download.specifics.progress.data_len = 0;
pi.value.download.specifics.progress.depth = 0;
pi.value.download.specifics.progress.trust_offered = 0;
+ pi.value.download.specifics.progress.block_download_duration = GNUNET_TIME_UNIT_ZERO;
GNUNET_FS_download_make_status_ (&pi, dc);
/* FIXME: duplicated code from 'process_result_with_request - refactor */
if (dc->completed == dc->length)
@@ -1676,7 +1724,7 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
(unsigned long long) GNUNET_ntohll (dc->uri->data.
chk.file_length));
/* truncate file to size (since we store IBlocks at the end) */
- if (dc->filename != NULL)
+ if (NULL != dc->filename)
{
if (0 !=
truncate (dc->filename,
@@ -1686,6 +1734,11 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
}
}
}
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Reconstruction failed, need to download block at offset %llu, depth %u\n",
+ (unsigned long long) offset,
+ depth);
break;
case BRS_DOWNLOAD_DOWN:
break;
@@ -1697,12 +1750,9 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset,
GNUNET_assert (0);
break;
}
+ dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
if ((dr == dc->top_request) && (dr->state == BRS_DOWNLOAD_UP))
- {
check_completed (dc);
- return;
- }
- dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
}
@@ -1725,16 +1775,19 @@ fh_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
struct GNUNET_DISK_FileHandle *fh = dc->rfh;
ssize_t ret;
- *emsg = NULL;
+ if (NULL != emsg)
+ *emsg = NULL;
if (offset != GNUNET_DISK_file_seek (fh, offset, GNUNET_DISK_SEEK_SET))
{
- *emsg = GNUNET_strdup (strerror (errno));
+ if (NULL != emsg)
+ *emsg = GNUNET_strdup (strerror (errno));
return 0;
}
ret = GNUNET_DISK_file_read (fh, buf, max);
if (ret < 0)
{
- *emsg = GNUNET_strdup (strerror (errno));
+ if (NULL != emsg)
+ *emsg = GNUNET_strdup (strerror (errno));
return 0;
}
return ret;
@@ -1758,10 +1811,10 @@ GNUNET_FS_download_start_task_ (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start task running...\n");
dc->task = GNUNET_SCHEDULER_NO_TASK;
- if (dc->length == 0)
+ if (0 == dc->length)
{
/* no bytes required! */
- if (dc->filename != NULL)
+ if (NULL != dc->filename)
{
fh = GNUNET_DISK_file_open (dc->filename,
GNUNET_DISK_OPEN_READWRITE |
@@ -1782,13 +1835,13 @@ GNUNET_FS_download_start_task_ (void *cls,
check_completed (dc);
return;
}
- if (dc->emsg != NULL)
+ if (NULL != dc->emsg)
return;
- if (dc->top_request == NULL)
+ if (NULL == dc->top_request)
{
dc->top_request =
- create_download_request (NULL, dc->treedepth - 1, 0, dc->offset,
- dc->length);
+ create_download_request (NULL, 0, dc->treedepth - 1, 0, dc->offset,
+ dc->length);
dc->top_request->state = BRS_CHK_SET;
dc->top_request->chk =
(dc->uri->type ==
@@ -1809,7 +1862,7 @@ GNUNET_FS_download_start_task_ (void *cls,
GNUNET_DISK_PERM_NONE);
if (dc->top_request->state == BRS_CHK_SET)
{
- if (dc->rfh != NULL)
+ if (NULL != dc->rfh)
{
/* first, try top-down */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1823,7 +1876,7 @@ GNUNET_FS_download_start_task_ (void *cls,
break; /* normal, some blocks already down */
case BRS_DOWNLOAD_UP:
/* already done entirely, party! */
- if (dc->rfh != NULL)
+ if (NULL != dc->rfh)
{
/* avoid hanging on to file handle longer than
* necessary */
@@ -1854,9 +1907,9 @@ GNUNET_FS_download_start_task_ (void *cls,
(unsigned int)
GNUNET_CONTAINER_meta_data_get_serialized_size (dc->meta));
GNUNET_CONTAINER_meta_data_iterate (dc->meta, &match_full_data, dc);
- if (dc->top_request->state == BRS_DOWNLOAD_UP)
+ if (BRS_DOWNLOAD_UP == dc->top_request->state)
{
- if (dc->rfh != NULL)
+ if (NULL != dc->rfh)
{
/* avoid hanging on to file handle longer than
* necessary */
@@ -1866,23 +1919,26 @@ GNUNET_FS_download_start_task_ (void *cls,
return; /* finished, status update was already done for us */
}
}
- if (dc->rfh != NULL)
+ if (NULL != dc->rfh)
{
- /* finally, try bottom-up */
+ /* finally, actually run bottom-up */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Trying bottom-up reconstruction of file `%s'\n", dc->filename);
dc->te =
- GNUNET_FS_tree_encoder_create (dc->h, dc->old_file_size, dc, &fh_reader,
- &reconstruct_cb, NULL,
- &reconstruct_cont);
+ GNUNET_FS_tree_encoder_create (dc->h,
+ GNUNET_FS_uri_chk_get_file_size (dc->uri),
+ dc, &fh_reader,
+ &reconstruct_cb, NULL,
+ &reconstruct_cont);
dc->task = GNUNET_SCHEDULER_add_now (&get_next_block, dc);
}
else
{
/* simple, top-level download */
+ dc->issue_requests = GNUNET_YES;
schedule_block_download (dc, dc->top_request);
}
- if (dc->top_request->state == BRS_DOWNLOAD_UP)
+ if (BRS_DOWNLOAD_UP == dc->top_request->state)
check_completed (dc);
}
@@ -1899,42 +1955,42 @@ GNUNET_FS_download_signal_suspend_ (void *cls)
struct GNUNET_FS_DownloadContext *dc = cls;
struct GNUNET_FS_ProgressInfo pi;
- if (dc->top != NULL)
+ if (NULL != dc->top)
GNUNET_FS_end_top (dc->h, dc->top);
while (NULL != dc->child_head)
GNUNET_FS_download_signal_suspend_ (dc->child_head);
- if (dc->search != NULL)
+ if (NULL != dc->search)
{
dc->search->download = NULL;
dc->search = NULL;
}
- if (dc->job_queue != NULL)
+ if (NULL != dc->job_queue)
{
GNUNET_FS_dequeue_ (dc->job_queue);
dc->job_queue = NULL;
}
- if (dc->parent != NULL)
+ if (NULL != dc->parent)
GNUNET_CONTAINER_DLL_remove (dc->parent->child_head, dc->parent->child_tail,
dc);
- if (dc->task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != dc->task)
{
GNUNET_SCHEDULER_cancel (dc->task);
dc->task = GNUNET_SCHEDULER_NO_TASK;
}
pi.status = GNUNET_FS_STATUS_DOWNLOAD_SUSPEND;
GNUNET_FS_download_make_status_ (&pi, dc);
- if (dc->te != NULL)
+ if (NULL != dc->te)
{
GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL);
dc->te = NULL;
}
- if (dc->rfh != NULL)
+ if (NULL != dc->rfh)
{
GNUNET_DISK_file_close (dc->rfh);
dc->rfh = NULL;
}
GNUNET_FS_free_download_request_ (dc->top_request);
- if (dc->active != NULL)
+ if (NULL != dc->active)
{
GNUNET_CONTAINER_multihashmap_destroy (dc->active);
dc->active = NULL;
@@ -1949,16 +2005,7 @@ GNUNET_FS_download_signal_suspend_ (void *cls)
/**
- * Download parts of a file. Note that this will store
- * the blocks at the respective offset in the given file. Also, the
- * download is still using the blocking of the underlying FS
- * encoding. As a result, the download may *write* outside of the
- * given boundaries (if offset and length do not match the 32k FS
- * block boundaries). <p>
- *
- * This function should be used to focus a download towards a
- * particular portion of the file (optimization), not to strictly
- * limit the download to exactly those bytes.
+ * Helper function to setup the download context.
*
* @param h handle to the file sharing subsystem
* @param uri the URI of the file (determines what to download); CHK or LOC URI
@@ -1974,38 +2021,27 @@ GNUNET_FS_download_signal_suspend_ (void *cls)
* @param anonymity anonymity level to use for the download
* @param options various options
* @param cctx initial value for the client context for this download
- * @param parent parent download to associate this download with (use NULL
- * for top-level downloads; useful for manually-triggered recursive downloads)
* @return context that can be used to control this download
*/
struct GNUNET_FS_DownloadContext *
-GNUNET_FS_download_start (struct GNUNET_FS_Handle *h,
- const struct GNUNET_FS_Uri *uri,
- const struct GNUNET_CONTAINER_MetaData *meta,
- const char *filename, const char *tempname,
- uint64_t offset, uint64_t length, uint32_t anonymity,
- enum GNUNET_FS_DownloadOptions options, void *cctx,
- struct GNUNET_FS_DownloadContext *parent)
+create_download_context (struct GNUNET_FS_Handle *h,
+ const struct GNUNET_FS_Uri *uri,
+ const struct GNUNET_CONTAINER_MetaData *meta,
+ const char *filename, const char *tempname,
+ uint64_t offset, uint64_t length, uint32_t anonymity,
+ enum GNUNET_FS_DownloadOptions options, void *cctx)
{
struct GNUNET_FS_DownloadContext *dc;
GNUNET_assert (GNUNET_FS_uri_test_chk (uri) || GNUNET_FS_uri_test_loc (uri));
-
if ((offset + length < offset) ||
(offset + length > GNUNET_FS_uri_chk_get_file_size (uri)))
{
GNUNET_break (0);
return NULL;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting download `%s' of %llu bytes\n",
- filename, (unsigned long long) length);
dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext));
dc->h = h;
- dc->parent = parent;
- if (parent != NULL)
- {
- GNUNET_CONTAINER_DLL_insert (parent->child_head, parent->child_tail, dc);
- }
dc->uri = GNUNET_FS_uri_dup (uri);
dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta);
dc->client_info = cctx;
@@ -2014,7 +2050,7 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h,
{
dc->filename = GNUNET_strdup (filename);
if (GNUNET_YES == GNUNET_DISK_file_test (filename))
- GNUNET_DISK_file_size (filename, &dc->old_file_size, GNUNET_YES);
+ GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (filename, &dc->old_file_size, GNUNET_YES, GNUNET_YES));
}
if (GNUNET_FS_uri_test_loc (dc->uri))
GNUNET_assert (GNUNET_OK ==
@@ -2027,22 +2063,74 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h,
GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE));
dc->treedepth =
GNUNET_FS_compute_depth (GNUNET_FS_uri_chk_get_file_size (dc->uri));
- if ((filename == NULL) && (is_recursive_download (dc)))
+ if ((NULL == filename) && (is_recursive_download (dc)))
{
- if (tempname != NULL)
+ if (NULL != tempname)
dc->temp_filename = GNUNET_strdup (tempname);
else
dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp");
}
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download tree has depth %u\n",
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Starting download `%s' of %llu bytes with tree depth %u\n",
+ filename,
+ (unsigned long long) length,
dc->treedepth);
- if (parent == NULL)
- {
+ dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc);
+ return dc;
+}
+
+
+/**
+ * Download parts of a file. Note that this will store
+ * the blocks at the respective offset in the given file. Also, the
+ * download is still using the blocking of the underlying FS
+ * encoding. As a result, the download may *write* outside of the
+ * given boundaries (if offset and length do not match the 32k FS
+ * block boundaries). <p>
+ *
+ * This function should be used to focus a download towards a
+ * particular portion of the file (optimization), not to strictly
+ * limit the download to exactly those bytes.
+ *
+ * @param h handle to the file sharing subsystem
+ * @param uri the URI of the file (determines what to download); CHK or LOC URI
+ * @param meta known metadata for the file (can be NULL)
+ * @param filename where to store the file, maybe NULL (then no file is
+ * created on disk and data must be grabbed from the callbacks)
+ * @param tempname where to store temporary file data, not used if filename is non-NULL;
+ * can be NULL (in which case we will pick a name if needed); the temporary file
+ * may already exist, in which case we will try to use the data that is there and
+ * if it is not what is desired, will overwrite it
+ * @param offset at what offset should we start the download (typically 0)
+ * @param length how many bytes should be downloaded starting at offset
+ * @param anonymity anonymity level to use for the download
+ * @param options various options
+ * @param cctx initial value for the client context for this download
+ * @param parent parent download to associate this download with (use NULL
+ * for top-level downloads; useful for manually-triggered recursive downloads)
+ * @return context that can be used to control this download
+ */
+struct GNUNET_FS_DownloadContext *
+GNUNET_FS_download_start (struct GNUNET_FS_Handle *h,
+ const struct GNUNET_FS_Uri *uri,
+ const struct GNUNET_CONTAINER_MetaData *meta,
+ const char *filename, const char *tempname,
+ uint64_t offset, uint64_t length, uint32_t anonymity,
+ enum GNUNET_FS_DownloadOptions options, void *cctx,
+ struct GNUNET_FS_DownloadContext *parent)
+{
+ struct GNUNET_FS_DownloadContext *dc;
+
+ dc = create_download_context (h, uri, meta, filename, tempname,
+ offset, length, anonymity, options, cctx);
+ if (NULL == dc)
+ return NULL;
+ dc->parent = parent;
+ if (NULL != parent)
+ GNUNET_CONTAINER_DLL_insert (parent->child_head, parent->child_tail, dc);
+ else
dc->top =
GNUNET_FS_make_top (dc->h, &GNUNET_FS_download_signal_suspend_, dc);
- }
- dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc);
return dc;
}
@@ -2092,62 +2180,22 @@ GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h,
{
struct GNUNET_FS_DownloadContext *dc;
- if ((sr == NULL) || (sr->download != NULL))
+ if ((NULL == sr) || (NULL != sr->download))
{
GNUNET_break (0);
return NULL;
}
- GNUNET_assert (GNUNET_FS_uri_test_chk (sr->uri) ||
- GNUNET_FS_uri_test_loc (sr->uri));
- if ((offset + length < offset) ||
- (offset + length > sr->uri->data.chk.file_length))
- {
- GNUNET_break (0);
+ dc = create_download_context (h, sr->uri, sr->meta, filename, tempname,
+ offset, length, anonymity, options, cctx);
+ if (NULL == dc)
return NULL;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting download `%s' of %llu bytes\n",
- filename, (unsigned long long) length);
- dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext));
- dc->h = h;
dc->search = sr;
sr->download = dc;
- if (sr->probe_ctx != NULL)
+ if (NULL != sr->probe_ctx)
{
GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
sr->probe_ctx = NULL;
}
- dc->uri = GNUNET_FS_uri_dup (sr->uri);
- dc->meta = GNUNET_CONTAINER_meta_data_duplicate (sr->meta);
- dc->client_info = cctx;
- dc->start_time = GNUNET_TIME_absolute_get ();
- if (NULL != filename)
- {
- dc->filename = GNUNET_strdup (filename);
- if (GNUNET_YES == GNUNET_DISK_file_test (filename))
- GNUNET_DISK_file_size (filename, &dc->old_file_size, GNUNET_YES);
- }
- if (GNUNET_FS_uri_test_loc (dc->uri))
- GNUNET_assert (GNUNET_OK ==
- GNUNET_FS_uri_loc_get_peer_identity (dc->uri, &dc->target));
- dc->offset = offset;
- dc->length = length;
- dc->anonymity = anonymity;
- dc->options = options;
- dc->active =
- GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE));
- dc->treedepth =
- GNUNET_FS_compute_depth (GNUNET_ntohll (dc->uri->data.chk.file_length));
- if ((filename == NULL) && (is_recursive_download (dc)))
- {
- if (tempname != NULL)
- dc->temp_filename = GNUNET_strdup (tempname);
- else
- dc->temp_filename = GNUNET_DISK_mktemp ("gnunet-directory-download-tmp");
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download tree has depth %u\n",
- dc->treedepth);
- dc->task = GNUNET_SCHEDULER_add_now (&GNUNET_FS_download_start_task_, dc);
return dc;
}
@@ -2162,10 +2210,13 @@ GNUNET_FS_download_start_downloading_ (struct GNUNET_FS_DownloadContext *dc)
{
if (dc->completed == dc->length)
return;
- GNUNET_assert (dc->job_queue == NULL);
+ GNUNET_assert (NULL == dc->job_queue);
dc->job_queue =
GNUNET_FS_queue_ (dc->h, &activate_fs_download, &deactivate_fs_download,
- dc, (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE);
+ dc, (dc->length + DBLOCK_SIZE - 1) / DBLOCK_SIZE,
+ (0 == (dc->options & GNUNET_FS_DOWNLOAD_IS_PROBE))
+ ? GNUNET_FS_QUEUE_PRIORITY_NORMAL
+ : GNUNET_FS_QUEUE_PRIORITY_PROBE);
}
@@ -2180,28 +2231,28 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete)
{
struct GNUNET_FS_ProgressInfo pi;
int have_children;
+ int search_was_null;
- if (dc->top != NULL)
+ if (NULL != dc->top)
GNUNET_FS_end_top (dc->h, dc->top);
-
-
- if (dc->task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != dc->task)
{
GNUNET_SCHEDULER_cancel (dc->task);
dc->task = GNUNET_SCHEDULER_NO_TASK;
}
- if (dc->search != NULL)
+ search_was_null = (NULL == dc->search);
+ if (NULL != dc->search)
{
dc->search->download = NULL;
GNUNET_FS_search_result_sync_ (dc->search);
dc->search = NULL;
}
- if (dc->job_queue != NULL)
+ if (NULL != dc->job_queue)
{
GNUNET_FS_dequeue_ (dc->job_queue);
dc->job_queue = NULL;
}
- if (dc->te != NULL)
+ if (NULL != dc->te)
{
GNUNET_FS_tree_encoder_finish (dc->te, NULL, NULL);
dc->te = NULL;
@@ -2209,32 +2260,30 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete)
have_children = (NULL != dc->child_head) ? GNUNET_YES : GNUNET_NO;
while (NULL != dc->child_head)
GNUNET_FS_download_stop (dc->child_head, do_delete);
- if (dc->parent != NULL)
+ if (NULL != dc->parent)
GNUNET_CONTAINER_DLL_remove (dc->parent->child_head, dc->parent->child_tail,
dc);
- if (dc->serialization != NULL)
+ if (NULL != dc->serialization)
GNUNET_FS_remove_sync_file_ (dc->h,
- ((dc->parent != NULL) ||
- (dc->search !=
- NULL)) ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD :
+ ((NULL != dc->parent) ||
+ (! search_was_null)) ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD :
GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD,
dc->serialization);
- if ((GNUNET_YES == have_children) && (dc->parent == NULL))
+ if ((GNUNET_YES == have_children) && (NULL == dc->parent))
GNUNET_FS_remove_sync_dir_ (dc->h,
- (dc->search !=
- NULL) ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD :
+ (! search_was_null) ? GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD :
GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD,
dc->serialization);
pi.status = GNUNET_FS_STATUS_DOWNLOAD_STOPPED;
GNUNET_FS_download_make_status_ (&pi, dc);
GNUNET_FS_free_download_request_ (dc->top_request);
dc->top_request = NULL;
- if (dc->active != NULL)
+ if (NULL != dc->active)
{
GNUNET_CONTAINER_multihashmap_destroy (dc->active);
dc->active = NULL;
}
- if (dc->filename != NULL)
+ if (NULL != dc->filename)
{
if ((dc->completed != dc->length) && (GNUNET_YES == do_delete))
{
diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c
index 85a076f..8065927 100644
--- a/src/fs/fs_file_information.c
+++ b/src/fs/fs_file_information.c
@@ -107,7 +107,7 @@ GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h,
*bo)
{
struct FileInfo *fi;
- struct stat sbuf;
+ uint64_t fsize;
struct GNUNET_FS_FileInformation *ret;
const char *fn;
const char *ss;
@@ -116,7 +116,8 @@ GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h,
char fn_conv[MAX_PATH];
#endif
- if (0 != STAT (filename, &sbuf))
+ /* FIXME: should includeSymLinks be GNUNET_NO or GNUNET_YES here? */
+ if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fsize, GNUNET_NO, GNUNET_YES))
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
return NULL;
@@ -129,7 +130,7 @@ GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h,
}
ret =
GNUNET_FS_file_information_create_from_reader (h, client_info,
- sbuf.st_size,
+ fsize,
&GNUNET_FS_data_reader_file_,
fi, keywords, meta,
do_index, bo);
@@ -145,6 +146,9 @@ GNUNET_FS_file_information_create_from_file (struct GNUNET_FS_Handle *h,
#endif
while (NULL != (ss = strstr (fn, DIR_SEPARATOR_STR)))
fn = ss + 1;
+/* FIXME: If we assume that on other platforms CRT is UTF-8-aware, then
+ * this should be changed to EXTRACTOR_METAFORMAT_UTF8
+ */
#if !WINDOWS
GNUNET_CONTAINER_meta_data_insert (ret->meta, "<gnunet>",
EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
diff --git a/src/fs/fs_list_indexed.c b/src/fs/fs_list_indexed.c
index 784c988..ef03dee 100644
--- a/src/fs/fs_list_indexed.c
+++ b/src/fs/fs_list_indexed.c
@@ -176,7 +176,7 @@ GNUNET_FS_get_indexed_files (struct GNUNET_FS_Handle *h,
void
GNUNET_FS_get_indexed_files_cancel (struct GNUNET_FS_GetIndexedContext *gic)
{
- GNUNET_CLIENT_disconnect (gic->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (gic->client);
GNUNET_free (gic);
}
diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c
index 1657e29..93c3046 100644
--- a/src/fs/fs_publish.c
+++ b/src/fs/fs_publish.c
@@ -98,7 +98,7 @@ publish_cleanup (struct GNUNET_FS_PublishContext *pc)
}
if (pc->client != NULL)
{
- GNUNET_CLIENT_disconnect (pc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (pc->client);
pc->client = NULL;
}
GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task);
@@ -355,6 +355,8 @@ block_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
}
else
{
+ if (UINT64_MAX == offset)
+ return p->data.file.reader (p->data.file.reader_cls, offset, 0, NULL, NULL);
pt_size = GNUNET_MIN (max, p->data.file.file_size - offset);
if (pt_size == 0)
return 0; /* calling reader with pt_size==0
@@ -385,10 +387,10 @@ encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
char *emsg;
uint64_t flen;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished with tree encoder\n");
p = pc->fi_pos;
GNUNET_FS_tree_encoder_finish (p->te, &p->chk_uri, &emsg);
p->te = NULL;
- GNUNET_FS_file_information_sync_ (p);
if (NULL != emsg)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error during tree walk: %s\n", emsg);
@@ -399,16 +401,19 @@ encode_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
pi.value.publish.specifics.error.message = p->emsg;
p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, 0);
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished with tree encoder\n");
+ else
+ {
/* final progress event */
- flen = GNUNET_FS_uri_chk_get_file_size (p->chk_uri);
- pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS;
- pi.value.publish.specifics.progress.data = NULL;
- pi.value.publish.specifics.progress.offset = flen;
- pi.value.publish.specifics.progress.data_len = 0;
- pi.value.publish.specifics.progress.depth = GNUNET_FS_compute_depth (flen);
- p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, flen);
-
+ GNUNET_assert (NULL != p->chk_uri);
+ flen = GNUNET_FS_uri_chk_get_file_size (p->chk_uri);
+ pi.status = GNUNET_FS_STATUS_PUBLISH_PROGRESS;
+ pi.value.publish.specifics.progress.data = NULL;
+ pi.value.publish.specifics.progress.offset = flen;
+ pi.value.publish.specifics.progress.data_len = 0;
+ pi.value.publish.specifics.progress.depth = GNUNET_FS_compute_depth (flen);
+ p->client_info = GNUNET_FS_publish_make_status_ (&pi, pc, p, flen);
+ }
+ GNUNET_FS_file_information_sync_ (p);
/* continue with main */
GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task);
pc->upload_task =
@@ -606,7 +611,7 @@ process_index_start_response (void *cls, const struct GNUNET_MessageHeader *msg)
const char *emsg;
uint16_t msize;
- GNUNET_CLIENT_disconnect (pc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (pc->client);
pc->client = NULL;
p = pc->fi_pos;
if (msg == NULL)
@@ -942,10 +947,9 @@ fip_signal_start (void *cls, struct GNUNET_FS_FileInformation *fi,
pi.status = GNUNET_FS_STATUS_PUBLISH_START;
*client_info = GNUNET_FS_publish_make_status_ (&pi, pc, fi, 0);
GNUNET_FS_file_information_sync_ (fi);
- if (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (meta)
- && (fi->dir != NULL))
+ if ((fi->is_directory) && (fi->dir != NULL))
{
- /* process entries in directory */
+ /* We are a directory, and we are not top-level; process entries in directory */
pc->skip_next_fi_callback = GNUNET_YES;
GNUNET_FS_file_information_inspect (fi, &fip_signal_start, pc);
}
diff --git a/src/fs/fs_publish_ksk.c b/src/fs/fs_publish_ksk.c
index 5119de4..0b6d407 100644
--- a/src/fs/fs_publish_ksk.c
+++ b/src/fs/fs_publish_ksk.c
@@ -188,7 +188,7 @@ publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
}
keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++];
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under keyword `%s'\n",
- keyword);
+ &keyword[1]);
/* first character of keyword indicates if it is
* mandatory or not -- ignore for hashing */
GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key);
diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c
index a163d97..b280670 100644
--- a/src/fs/fs_search.c
+++ b/src/fs/fs_search.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001-2006, 2008-2011 Christian Grothoff (and other contributing authors)
+ (C) 2001-2006, 2008-2012 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
@@ -14,10 +14,9 @@
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Free Software Foundation, Inc., 59 Tem ple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
-
/**
* @file fs/fs_search.c
* @brief Helper functions for searching.
@@ -30,7 +29,6 @@
#include "gnunet_protocols.h"
#include "fs_api.h"
-#define DEBUG_SEARCH GNUNET_EXTRA_LOGGING
/**
* Number of availability trials we perform per search result.
@@ -54,7 +52,7 @@ GNUNET_FS_search_make_status_ (struct GNUNET_FS_ProgressInfo *pi,
pi->value.search.sc = sc;
pi->value.search.cctx = sc->client_info;
pi->value.search.pctx =
- (sc->psearch_result == NULL) ? NULL : sc->psearch_result->client_info;
+ (NULL == sc->psearch_result) ? NULL : sc->psearch_result->client_info;
pi->value.search.query = sc->uri;
pi->value.search.duration =
GNUNET_TIME_absolute_get_duration (sc->start_time);
@@ -121,7 +119,7 @@ notify_client_chk_update (struct GNUNET_FS_SearchContext *sc,
struct GNUNET_FS_SearchResult *sr)
{
struct GNUNET_FS_ProgressInfo pi;
-
+
pi.status = GNUNET_FS_STATUS_SEARCH_UPDATE;
pi.value.search.specifics.update.cctx = sr->client_info;
pi.value.search.specifics.update.meta = sr->meta;
@@ -184,7 +182,7 @@ signal_probe_result (struct GNUNET_FS_SearchResult *sr)
{
struct GNUNET_FS_ProgressInfo pi;
- pi.status = GNUNET_FS_STATUS_SEARCH_START;
+ pi.status = GNUNET_FS_STATUS_SEARCH_UPDATE;
pi.value.search.specifics.update.cctx = sr->client_info;
pi.value.search.specifics.update.meta = sr->meta;
pi.value.search.specifics.update.uri = sr->uri;
@@ -192,7 +190,7 @@ signal_probe_result (struct GNUNET_FS_SearchResult *sr)
pi.value.search.specifics.update.availability_certainty =
sr->availability_trials;
pi.value.search.specifics.update.applicability_rank = sr->optional_support;
- sr->sc->client_info = GNUNET_FS_search_make_status_ (&pi, sr->sc);
+ sr->client_info = GNUNET_FS_search_make_status_ (&pi, sr->sc);
GNUNET_FS_search_start_probe_ (sr);
}
@@ -208,7 +206,10 @@ probe_failure_handler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_FS_SearchResult *sr = cls;
+ sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
sr->availability_trials++;
+ GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
+ sr->probe_ctx = NULL;
GNUNET_FS_search_result_sync_ (sr);
signal_probe_result (sr);
}
@@ -225,8 +226,11 @@ probe_success_handler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_FS_SearchResult *sr = cls;
+ sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
sr->availability_trials++;
sr->availability_success++;
+ GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
+ sr->probe_ctx = NULL;
GNUNET_FS_search_result_sync_ (sr);
signal_probe_result (sr);
}
@@ -271,7 +275,7 @@ GNUNET_FS_search_probe_progress_ (void *cls,
/* ignore */
break;
case GNUNET_FS_STATUS_DOWNLOAD_ERROR:
- if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
{
GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
@@ -281,17 +285,16 @@ GNUNET_FS_search_probe_progress_ (void *cls,
&probe_failure_handler, sr);
break;
case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED:
- if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
{
GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
}
sr->probe_cancel_task =
- GNUNET_SCHEDULER_add_delayed (sr->remaining_probe_time,
- &probe_success_handler, sr);
+ GNUNET_SCHEDULER_add_now (&probe_success_handler, sr);
break;
case GNUNET_FS_STATUS_DOWNLOAD_STOPPED:
- if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
{
GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
@@ -299,14 +302,14 @@ GNUNET_FS_search_probe_progress_ (void *cls,
sr = NULL;
break;
case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE:
- GNUNET_assert (sr->probe_cancel_task == GNUNET_SCHEDULER_NO_TASK);
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sr->probe_cancel_task);
sr->probe_active_time = GNUNET_TIME_absolute_get ();
sr->probe_cancel_task =
GNUNET_SCHEDULER_add_delayed (sr->remaining_probe_time,
&probe_failure_handler, sr);
break;
case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE:
- if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
{
GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
@@ -335,16 +338,18 @@ GNUNET_FS_search_start_probe_ (struct GNUNET_FS_SearchResult *sr)
uint64_t off;
uint64_t len;
- if (sr->probe_ctx != NULL)
+ if (NULL != sr->probe_ctx)
return;
- if (sr->download != NULL)
+ if (NULL != sr->download)
return;
if (0 == (sr->sc->h->flags & GNUNET_FS_FLAGS_DO_PROBES))
return;
if (sr->availability_trials > AVAILABILITY_TRIALS_MAX)
return;
+ if ( (chk != sr->uri->type) && (loc != sr->uri->type))
+ return;
len = GNUNET_FS_uri_chk_get_file_size (sr->uri);
- if (len == 0)
+ if (0 == len)
return;
if ((len <= DBLOCK_SIZE) && (sr->availability_success > 0))
return;
@@ -497,7 +502,7 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, const char *id_update,
/* notify client */
notify_client_chk_result (sc, sr);
/* search for updates */
- if (strlen (id_update) == 0)
+ if (0 == strlen (id_update))
return; /* no updates */
uu.type = sks;
uu.data.sks.namespace = sc->uri->data.sks.namespace;
@@ -508,28 +513,32 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, const char *id_update,
/**
- * Process a keyword-search result.
+ * Decrypt a block using a 'keyword' as the passphrase. Given the
+ * KSK public key derived from the keyword, this function looks up
+ * the original keyword in the search context and decrypts the
+ * given ciphertext block.
*
- * @param sc our search context
- * @param kb the kblock
- * @param size size of kb
+ * @param sc search context with the keywords
+ * @param public_key public key to use to lookup the keyword
+ * @param edata encrypted data
+ * @param edata_size number of bytes in 'edata' (and 'data')
+ * @param data where to store the plaintext
+ * @return keyword index on success, GNUNET_SYSERR on error (no such
+ * keyword, internal error)
*/
-static void
-process_kblock (struct GNUNET_FS_SearchContext *sc, const struct KBlock *kb,
- size_t size)
-{
- unsigned int i;
- size_t j;
+static int
+decrypt_block_with_keyword (const struct GNUNET_FS_SearchContext *sc,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
+ const void *edata,
+ size_t edata_size,
+ char *data)
+{
GNUNET_HashCode q;
- char pt[size - sizeof (struct KBlock)];
struct GNUNET_CRYPTO_AesSessionKey skey;
struct GNUNET_CRYPTO_AesInitializationVector iv;
- const char *eos;
- struct GNUNET_CONTAINER_MetaData *meta;
- struct GNUNET_FS_Uri *uri;
- char *emsg;
+ int i;
- GNUNET_CRYPTO_hash (&kb->keyspace,
+ GNUNET_CRYPTO_hash (public_key,
sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
&q);
/* find key */
@@ -540,17 +549,46 @@ process_kblock (struct GNUNET_FS_SearchContext *sc, const struct KBlock *kb,
{
/* oops, does not match any of our keywords!? */
GNUNET_break (0);
- return;
+ return GNUNET_SYSERR;
}
/* decrypt */
GNUNET_CRYPTO_hash_to_aes_key (&sc->requests[i].key, &skey, &iv);
if (-1 ==
- GNUNET_CRYPTO_aes_decrypt (&kb[1], size - sizeof (struct KBlock), &skey,
- &iv, pt))
+ GNUNET_CRYPTO_aes_decrypt (edata, edata_size, &skey,
+ &iv, data))
{
GNUNET_break (0);
- return;
+ return GNUNET_SYSERR;
}
+ return i;
+}
+
+
+/**
+ * Process a keyword-search result.
+ *
+ * @param sc our search context
+ * @param kb the kblock
+ * @param size size of kb
+ */
+static void
+process_kblock (struct GNUNET_FS_SearchContext *sc, const struct KBlock *kb,
+ size_t size)
+{
+ size_t j;
+ char pt[size - sizeof (struct KBlock)];
+ const char *eos;
+ struct GNUNET_CONTAINER_MetaData *meta;
+ struct GNUNET_FS_Uri *uri;
+ char *emsg;
+ int i;
+
+ if (-1 == (i = decrypt_block_with_keyword (sc,
+ &kb->keyspace,
+ &kb[1],
+ size - sizeof (struct KBlock),
+ pt)))
+ return;
/* parse */
eos = memchr (pt, 0, sizeof (pt));
if (NULL == eos)
@@ -563,13 +601,13 @@ process_kblock (struct GNUNET_FS_SearchContext *sc, const struct KBlock *kb,
meta = GNUNET_CONTAINER_meta_data_create ();
else
meta = GNUNET_CONTAINER_meta_data_deserialize (&pt[j], sizeof (pt) - j);
- if (meta == NULL)
+ if (NULL == meta)
{
GNUNET_break_op (0); /* kblock malformed */
return;
}
uri = GNUNET_FS_uri_parse (pt, &emsg);
- if (uri == NULL)
+ if (NULL == uri)
{
GNUNET_break_op (0); /* kblock malformed */
GNUNET_free_non_null (emsg);
@@ -596,39 +634,20 @@ static void
process_nblock (struct GNUNET_FS_SearchContext *sc, const struct NBlock *nb,
size_t size)
{
- unsigned int i;
size_t j;
- GNUNET_HashCode q;
char pt[size - sizeof (struct NBlock)];
- struct GNUNET_CRYPTO_AesSessionKey skey;
- struct GNUNET_CRYPTO_AesInitializationVector iv;
const char *eos;
struct GNUNET_CONTAINER_MetaData *meta;
struct GNUNET_FS_Uri *uri;
char *uris;
+ int i;
- GNUNET_CRYPTO_hash (&nb->keyspace,
- sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
- &q);
- /* find key */
- for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
- if (0 == memcmp (&q, &sc->requests[i].query, sizeof (GNUNET_HashCode)))
- break;
- if (i == sc->uri->data.ksk.keywordCount)
- {
- /* oops, does not match any of our keywords!? */
- GNUNET_break (0);
- return;
- }
- /* decrypt */
- GNUNET_CRYPTO_hash_to_aes_key (&sc->requests[i].key, &skey, &iv);
- if (-1 ==
- GNUNET_CRYPTO_aes_decrypt (&nb[1], size - sizeof (struct NBlock), &skey,
- &iv, pt))
- {
- GNUNET_break (0);
+ if (-1 == (i = decrypt_block_with_keyword (sc,
+ &nb->keyspace,
+ &nb[1],
+ size - sizeof (struct NBlock),
+ pt)))
return;
- }
/* parse */
eos = memchr (pt, 0, sizeof (pt));
if (NULL == eos)
@@ -641,7 +660,7 @@ process_nblock (struct GNUNET_FS_SearchContext *sc, const struct NBlock *nb,
meta = GNUNET_CONTAINER_meta_data_create ();
else
meta = GNUNET_CONTAINER_meta_data_deserialize (&pt[j], sizeof (pt) - j);
- if (meta == NULL)
+ if (NULL == meta)
{
GNUNET_break_op (0); /* nblock malformed */
return;
@@ -703,7 +722,7 @@ process_sblock (struct GNUNET_FS_SearchContext *sc, const struct SBlock *sb,
}
/* parse */
off = GNUNET_STRINGS_buffer_tokenize (pt, len, 2, &id, &uris);
- if (off == 0)
+ if (0 == off)
{
GNUNET_break_op (0); /* sblock malformed */
return;
@@ -715,7 +734,7 @@ process_sblock (struct GNUNET_FS_SearchContext *sc, const struct SBlock *sb,
return;
}
uri = GNUNET_FS_uri_parse (uris, &emsg);
- if (uri == NULL)
+ if (NULL == uri)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to parse URI `%s': %s\n", uris,
emsg);
@@ -914,7 +933,7 @@ build_result_set (void *cls, const GNUNET_HashCode * key, void *value)
struct MessageBuilderContext *mbc = cls;
struct GNUNET_FS_SearchResult *sr = value;
- if ( (sr->keyword_bitmap != NULL) &&
+ if ( (NULL != sr->keyword_bitmap) &&
(0 == (sr->keyword_bitmap[mbc->keyword_offset / 8] & (1 << (mbc->keyword_offset % 8)))) )
return GNUNET_OK; /* have no match for this keyword yet */
if (mbc->skip_cnt > 0)
@@ -922,7 +941,7 @@ build_result_set (void *cls, const GNUNET_HashCode * key, void *value)
mbc->skip_cnt--;
return GNUNET_OK;
}
- if (mbc->put_cnt == 0)
+ if (0 == mbc->put_cnt)
return GNUNET_SYSERR;
mbc->sc->search_request_map_offset++;
mbc->xoff[--mbc->put_cnt] = *key;
@@ -946,7 +965,7 @@ find_result_set (void *cls, const GNUNET_HashCode * key, void *value)
struct MessageBuilderContext *mbc = cls;
struct GNUNET_FS_SearchResult *sr = value;
- if ( (sr->keyword_bitmap != NULL) &&
+ if ( (NULL != sr->keyword_bitmap) &&
(0 == (sr->keyword_bitmap[mbc->keyword_offset / 8] & (1 << (mbc->keyword_offset % 8)))) )
return GNUNET_OK; /* have no match for this keyword yet */
mbc->put_cnt++;
@@ -1133,7 +1152,7 @@ try_reconnect (struct GNUNET_FS_SearchContext *sc)
{
if (NULL != sc->client)
{
- GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (sc->client);
sc->client = NULL;
}
sc->task =
@@ -1168,7 +1187,7 @@ search_start (struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri,
sc->uri = GNUNET_FS_uri_dup (uri);
sc->anonymity = anonymity;
sc->start_time = GNUNET_TIME_absolute_get ();
- if (psearch != NULL)
+ if (NULL != psearch)
{
sc->psearch_result = psearch;
psearch->update_search = sc;
@@ -1217,7 +1236,7 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc)
keyword = &sc->uri->data.ksk.keywords[i][1];
GNUNET_CRYPTO_hash (keyword, strlen (keyword), &hc);
pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&hc);
- GNUNET_assert (pk != NULL);
+ GNUNET_assert (NULL != pk);
GNUNET_CRYPTO_rsa_key_get_public (pk, &pub);
GNUNET_CRYPTO_rsa_key_free (pk);
GNUNET_CRYPTO_hash (&pub,
@@ -1253,17 +1272,17 @@ search_result_freeze_probes (void *cls, const GNUNET_HashCode * key,
{
struct GNUNET_FS_SearchResult *sr = value;
- if (sr->probe_ctx != NULL)
+ if (NULL != sr->probe_ctx)
{
GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
sr->probe_ctx = NULL;
}
- if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
{
GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
}
- if (sr->update_search != NULL)
+ if (NULL != sr->update_search)
GNUNET_FS_search_pause (sr->update_search);
return GNUNET_OK;
}
@@ -1284,7 +1303,7 @@ search_result_resume_probes (void *cls, const GNUNET_HashCode * key,
struct GNUNET_FS_SearchResult *sr = value;
GNUNET_FS_search_start_probe_ (sr);
- if (sr->update_search != NULL)
+ if (NULL != sr->update_search)
GNUNET_FS_search_continue (sr->update_search);
return GNUNET_OK;
}
@@ -1305,10 +1324,21 @@ search_result_suspend (void *cls, const GNUNET_HashCode * key, void *value)
struct GNUNET_FS_SearchResult *sr = value;
struct GNUNET_FS_ProgressInfo pi;
- if (sr->download != NULL)
+ if (NULL != sr->download)
+ {
GNUNET_FS_download_signal_suspend_ (sr->download);
- if (sr->update_search != NULL)
+ sr->download = NULL;
+ }
+ if (NULL != sr->probe_ctx)
+ {
+ GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
+ sr->probe_ctx = NULL;
+ }
+ if (NULL != sr->update_search)
+ {
GNUNET_FS_search_signal_suspend_ (sr->update_search);
+ sr->update_search = NULL;
+ }
pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_SUSPEND;
pi.value.search.specifics.result_suspend.cctx = sr->client_info;
pi.value.search.specifics.result_suspend.meta = sr->meta;
@@ -1318,10 +1348,11 @@ search_result_suspend (void *cls, const GNUNET_HashCode * key, void *value)
GNUNET_free_non_null (sr->serialization);
GNUNET_FS_uri_destroy (sr->uri);
GNUNET_CONTAINER_meta_data_destroy (sr->meta);
- if (sr->probe_ctx != NULL)
- GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
- if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
+ {
GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
+ sr->probe_cancel_task = GNUNET_SCHEDULER_NO_TASK;
+ }
GNUNET_free_non_null (sr->keyword_bitmap);
GNUNET_free (sr);
return GNUNET_OK;
@@ -1350,9 +1381,9 @@ GNUNET_FS_search_signal_suspend_ (void *cls)
if (sc->task != GNUNET_SCHEDULER_NO_TASK)
GNUNET_SCHEDULER_cancel (sc->task);
if (NULL != sc->client)
- GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (sc->client);
GNUNET_CONTAINER_multihashmap_destroy (sc->master_result_map);
- if (sc->requests != NULL)
+ if (NULL != sc->requests)
{
GNUNET_assert (GNUNET_FS_uri_test_ksk (sc->uri));
for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
@@ -1385,7 +1416,7 @@ GNUNET_FS_search_start (struct GNUNET_FS_Handle *h,
struct GNUNET_FS_SearchContext *ret;
ret = search_start (h, uri, anonymity, options, cctx, NULL);
- if (ret == NULL)
+ if (NULL == ret)
return NULL;
ret->top = GNUNET_FS_make_top (h, &GNUNET_FS_search_signal_suspend_, ret);
return ret;
@@ -1402,11 +1433,11 @@ GNUNET_FS_search_pause (struct GNUNET_FS_SearchContext *sc)
{
struct GNUNET_FS_ProgressInfo pi;
- if (sc->task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != sc->task)
GNUNET_SCHEDULER_cancel (sc->task);
sc->task = GNUNET_SCHEDULER_NO_TASK;
if (NULL != sc->client)
- GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (sc->client);
sc->client = NULL;
GNUNET_FS_search_sync_ (sc);
GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
@@ -1426,8 +1457,8 @@ GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc)
{
struct GNUNET_FS_ProgressInfo pi;
- GNUNET_assert (sc->client == NULL);
- GNUNET_assert (sc->task == GNUNET_SCHEDULER_NO_TASK);
+ GNUNET_assert (NULL == sc->client);
+ GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sc->task);
do_reconnect (sc, NULL);
GNUNET_FS_search_sync_ (sc);
pi.status = GNUNET_FS_STATUS_SEARCH_CONTINUED;
@@ -1438,7 +1469,7 @@ GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc)
/**
- * Free the given search result.
+ * Signal stop for the given search result.
*
* @param cls the global FS handle
* @param key the key for the search result (unused)
@@ -1446,7 +1477,7 @@ GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc)
* @return GNUNET_OK
*/
static int
-search_result_free (void *cls, const GNUNET_HashCode * key, void *value)
+search_result_stop (void *cls, const GNUNET_HashCode * key, void *value)
{
struct GNUNET_FS_SearchContext *sc = cls;
struct GNUNET_FS_SearchResult *sr = value;
@@ -1470,23 +1501,40 @@ search_result_free (void *cls, const GNUNET_HashCode * key, void *value)
GNUNET_FS_download_sync_ (sr->download);
sr->download = NULL;
}
- if (NULL != sr->update_search)
- {
- GNUNET_FS_search_stop (sr->update_search);
- GNUNET_assert (sr->update_search == NULL);
- }
pi.status = GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED;
pi.value.search.specifics.result_stopped.cctx = sr->client_info;
pi.value.search.specifics.result_stopped.meta = sr->meta;
pi.value.search.specifics.result_stopped.uri = sr->uri;
sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Free the given search result.
+ *
+ * @param cls the global FS handle
+ * @param key the key for the search result (unused)
+ * @param value the search result to free
+ * @return GNUNET_OK
+ */
+static int
+search_result_free (void *cls, const GNUNET_HashCode * key, void *value)
+{
+ struct GNUNET_FS_SearchResult *sr = value;
+
+ if (NULL != sr->update_search)
+ {
+ GNUNET_FS_search_stop (sr->update_search);
+ GNUNET_assert (NULL == sr->update_search);
+ }
GNUNET_break (NULL == sr->client_info);
GNUNET_free_non_null (sr->serialization);
GNUNET_FS_uri_destroy (sr->uri);
GNUNET_CONTAINER_meta_data_destroy (sr->meta);
- if (sr->probe_ctx != NULL)
+ if (NULL != sr->probe_ctx)
GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES);
- if (sr->probe_cancel_task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task)
GNUNET_SCHEDULER_cancel (sr->probe_cancel_task);
GNUNET_free_non_null (sr->keyword_bitmap);
GNUNET_free (sr);
@@ -1505,13 +1553,13 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc)
struct GNUNET_FS_ProgressInfo pi;
unsigned int i;
- if (sc->top != NULL)
+ if (NULL != sc->top)
GNUNET_FS_end_top (sc->h, sc->top);
- if (sc->psearch_result != NULL)
- sc->psearch_result->update_search = NULL;
GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
- &search_result_free, sc);
- if (sc->serialization != NULL)
+ &search_result_stop, sc);
+ if (NULL != sc->psearch_result)
+ sc->psearch_result->update_search = NULL;
+ if (NULL != sc->serialization)
{
GNUNET_FS_remove_sync_file_ (sc->h,
(sc->psearch_result !=
@@ -1528,12 +1576,14 @@ GNUNET_FS_search_stop (struct GNUNET_FS_SearchContext *sc)
pi.status = GNUNET_FS_STATUS_SEARCH_STOPPED;
sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc);
GNUNET_break (NULL == sc->client_info);
- if (sc->task != GNUNET_SCHEDULER_NO_TASK)
+ if (GNUNET_SCHEDULER_NO_TASK != sc->task)
GNUNET_SCHEDULER_cancel (sc->task);
if (NULL != sc->client)
- GNUNET_CLIENT_disconnect (sc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (sc->client);
+ GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map,
+ &search_result_free, sc);
GNUNET_CONTAINER_multihashmap_destroy (sc->master_result_map);
- if (sc->requests != NULL)
+ if (NULL != sc->requests)
{
GNUNET_assert (GNUNET_FS_uri_test_ksk (sc->uri));
for (i = 0; i < sc->uri->data.ksk.keywordCount; i++)
diff --git a/src/fs/fs_tree.c b/src/fs/fs_tree.c
index b3bbdc7..30cdded 100644
--- a/src/fs/fs_tree.c
+++ b/src/fs/fs_tree.c
@@ -287,6 +287,10 @@ GNUNET_FS_tree_encoder_create (struct GNUNET_FS_Handle *h, uint64_t size,
te->chk_tree =
GNUNET_malloc (te->chk_tree_depth * CHK_PER_INODE *
sizeof (struct ContentHashKey));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Created tree encoder for file with %llu bytes and depth %u\n",
+ (unsigned long long) size,
+ te->chk_tree_depth);
return te;
}
@@ -357,8 +361,8 @@ GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder *te)
if (pt_size !=
te->reader (te->cls, te->publish_offset, pt_size, iob, &te->emsg))
{
- te->cont (te->cls, NULL);
te->in_next = GNUNET_NO;
+ te->cont (te->cls, NULL);
return;
}
pt_block = iob;
@@ -425,6 +429,7 @@ void
GNUNET_FS_tree_encoder_finish (struct GNUNET_FS_TreeEncoder *te,
struct GNUNET_FS_Uri **uri, char **emsg)
{
+ (void) te->reader (te->cls, UINT64_MAX, 0, 0, NULL);
GNUNET_assert (GNUNET_NO == te->in_next);
if (uri != NULL)
*uri = te->uri;
diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c
index ff1996a..6910321 100644
--- a/src/fs/fs_unindex.c
+++ b/src/fs/fs_unindex.c
@@ -30,6 +30,7 @@
#include "gnunet_protocols.h"
#include "fs_api.h"
#include "fs_tree.h"
+#include "block_fs.h"
/**
@@ -203,6 +204,7 @@ unindex_process (void *cls, const struct ContentHashKey *chk, uint64_t offset,
"Sending REMOVE request to DATASTORE service\n");
GNUNET_DATASTORE_remove (uc->dsh, &chk->query, size, data, -2, 1,
GNUNET_CONSTANTS_SERVICE_TIMEOUT, &process_cont, uc);
+ uc->chk = *chk;
}
@@ -221,7 +223,7 @@ process_fs_response (void *cls, const struct GNUNET_MessageHeader *msg)
if (uc->client != NULL)
{
- GNUNET_CLIENT_disconnect (uc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (uc->client);
uc->client = NULL;
}
if (uc->state != UNINDEX_STATE_FS_NOTIFY)
@@ -258,16 +260,15 @@ process_fs_response (void *cls, const struct GNUNET_MessageHeader *msg)
/**
- * Function called when the tree encoder has
- * processed all blocks. Clean up.
+ * Function called when we are done with removing KBlocks.
+ * Disconnect from datastore and notify FS service about
+ * the unindex event.
*
- * @param cls our unindexing context
- * @param tc not used
+ * @param uc our unindexing context
*/
static void
-unindex_finish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+unindex_finish (struct GNUNET_FS_UnindexContext *uc)
{
- struct GNUNET_FS_UnindexContext *uc = cls;
char *emsg;
struct GNUNET_FS_Uri *uri;
struct UnindexMessage req;
@@ -310,6 +311,297 @@ unindex_finish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
}
+
+/**
+ * Function called by the directory scanner as we extract keywords
+ * that we will need to remove KBlocks.
+ *
+ * @param cls the 'struct GNUNET_FS_UnindexContext *'
+ * @param filename which file we are making progress on
+ * @param is_directory GNUNET_YES if this is a directory,
+ * GNUNET_NO if this is a file
+ * GNUNET_SYSERR if it is neither (or unknown)
+ * @param reason kind of progress we are making
+ */
+static void
+unindex_directory_scan_cb (void *cls,
+ const char *filename,
+ int is_directory,
+ enum GNUNET_FS_DirScannerProgressUpdateReason reason)
+{
+ struct GNUNET_FS_UnindexContext *uc = cls;
+ static struct GNUNET_FS_ShareTreeItem * directory_scan_result;
+
+ switch (reason)
+ {
+ case GNUNET_FS_DIRSCANNER_FINISHED:
+ directory_scan_result = GNUNET_FS_directory_scan_get_result (uc->dscan);
+ uc->dscan = NULL;
+ if (NULL != directory_scan_result->ksk_uri)
+ {
+ uc->ksk_uri = GNUNET_FS_uri_dup (directory_scan_result->ksk_uri);
+ uc->state = UNINDEX_STATE_DS_REMOVE_KBLOCKS;
+ uc->emsg = GNUNET_strdup (_("Failed to get KSKs from directory scan."));
+ GNUNET_FS_unindex_sync_ (uc);
+ GNUNET_FS_unindex_do_remove_kblocks_ (uc);
+ }
+ else
+ {
+ unindex_finish (uc);
+ }
+ GNUNET_FS_share_tree_free (directory_scan_result);
+ break;
+ case GNUNET_FS_DIRSCANNER_INTERNAL_ERROR:
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Internal error scanning `%s'.\n"),
+ uc->filename);
+ break;
+ default:
+ break;
+ }
+
+}
+
+
+/**
+ * If necessary, connect to the datastore and remove the KBlocks.
+ *
+ * @param uc context for the unindex operation.
+ */
+void
+GNUNET_FS_unindex_do_extract_keywords_ (struct GNUNET_FS_UnindexContext *uc)
+{
+ char *ex;
+
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (uc->h->cfg, "FS", "EXTRACTORS", &ex))
+ ex = NULL;
+ uc->dscan = GNUNET_FS_directory_scan_start (uc->filename,
+ GNUNET_NO, ex,
+ &unindex_directory_scan_cb,
+ uc);
+ GNUNET_free_non_null (ex);
+}
+
+
+/**
+ * Continuation called to notify client about result of the remove
+ * operation for the KBlock.
+ *
+ * @param cls the 'struct GNUNET_FS_UnindexContext *'
+ * @param success GNUNET_SYSERR on failure (including timeout/queue drop)
+ * GNUNET_NO if content was already there
+ * GNUNET_YES (or other positive value) on success
+ * @param min_expiration minimum expiration time required for 0-priority content to be stored
+ * by the datacache at this time, zero for unknown, forever if we have no
+ * space for 0-priority content
+ * @param msg NULL on success, otherwise an error message
+ */
+static void
+continue_after_remove (void *cls,
+ int32_t success,
+ struct GNUNET_TIME_Absolute min_expiration,
+ const char *msg)
+{
+ struct GNUNET_FS_UnindexContext *uc = cls;
+
+ uc->dqe = NULL;
+ if (success != GNUNET_YES)
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Failed to remove KBlock: %s\n"),
+ msg);
+ uc->ksk_offset++;
+ GNUNET_FS_unindex_do_remove_kblocks_ (uc);
+}
+
+
+/**
+ * Function called from datastore with result from us looking for
+ * a KBlock. 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) KBlock for a different CHK, means we keep looking for more
+ * 4) KBlock 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 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 KBlock *kb;
+ struct GNUNET_FS_Uri *chk_uri;
+
+ uc->dqe = NULL;
+ if (NULL == data)
+ {
+ /* no result */
+ uc->ksk_offset++;
+ GNUNET_FS_unindex_do_remove_kblocks_ (uc);
+ return;
+ }
+ if (0 == uc->first_uid)
+ {
+ /* remember UID of first result to detect cycles */
+ uc->first_uid = uid;
+ }
+ else if (uid == uc->first_uid)
+ {
+ /* no more additional results */
+ uc->ksk_offset++;
+ GNUNET_FS_unindex_do_remove_kblocks_ (uc);
+ return;
+ }
+ GNUNET_assert (GNUNET_BLOCK_TYPE_FS_KBLOCK == type);
+ if (size < sizeof (struct KBlock))
+ {
+ GNUNET_break (0);
+ goto get_next;
+ }
+ kb = data;
+ {
+ char pt[size - sizeof (struct KBlock)];
+ struct GNUNET_CRYPTO_AesSessionKey skey;
+ struct GNUNET_CRYPTO_AesInitializationVector iv;
+
+ GNUNET_CRYPTO_hash_to_aes_key (&uc->key, &skey, &iv);
+ if (-1 ==
+ GNUNET_CRYPTO_aes_decrypt (&kb[1], size - sizeof (struct KBlock), &skey,
+ &iv, pt))
+ {
+ GNUNET_break (0);
+ goto get_next;
+ }
+ if (NULL == memchr (pt, 0, sizeof (pt)))
+ {
+ GNUNET_break (0);
+ goto get_next;
+ }
+ chk_uri = GNUNET_FS_uri_parse (pt, NULL);
+ if (NULL == chk_uri)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ _("Failed to parse URI `%s' from KBlock!\n"),
+ pt);
+ GNUNET_break (0);
+ 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->query,
+ GNUNET_BLOCK_TYPE_FS_KBLOCK,
+ 0 /* priority */, 1 /* queue size */,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &process_kblock_for_unindex,
+ uc);
+}
+
+
+/**
+ * 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;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
+ struct GNUNET_CRYPTO_RsaPrivateKey *pk;
+
+ 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;
+ }
+ /* FIXME: code duplication with fs_search.c here... */
+ keyword = &uc->ksk_uri->data.ksk.keywords[uc->ksk_offset][1];
+ GNUNET_CRYPTO_hash (keyword, strlen (keyword), &uc->key);
+ pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&uc->key);
+ GNUNET_assert (pk != NULL);
+ GNUNET_CRYPTO_rsa_key_get_public (pk, &pub);
+ GNUNET_CRYPTO_rsa_key_free (pk);
+ GNUNET_CRYPTO_hash (&pub,
+ sizeof (struct
+ GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
+ &uc->query);
+ uc->first_uid = 0;
+ uc->dqe = GNUNET_DATASTORE_get_key (uc->dsh,
+ uc->roff++,
+ &uc->query,
+ GNUNET_BLOCK_TYPE_FS_KBLOCK,
+ 0 /* priority */, 1 /* queue size */,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &process_kblock_for_unindex,
+ uc);
+}
+
+
+/**
+ * Function called when the tree encoder has
+ * processed all blocks. Clean up.
+ *
+ * @param cls our unindexing context
+ * @param tc not used
+ */
+static void
+unindex_extract_keywords (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_FS_UnindexContext *uc = cls;
+
+ uc->state = UNINDEX_STATE_EXTRACT_KEYWORDS;
+ GNUNET_FS_unindex_sync_ (uc);
+ GNUNET_FS_unindex_do_extract_keywords_ (uc);
+}
+
+
/**
* Connect to the datastore and remove the blocks.
*
@@ -318,7 +610,8 @@ unindex_finish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
void
GNUNET_FS_unindex_do_remove_ (struct GNUNET_FS_UnindexContext *uc)
{
- uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg);
+ if (NULL == uc->dsh)
+ uc->dsh = GNUNET_DATASTORE_connect (uc->h->cfg);
if (NULL == uc->dsh)
{
uc->state = UNINDEX_STATE_ERROR;
@@ -343,7 +636,7 @@ GNUNET_FS_unindex_do_remove_ (struct GNUNET_FS_UnindexContext *uc)
uc->tc =
GNUNET_FS_tree_encoder_create (uc->h, uc->file_size, uc, &unindex_reader,
&unindex_process, &unindex_progress,
- &unindex_finish);
+ &unindex_extract_keywords);
GNUNET_FS_tree_encoder_next (uc->tc);
}
@@ -393,14 +686,30 @@ GNUNET_FS_unindex_signal_suspend_ (void *cls)
struct GNUNET_FS_UnindexContext *uc = cls;
struct GNUNET_FS_ProgressInfo pi;
+ /* FIXME: lots of duplication with unindex_stop here! */
+ if (uc->dscan != NULL)
+ {
+ GNUNET_FS_directory_scan_abort (uc->dscan);
+ uc->dscan = NULL;
+ }
+ if (NULL != uc->dqe)
+ {
+ GNUNET_DATASTORE_cancel (uc->dqe);
+ uc->dqe = NULL;
+ }
if (uc->fhc != NULL)
{
GNUNET_CRYPTO_hash_file_cancel (uc->fhc);
uc->fhc = NULL;
}
+ if (NULL != uc->ksk_uri)
+ {
+ GNUNET_FS_uri_destroy (uc->ksk_uri);
+ uc->ksk_uri = NULL;
+ }
if (uc->client != NULL)
{
- GNUNET_CLIENT_disconnect (uc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (uc->client);
uc->client = NULL;
}
if (NULL != uc->dsh)
@@ -447,7 +756,7 @@ GNUNET_FS_unindex_start (struct GNUNET_FS_Handle *h, const char *filename,
struct GNUNET_FS_ProgressInfo pi;
uint64_t size;
- if (GNUNET_OK != GNUNET_DISK_file_size (filename, &size, GNUNET_YES))
+ if (GNUNET_OK != GNUNET_DISK_file_size (filename, &size, GNUNET_YES, GNUNET_YES))
return NULL;
ret = GNUNET_malloc (sizeof (struct GNUNET_FS_UnindexContext));
ret->h = h;
@@ -478,6 +787,16 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc)
{
struct GNUNET_FS_ProgressInfo pi;
+ if (uc->dscan != NULL)
+ {
+ GNUNET_FS_directory_scan_abort (uc->dscan);
+ uc->dscan = NULL;
+ }
+ if (NULL != uc->dqe)
+ {
+ GNUNET_DATASTORE_cancel (uc->dqe);
+ uc->dqe = NULL;
+ }
if (uc->fhc != NULL)
{
GNUNET_CRYPTO_hash_file_cancel (uc->fhc);
@@ -485,7 +804,7 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc)
}
if (uc->client != NULL)
{
- GNUNET_CLIENT_disconnect (uc->client, GNUNET_NO);
+ GNUNET_CLIENT_disconnect (uc->client);
uc->client = NULL;
}
if (NULL != uc->dsh)
@@ -493,6 +812,11 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc)
GNUNET_DATASTORE_disconnect (uc->dsh, GNUNET_NO);
uc->dsh = NULL;
}
+ if (NULL != uc->ksk_uri)
+ {
+ GNUNET_FS_uri_destroy (uc->ksk_uri);
+ uc->ksk_uri = NULL;
+ }
if (NULL != uc->tc)
{
GNUNET_FS_tree_encoder_finish (uc->tc, NULL, NULL);
@@ -517,6 +841,7 @@ GNUNET_FS_unindex_stop (struct GNUNET_FS_UnindexContext *uc)
(uc->state ==
UNINDEX_STATE_COMPLETE) ? uc->file_size : 0);
GNUNET_break (NULL == uc->client_info);
+ GNUNET_free_non_null (uc->emsg);
GNUNET_free (uc->filename);
GNUNET_free (uc);
}
diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c
index 5dfdcb5..0c2d64c 100644
--- a/src/fs/fs_uri.c
+++ b/src/fs/fs_uri.c
@@ -214,7 +214,7 @@ percent_decode_keyword (const char *in, char **emsg)
{
if (out[rpos] == '%')
{
- if (1 != sscanf (&out[rpos + 1], "%2X", &hx))
+ if (1 != SSCANF (&out[rpos + 1], "%2X", &hx))
{
GNUNET_free (out);
*emsg = GNUNET_strdup (_("`%' must be followed by HEX number"));
@@ -1378,14 +1378,16 @@ GNUNET_FS_uri_sks_to_string_fancy (struct GNUNET_CONFIGURATION_Handle *cfg,
{
char *ret;
char *name;
+ char *unique_name;
if (uri->type != sks)
return NULL;
- name = GNUNET_PSEUDONYM_id_to_name (cfg, &uri->data.sks.namespace);
- if (name == NULL)
- return GNUNET_FS_uri_to_string (uri);
- GNUNET_asprintf (&ret, "%s: %s", name, uri->data.sks.identifier);
+ (void) GNUNET_PSEUDONYM_get_info (cfg, &uri->data.sks.namespace,
+ NULL, NULL, &name, NULL);
+ unique_name = GNUNET_PSEUDONYM_name_uniquify (cfg, &uri->data.sks.namespace, name, NULL);
GNUNET_free (name);
+ GNUNET_asprintf (&ret, "%s: %s", unique_name, uri->data.sks.identifier);
+ GNUNET_free (unique_name);
return ret;
}
@@ -1499,6 +1501,10 @@ find_duplicate (const char *s, const char **array, int array_length)
return GNUNET_NO;
}
+
+/**
+ * FIXME: comment
+ */
static char *
normalize_metadata (enum EXTRACTOR_MetaFormat format, const char *data,
size_t data_len)
diff --git a/src/fs/gnunet-directory.c b/src/fs/gnunet-directory.c
index 0721ea9..c722f57 100644
--- a/src/fs/gnunet-directory.c
+++ b/src/fs/gnunet-directory.c
@@ -136,7 +136,7 @@ run (void *cls, char *const *args, const char *cfgfile,
i = 0;
while (NULL != (filename = args[i++]))
{
- if ((GNUNET_OK != GNUNET_DISK_file_size (filename, &size, GNUNET_YES)) ||
+ if ((GNUNET_OK != GNUNET_DISK_file_size (filename, &size, GNUNET_YES, GNUNET_YES)) ||
(NULL ==
(h =
GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
diff --git a/src/fs/gnunet-download.c b/src/fs/gnunet-download.c
index ff10c39..5a66aea 100644
--- a/src/fs/gnunet-download.c
+++ b/src/fs/gnunet-download.c
@@ -90,7 +90,8 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
static void *
progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info)
{
- char *s, *s2;
+ char *s;
+ char *s2;
char *t;
switch (info->status)
diff --git a/src/fs/gnunet-helper-fs-publish.c b/src/fs/gnunet-helper-fs-publish.c
index 4f70464..86b0249 100644
--- a/src/fs/gnunet-helper-fs-publish.c
+++ b/src/fs/gnunet-helper-fs-publish.c
@@ -69,7 +69,8 @@ struct ScanTreeNode
char *filename;
/**
- * Size of the file (if it is a file), in bytes
+ * Size of the file (if it is a file), in bytes.
+ * At the moment it is set to 0 for directories.
*/
uint64_t file_size;
@@ -185,6 +186,11 @@ write_message (uint16_t message_type,
{
struct GNUNET_MessageHeader hdr;
+#if 0
+ fprintf (stderr, "Helper sends %u-byte message of type %u\n",
+ (unsigned int) (sizeof (struct GNUNET_MessageHeader) + data_length),
+ (unsigned int) message_type);
+#endif
hdr.type = htons (message_type);
hdr.size = htons (sizeof (struct GNUNET_MessageHeader) + data_length);
if ( (GNUNET_OK !=
@@ -204,7 +210,8 @@ write_message (uint16_t message_type,
* the scan. Does NOT yet add any metadata.
*
* @param filename file or directory to scan
- * @param dst where to store the resulting share tree item
+ * @param dst where to store the resulting share tree item;
+ * NULL is stored in 'dst' upon recoverable errors (GNUNET_OK is returned)
* @return GNUNET_OK on success, GNUNET_SYSERR on error
*/
static int
@@ -252,6 +259,8 @@ scan_callback (void *cls,
rc->stop = GNUNET_YES;
return GNUNET_SYSERR;
}
+ if (NULL == chld)
+ return GNUNET_OK;
chld->parent = rc->parent;
GNUNET_CONTAINER_DLL_insert (rc->parent->children_head,
rc->parent->children_tail,
@@ -266,7 +275,8 @@ scan_callback (void *cls,
* the scan. Does NOT yet add any metadata.
*
* @param filename file or directory to scan
- * @param dst where to store the resulting share tree item
+ * @param dst where to store the resulting share tree item;
+ * NULL is stored in 'dst' upon recoverable errors (GNUNET_OK is returned)
* @return GNUNET_OK on success, GNUNET_SYSERR on error
*/
static int
@@ -275,8 +285,11 @@ preprocess_file (const char *filename,
{
struct ScanTreeNode *item;
struct stat sbuf;
+ uint64_t fsize = 0;
- if (0 != STAT (filename, &sbuf))
+ if ((0 != STAT (filename, &sbuf)) ||
+ ((!S_ISDIR (sbuf.st_mode)) && (GNUNET_OK != GNUNET_DISK_file_size (
+ filename, &fsize, GNUNET_NO, GNUNET_YES))))
{
/* If the file doesn't exist (or is not stat-able for any other reason)
skip it (but report it), but do continue. */
@@ -284,6 +297,8 @@ preprocess_file (const char *filename,
write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_SKIP_FILE,
filename, strlen (filename) + 1))
return GNUNET_SYSERR;
+ /* recoverable error, store 'NULL' in *dst */
+ *dst = NULL;
return GNUNET_OK;
}
@@ -297,8 +312,8 @@ preprocess_file (const char *filename,
item = GNUNET_malloc (sizeof (struct ScanTreeNode));
item->filename = GNUNET_strdup (filename);
item->is_directory = (S_ISDIR (sbuf.st_mode)) ? GNUNET_YES : GNUNET_NO;
- item->file_size = (uint64_t) sbuf.st_size;
- if (item->is_directory == GNUNET_YES)
+ item->file_size = fsize;
+ if (GNUNET_YES == item->is_directory)
{
struct RecursionContext rc;
@@ -307,7 +322,7 @@ preprocess_file (const char *filename,
GNUNET_DISK_directory_scan (filename,
&scan_callback,
&rc);
- if ( (rc.stop == GNUNET_YES) ||
+ if ( (GNUNET_YES == rc.stop) ||
(GNUNET_OK !=
write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_PROGRESS_DIRECTORY,
"..", 3)) )
@@ -334,7 +349,7 @@ extract_files (struct ScanTreeNode *item)
ssize_t size;
size_t slen;
- if (item->is_directory == GNUNET_YES)
+ if (GNUNET_YES == item->is_directory)
{
/* for directories, we simply only descent, no extraction, no
progress reporting */
@@ -369,8 +384,13 @@ extract_files (struct ScanTreeNode *item)
memcpy (buf, item->filename, slen);
size = GNUNET_CONTAINER_meta_data_serialize (meta,
- &dst, size - slen,
+ &dst, size,
GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
+ if (size < 0)
+ {
+ GNUNET_break (0);
+ size = 0;
+ }
GNUNET_CONTAINER_meta_data_destroy (meta);
if (GNUNET_OK !=
write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_META_DATA,
@@ -407,7 +427,7 @@ int main(int argc,
#endif
/* parse command line */
- if ( (argc != 3) && (argc != 2) )
+ if ( (3 != argc) && (2 != argc) )
{
FPRINTF (stderr,
"%s",
@@ -416,7 +436,7 @@ int main(int argc,
}
filename_expanded = argv[1];
ex = argv[2];
- if ( (ex == NULL) ||
+ if ( (NULL == ex) ||
(0 != strcmp (ex, "-")) )
{
plugins = EXTRACTOR_plugin_add_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY);
@@ -437,14 +457,17 @@ int main(int argc,
if (GNUNET_OK !=
write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_COUNTING_DONE, NULL, 0))
return 3;
- if (GNUNET_OK !=
- extract_files (root))
+ if (NULL != root)
{
- (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR, NULL, 0);
+ if (GNUNET_OK !=
+ extract_files (root))
+ {
+ (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR, NULL, 0);
+ free_tree (root);
+ return 4;
+ }
free_tree (root);
- return 4;
}
- free_tree (root);
/* enable "clean" shutdown by telling parent that we are done */
(void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_FINISHED, NULL, 0);
if (NULL != plugins)
diff --git a/src/fs/gnunet-pseudonym.c b/src/fs/gnunet-pseudonym.c
index 412ddd2..38826d1 100644
--- a/src/fs/gnunet-pseudonym.c
+++ b/src/fs/gnunet-pseudonym.c
@@ -106,20 +106,29 @@ ns_printer (void *cls, const char *name, const GNUNET_HashCode * id)
static int
pseudo_printer (void *cls, const GNUNET_HashCode * pseudonym,
+ const char *name, const char *unique_name,
const struct GNUNET_CONTAINER_MetaData *md, int rating)
{
char *id;
-
- id = GNUNET_PSEUDONYM_id_to_name (cfg, pseudonym);
- if (id == NULL)
+ char *unique_id;
+ int getinfo_result;
+
+ /* While we get a name from the caller, it might be NULL.
+ * GNUNET_PSEUDONYM_get_info () never returns NULL.
+ */
+ getinfo_result = GNUNET_PSEUDONYM_get_info (cfg, pseudonym,
+ NULL, NULL, &id, NULL);
+ if (getinfo_result != GNUNET_OK)
{
GNUNET_break (0);
return GNUNET_OK;
}
- FPRINTF (stdout, "%s (%d):\n", id, rating);
+ unique_id = GNUNET_PSEUDONYM_name_uniquify (cfg, pseudonym, id, NULL);
+ GNUNET_free (id);
+ FPRINTF (stdout, "%s (%d):\n", unique_id, rating);
GNUNET_CONTAINER_meta_data_iterate (md, &EXTRACTOR_meta_data_print, stdout);
FPRINTF (stdout, "%s", "\n");
- GNUNET_free (id);
+ GNUNET_free (unique_id);
return GNUNET_OK;
}
@@ -162,7 +171,8 @@ post_advertising (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
}
else
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Namespace `%s' unknown.\n"),
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ ("Namespace `%s' unknown. Make sure you specify its numeric suffix, if any.\n"),
rating_change);
}
}
diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c
index 50f507d..a1b26db 100644
--- a/src/fs/gnunet-publish.c
+++ b/src/fs/gnunet-publish.c
@@ -291,6 +291,12 @@ publish_inspector (void *cls, struct GNUNET_FS_FileInformation *fi,
}
if (!do_disable_creation_time)
GNUNET_CONTAINER_meta_data_add_publication_date (m);
+ if ( (disable_extractor) &&
+ (NULL != *uri) )
+ {
+ GNUNET_FS_uri_destroy (*uri);
+ *uri = NULL;
+ }
if (extract_only)
{
fn = GNUNET_CONTAINER_meta_data_get_by_type (m,
diff --git a/src/fs/gnunet-service-fs.h b/src/fs/gnunet-service-fs.h
index 5ea73ee..0c796bf 100644
--- a/src/fs/gnunet-service-fs.h
+++ b/src/fs/gnunet-service-fs.h
@@ -129,7 +129,7 @@ struct GetMessage
* Hashcodes of the file(s) we're looking for.
* Details depend on the query type.
*/
- GNUNET_HashCode query GNUNET_PACKED;
+ GNUNET_HashCode query;
/* this is followed by hash codes as specified in the "hash_bitmap";
* after that, an optional bloomfilter (with bits set for replies
diff --git a/src/fs/gnunet-service-fs_indexing.c b/src/fs/gnunet-service-fs_indexing.c
index b563019..e452894 100644
--- a/src/fs/gnunet-service-fs_indexing.c
+++ b/src/fs/gnunet-service-fs_indexing.c
@@ -368,7 +368,7 @@ GNUNET_FS_handle_index_list_get (void *cls, struct GNUNET_SERVER_Client *client,
{
struct GNUNET_SERVER_TransmitContext *tc;
struct IndexInfoMessage *iim;
- char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
+ char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
size_t slen;
const char *fn;
struct IndexInfo *pos;
diff --git a/src/fs/gnunet-service-fs_lc.c b/src/fs/gnunet-service-fs_lc.c
index 36aafdd..20d430e 100644
--- a/src/fs/gnunet-service-fs_lc.c
+++ b/src/fs/gnunet-service-fs_lc.c
@@ -140,7 +140,7 @@ struct GSF_LocalClient
/**
* Context for sending replies.
*/
- struct GNUNET_CONNECTION_TransmitHandle *th;
+ struct GNUNET_SERVER_TransmitHandle *th;
};
@@ -259,7 +259,7 @@ client_response_handler (void *cls, enum GNUNET_BLOCK_EvaluationResult eval,
lc = cr->lc;
msize = sizeof (struct ClientPutMessage) + data_len;
{
- char buf[msize];
+ char buf[msize] GNUNET_ALIGN;
pm = (struct ClientPutMessage *) buf;
pm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_PUT);
@@ -498,7 +498,7 @@ GSF_client_disconnect_handler_ (void *cls, struct GNUNET_SERVER_Client *client)
}
if (pos->th != NULL)
{
- GNUNET_CONNECTION_notify_transmit_ready_cancel (pos->th);
+ GNUNET_SERVER_notify_transmit_ready_cancel (pos->th);
pos->th = NULL;
}
GSF_handle_local_client_disconnect_ (pos);
diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c
index d4b4481..8ca4121 100644
--- a/src/fs/gnunet-service-fs_pr.c
+++ b/src/fs/gnunet-service-fs_pr.c
@@ -1057,7 +1057,7 @@ GSF_dht_lookup_ (struct GSF_PendingRequest *pr)
const void *xquery;
size_t xquery_size;
struct GNUNET_PeerIdentity pi;
- char buf[sizeof (GNUNET_HashCode) * 2];
+ char buf[sizeof (GNUNET_HashCode) * 2] GNUNET_ALIGN;
if (0 != pr->public_data.anonymity_level)
return;
@@ -1082,7 +1082,7 @@ GSF_dht_lookup_ (struct GSF_PendingRequest *pr)
xquery_size += sizeof (struct GNUNET_PeerIdentity);
}
pr->gh =
- GNUNET_DHT_get_start (GSF_dht, GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_DHT_get_start (GSF_dht,
pr->public_data.type, &pr->public_data.query,
5 /* DEFAULT_GET_REPLICATION */ ,
GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
diff --git a/src/fs/gnunet-service-fs_put.c b/src/fs/gnunet-service-fs_put.c
index 3ac6713..463acc0 100644
--- a/src/fs/gnunet-service-fs_put.c
+++ b/src/fs/gnunet-service-fs_put.c
@@ -33,6 +33,11 @@
*/
#define MAX_DHT_PUT_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+/**
+ * How many replicas do we try to create per PUT?
+ */
+#define DEFAULT_PUT_REPLICATION 5
+
/**
* Context for each zero-anonymity iterator.
@@ -51,6 +56,11 @@ struct PutOperator
enum GNUNET_BLOCK_Type dht_put_type;
/**
+ * Handle to PUT operation.
+ */
+ struct GNUNET_DHT_PutHandle *dht_put;
+
+ /**
* ID of task that collects blocks for DHT PUTs.
*/
GNUNET_SCHEDULER_TaskIdentifier dht_task;
@@ -92,20 +102,15 @@ gather_dht_put_blocks (void *cls,
/**
- * Task that is run periodically to obtain blocks for DHT PUTs.
+ * Calculate when to run the next PUT operation and schedule it.
*
- * @param cls type of blocks to gather
- * @param tc scheduler context (unused)
+ * @param po put operator to schedule
*/
static void
-delay_dht_put_blocks (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+schedule_next_put (struct PutOperator *po)
{
- struct PutOperator *po = cls;
struct GNUNET_TIME_Relative delay;
- po->dht_task = GNUNET_SCHEDULER_NO_TASK;
- if (tc != NULL && 0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
if (po->zero_anonymity_count_estimate > 0)
{
delay =
@@ -125,6 +130,42 @@ delay_dht_put_blocks (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
/**
+ * Continuation called after DHT PUT operation has finished.
+ *
+ * @param cls type of blocks to gather
+ * @param success GNUNET_OK if the PUT was transmitted,
+ * GNUNET_NO on timeout,
+ * GNUNET_SYSERR on disconnect from service
+ * after the PUT message was transmitted
+ * (so we don't know if it was received or not)
+ */
+static void
+delay_dht_put_blocks (void *cls, int success)
+{
+ struct PutOperator *po = cls;
+
+ po->dht_put = NULL;
+ schedule_next_put (po);
+}
+
+
+/**
+ * Task that is run periodically to obtain blocks for DHT PUTs.
+ *
+ * @param cls type of blocks to gather
+ * @param tc scheduler context
+ */
+static void
+delay_dht_put_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct PutOperator *po = cls;
+
+ po->dht_task = GNUNET_SCHEDULER_NO_TASK;
+ schedule_next_put (po);
+}
+
+
+/**
* Store content in DHT.
*
* @param cls closure
@@ -151,7 +192,7 @@ process_dht_put_content (void *cls, const GNUNET_HashCode * key, size_t size,
{
po->zero_anonymity_count_estimate = po->current_offset - 1;
po->current_offset = 0;
- po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_blocks, po);
+ po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po);
return;
}
po->zero_anonymity_count_estimate =
@@ -159,10 +200,10 @@ process_dht_put_content (void *cls, const GNUNET_HashCode * key, size_t size,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Retrieved block `%s' of type %u for DHT PUT\n", GNUNET_h2s (key),
type);
- GNUNET_DHT_put (GSF_dht, key, 5 /* DEFAULT_PUT_REPLICATION */ ,
- GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, type, size, data,
- expiration, GNUNET_TIME_UNIT_FOREVER_REL,
- &delay_dht_put_blocks, po);
+ po->dht_put = GNUNET_DHT_put (GSF_dht, key, DEFAULT_PUT_REPLICATION,
+ GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, type, size, data,
+ expiration, GNUNET_TIME_UNIT_FOREVER_REL,
+ &delay_dht_put_blocks, po);
}
@@ -187,7 +228,7 @@ gather_dht_put_blocks (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
po->dht_put_type,
&process_dht_put_content, po);
if (NULL == po->dht_qe)
- po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_blocks, po);
+ po->dht_task = GNUNET_SCHEDULER_add_now (&delay_dht_put_task, po);
}
@@ -226,6 +267,11 @@ GSF_put_done_ ()
GNUNET_SCHEDULER_cancel (po->dht_task);
po->dht_task = GNUNET_SCHEDULER_NO_TASK;
}
+ if (NULL != po->dht_put)
+ {
+ GNUNET_DHT_put_cancel (po->dht_put);
+ po->dht_put = NULL;
+ }
if (NULL != po->dht_qe)
{
GNUNET_DATASTORE_cancel (po->dht_qe);
diff --git a/src/fs/perf_gnunet_service_fs_p2p.c b/src/fs/perf_gnunet_service_fs_p2p.c
index 32dcffa..7b2c044 100644
--- a/src/fs/perf_gnunet_service_fs_p2p.c
+++ b/src/fs/perf_gnunet_service_fs_p2p.c
@@ -191,7 +191,7 @@ do_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
char *fancy;
struct StatMaster *sm;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
+ if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
{
del = GNUNET_TIME_absolute_get_duration (start_time);
if (del.rel_value == 0)
diff --git a/src/fs/test_fs_defaults.conf b/src/fs/test_fs_defaults.conf
index 2bc3d26..fcb888c 100644
--- a/src/fs/test_fs_defaults.conf
+++ b/src/fs/test_fs_defaults.conf
@@ -85,3 +85,6 @@ AUTOSTART = NO
[vpn]
AUTOSTART = NO
+
+[namestore]
+AUTOSTART = NO
diff --git a/src/fs/test_fs_download.c b/src/fs/test_fs_download.c
index 570eab9..2781974 100644
--- a/src/fs/test_fs_download.c
+++ b/src/fs/test_fs_download.c
@@ -118,7 +118,7 @@ abort_download_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_FS_download_stop (download, GNUNET_YES);
download = NULL;
}
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES));
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES, GNUNET_NO));
GNUNET_assert (size == FILESIZE);
GNUNET_DISK_directory_remove (fn);
GNUNET_free (fn);
@@ -268,7 +268,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
diff --git a/src/fs/test_fs_download_indexed.c b/src/fs/test_fs_download_indexed.c
index e8504f1..d16aa97 100644
--- a/src/fs/test_fs_download_indexed.c
+++ b/src/fs/test_fs_download_indexed.c
@@ -42,7 +42,7 @@
/**
* How long until we give up on transmitting the message?
*/
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
/**
* How long should our test-content live?
@@ -75,9 +75,11 @@ static char *fn1;
static int err;
+
static void
timeout_kill_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
+ fprintf (stderr, "Download not fast enough, timeout!\n");
if (download != NULL)
{
GNUNET_FS_download_stop (download, GNUNET_YES);
@@ -102,6 +104,7 @@ abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
}
}
+
static void
stop_fs_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
@@ -109,6 +112,7 @@ stop_fs_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
fs = NULL;
}
+
static void
abort_download_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
@@ -119,7 +123,7 @@ abort_download_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_FS_download_stop (download, GNUNET_YES);
download = NULL;
}
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES));
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES, GNUNET_NO));
GNUNET_assert (size == FILESIZE);
GNUNET_DISK_directory_remove (fn);
GNUNET_free (fn);
@@ -248,9 +252,6 @@ setup_peer (struct PeerContext *p, const char *cfgname)
p->arm_proc =
GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
"gnunet-service-arm",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
"-c", cfgname, NULL);
#endif
GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
@@ -269,7 +270,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
@@ -335,9 +336,6 @@ main (int argc, char *argv[])
"test-fs-download-indexed",
"-c",
"test_fs_download_data.conf",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
NULL
};
struct GNUNET_GETOPT_CommandLineOption options[] = {
@@ -345,11 +343,7 @@ main (int argc, char *argv[])
};
GNUNET_log_setup ("test_fs_download_indexed",
-#if VERBOSE
- "DEBUG",
-#else
"WARNING",
-#endif
NULL);
GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx,
"test-fs-download-indexed", "nohelp", options, &run,
diff --git a/src/fs/test_fs_download_persistence.c b/src/fs/test_fs_download_persistence.c
index bcb1c54..ba776dd 100644
--- a/src/fs/test_fs_download_persistence.c
+++ b/src/fs/test_fs_download_persistence.c
@@ -113,7 +113,7 @@ abort_download_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_FS_download_stop (download, GNUNET_YES);
download = NULL;
}
- GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES));
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_size (fn, &size, GNUNET_YES, GNUNET_NO));
GNUNET_assert (size == FILESIZE);
GNUNET_DISK_directory_remove (fn);
GNUNET_free (fn);
@@ -318,7 +318,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
diff --git a/src/fs/test_fs_list_indexed.c b/src/fs/test_fs_list_indexed.c
index 535f8ef..d046a20 100644
--- a/src/fs/test_fs_list_indexed.c
+++ b/src/fs/test_fs_list_indexed.c
@@ -211,7 +211,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
diff --git a/src/fs/test_fs_namespace.c b/src/fs/test_fs_namespace.c
index d25fd6f..78af1f1 100644
--- a/src/fs/test_fs_namespace.c
+++ b/src/fs/test_fs_namespace.c
@@ -69,9 +69,6 @@ setup_peer (struct PeerContext *p, const char *cfgname)
p->arm_proc =
GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
"gnunet-service-arm",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
"-c", cfgname, NULL);
#endif
GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
@@ -90,7 +87,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
@@ -261,6 +258,13 @@ sks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
char *msg;
struct GNUNET_FS_BlockOptions bo;
+ if (NULL == uri)
+ {
+ fprintf (stderr, "Error publishing: %s\n", emsg);
+ err = 1;
+ GNUNET_FS_stop (fs);
+ return;
+ }
meta = GNUNET_CONTAINER_meta_data_create ();
msg = NULL;
ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg);
@@ -378,9 +382,6 @@ main (int argc, char *argv[])
"test-fs-namespace",
"-c",
"test_fs_namespace_data.conf",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
NULL
};
struct GNUNET_GETOPT_CommandLineOption options[] = {
@@ -388,11 +389,7 @@ main (int argc, char *argv[])
};
GNUNET_log_setup ("test_fs_namespace",
-#if VERBOSE
- "DEBUG",
-#else
"WARNING",
-#endif
NULL);
GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx,
"test-fs-namespace", "nohelp", options, &run, NULL);
diff --git a/src/fs/test_fs_namespace_list_updateable.c b/src/fs/test_fs_namespace_list_updateable.c
index 44775ac..2cec67d 100644
--- a/src/fs/test_fs_namespace_list_updateable.c
+++ b/src/fs/test_fs_namespace_list_updateable.c
@@ -94,7 +94,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
diff --git a/src/fs/test_fs_publish.c b/src/fs/test_fs_publish.c
index e527438..1560f4e 100644
--- a/src/fs/test_fs_publish.c
+++ b/src/fs/test_fs_publish.c
@@ -196,7 +196,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
diff --git a/src/fs/test_fs_publish_persistence.c b/src/fs/test_fs_publish_persistence.c
index 7707eac..7d3bc32 100644
--- a/src/fs/test_fs_publish_persistence.c
+++ b/src/fs/test_fs_publish_persistence.c
@@ -259,7 +259,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
diff --git a/src/fs/test_fs_search.c b/src/fs/test_fs_search.c
index f6c8f00..04c5897 100644
--- a/src/fs/test_fs_search.c
+++ b/src/fs/test_fs_search.c
@@ -176,9 +176,6 @@ setup_peer (struct PeerContext *p, const char *cfgname)
p->arm_proc =
GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
"gnunet-service-arm",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
"-c", cfgname, NULL);
#endif
GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
@@ -197,7 +194,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
@@ -254,9 +251,6 @@ main (int argc, char *argv[])
"test-fs-search",
"-c",
"test_fs_search_data.conf",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
NULL
};
struct GNUNET_GETOPT_CommandLineOption options[] = {
@@ -264,11 +258,7 @@ main (int argc, char *argv[])
};
GNUNET_log_setup ("test_fs_search",
-#if VERBOSE
- "DEBUG",
-#else
"WARNING",
-#endif
NULL);
GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx,
"test-fs-search", "nohelp", options, &run, NULL);
diff --git a/src/fs/test_fs_search_persistence.c b/src/fs/test_fs_search_persistence.c
index 38f88a8..d18b50e 100644
--- a/src/fs/test_fs_search_persistence.c
+++ b/src/fs/test_fs_search_persistence.c
@@ -259,7 +259,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
diff --git a/src/fs/test_fs_search_probes.c b/src/fs/test_fs_search_probes.c
new file mode 100644
index 0000000..b816598
--- /dev/null
+++ b/src/fs/test_fs_search_probes.c
@@ -0,0 +1,268 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 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
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file fs/test_fs_search_probes.c
+ * @brief simple testcase for publish + search operation with probes
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_arm_service.h"
+#include "gnunet_fs_service.h"
+
+#define START_ARM GNUNET_YES
+
+/**
+ * File-size we use for testing.
+ */
+#define FILESIZE 1024
+
+/**
+ * How long until we give up on transmitting the message?
+ */
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
+
+/**
+ * How long should our test-content live?
+ */
+#define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
+
+struct PeerContext
+{
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+ struct GNUNET_PeerIdentity id;
+#if START_ARM
+ struct GNUNET_OS_Process *arm_proc;
+#endif
+};
+
+static struct PeerContext p1;
+
+static struct GNUNET_TIME_Absolute start;
+
+static struct GNUNET_FS_Handle *fs;
+
+static struct GNUNET_FS_SearchContext *search;
+
+static struct GNUNET_FS_PublishContext *publish;
+
+
+static void
+abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ GNUNET_FS_publish_stop (publish);
+ publish = NULL;
+}
+
+
+static void
+abort_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (search != NULL)
+ GNUNET_FS_search_stop (search);
+ search = NULL;
+}
+
+
+static void *
+progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
+{
+ const char *keywords[] = {
+ "down_foo"
+ };
+ struct GNUNET_FS_Uri *kuri;
+
+ switch (event->status)
+ {
+ case GNUNET_FS_STATUS_PUBLISH_PROGRESS:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Publish is progressing (%llu/%llu at level %u off %llu)...\n",
+ (unsigned long long) event->value.publish.completed,
+ (unsigned long long) event->value.publish.size,
+ event->value.publish.specifics.progress.depth,
+ (unsigned long long) event->value.publish.specifics.
+ progress.offset);
+ break;
+ case GNUNET_FS_STATUS_PUBLISH_COMPLETED:
+ kuri = GNUNET_FS_uri_ksk_create_from_args (1, keywords);
+ start = GNUNET_TIME_absolute_get ();
+ search =
+ GNUNET_FS_search_start (fs, kuri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
+ "search");
+ GNUNET_FS_uri_destroy (kuri);
+ GNUNET_assert (search != NULL);
+ break;
+ case GNUNET_FS_STATUS_SEARCH_RESULT:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Search complete.\n");
+ break;
+ case GNUNET_FS_STATUS_PUBLISH_ERROR:
+ FPRINTF (stderr, "Error publishing file: %s\n",
+ event->value.publish.specifics.error.message);
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL,
+ GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+ break;
+ case GNUNET_FS_STATUS_SEARCH_ERROR:
+ FPRINTF (stderr, "Error searching file: %s\n",
+ event->value.search.specifics.error.message);
+ GNUNET_SCHEDULER_add_continuation (&abort_search_task, NULL,
+ GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+ break;
+ case GNUNET_FS_STATUS_PUBLISH_START:
+ GNUNET_assert (0 == strcmp ("publish-context", event->value.publish.cctx));
+ GNUNET_assert (NULL == event->value.publish.pctx);
+ GNUNET_assert (FILESIZE == event->value.publish.size);
+ GNUNET_assert (0 == event->value.publish.completed);
+ GNUNET_assert (1 == event->value.publish.anonymity);
+ break;
+ case GNUNET_FS_STATUS_PUBLISH_STOPPED:
+ GNUNET_assert (publish == event->value.publish.pc);
+ GNUNET_assert (FILESIZE == event->value.publish.size);
+ GNUNET_assert (1 == event->value.publish.anonymity);
+ GNUNET_FS_stop (fs);
+ fs = NULL;
+ break;
+ case GNUNET_FS_STATUS_SEARCH_UPDATE:
+ GNUNET_assert (0 < event->value.search.specifics.update.availability_rank);
+ GNUNET_assert (0 < event->value.search.specifics.update.availability_certainty);
+ GNUNET_SCHEDULER_add_now (&abort_search_task, NULL);
+ break;
+ case GNUNET_FS_STATUS_SEARCH_START:
+ GNUNET_assert (search == NULL);
+ GNUNET_assert (0 == strcmp ("search", event->value.search.cctx));
+ GNUNET_assert (1 == event->value.search.anonymity);
+ break;
+ case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED:
+ break;
+ case GNUNET_FS_STATUS_SEARCH_STOPPED:
+ GNUNET_assert (search == event->value.search.sc);
+ GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL,
+ GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+ break;
+ default:
+ FPRINTF (stderr, "Unexpected event: %d\n", event->status);
+ break;
+ }
+ return NULL;
+}
+
+
+static void
+setup_peer (struct PeerContext *p, const char *cfgname)
+{
+ p->cfg = GNUNET_CONFIGURATION_create ();
+#if START_ARM
+ p->arm_proc =
+ GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm",
+ "-c", cfgname, NULL);
+#endif
+ GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
+}
+
+
+static void
+stop_arm (struct PeerContext *p)
+{
+#if START_ARM
+ if (NULL != p->arm_proc)
+ {
+ if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+ if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK)
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
+ GNUNET_OS_process_get_pid (p->arm_proc));
+ GNUNET_OS_process_destroy (p->arm_proc);
+ p->arm_proc = NULL;
+ }
+#endif
+ GNUNET_CONFIGURATION_destroy (p->cfg);
+}
+
+
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ const char *keywords[] = {
+ "down_foo",
+ "down_bar"
+ };
+ char *buf;
+ struct GNUNET_CONTAINER_MetaData *meta;
+ struct GNUNET_FS_Uri *kuri;
+ struct GNUNET_FS_BlockOptions bo;
+ struct GNUNET_FS_FileInformation *fi;
+ size_t i;
+
+ setup_peer (&p1, "test_fs_search_data.conf");
+ fs = GNUNET_FS_start (cfg, "test-fs-search", &progress_cb, NULL,
+ GNUNET_FS_FLAGS_DO_PROBES,
+ GNUNET_FS_OPTIONS_END);
+ GNUNET_assert (NULL != fs);
+ buf = GNUNET_malloc (FILESIZE);
+ for (i = 0; i < FILESIZE; i++)
+ buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256);
+ meta = GNUNET_CONTAINER_meta_data_create ();
+ kuri = GNUNET_FS_uri_ksk_create_from_args (2, keywords);
+ bo.content_priority = 42;
+ bo.anonymity_level = 1;
+ bo.replication_level = 0;
+ bo.expiration_time = GNUNET_TIME_relative_to_absolute (LIFETIME);
+ fi = GNUNET_FS_file_information_create_from_data (fs, "publish-context",
+ FILESIZE, buf, kuri, meta,
+ GNUNET_NO, &bo);
+ GNUNET_FS_uri_destroy (kuri);
+ GNUNET_CONTAINER_meta_data_destroy (meta);
+ GNUNET_assert (NULL != fi);
+ start = GNUNET_TIME_absolute_get ();
+ publish =
+ GNUNET_FS_publish_start (fs, fi, NULL, NULL, NULL,
+ GNUNET_FS_PUBLISH_OPTION_NONE);
+ GNUNET_assert (publish != NULL);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ char *const argvx[] = {
+ "test-fs-search-probes",
+ "-c",
+ "test_fs_search_data.conf",
+ NULL
+ };
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ GNUNET_log_setup ("test_fs_search_probes",
+ "WARNING",
+ NULL);
+ GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx,
+ "test-fs-search", "nohelp", options, &run, NULL);
+ stop_arm (&p1);
+ GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-search/");
+ return 0;
+}
+
+/* end of test_fs_search_probes.c */
diff --git a/src/fs/test_fs_start_stop.c b/src/fs/test_fs_start_stop.c
index 0ef0723..6bd698a 100644
--- a/src/fs/test_fs_start_stop.c
+++ b/src/fs/test_fs_start_stop.c
@@ -80,7 +80,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
diff --git a/src/fs/test_fs_test_lib.c b/src/fs/test_fs_test_lib.c
index 589abb3..29d5fe4 100644
--- a/src/fs/test_fs_test_lib.c
+++ b/src/fs/test_fs_test_lib.c
@@ -138,9 +138,6 @@ main (int argc, char *argv[])
"test-fs-test-lib",
"-c",
"fs_test_lib_data.conf",
-#if VERBOSE
- "-L", "DEBUG",
-#endif
NULL
};
struct GNUNET_GETOPT_CommandLineOption options[] = {
@@ -149,11 +146,7 @@ main (int argc, char *argv[])
GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/");
GNUNET_log_setup ("test_fs_test_lib",
-#if VERBOSE
- "DEBUG",
-#else
"WARNING",
-#endif
NULL);
GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx,
"test-fs-test-lib", "nohelp", options, &run, NULL);
diff --git a/src/fs/test_fs_unindex.c b/src/fs/test_fs_unindex.c
index a8b68a3..ee76bf9 100644
--- a/src/fs/test_fs_unindex.c
+++ b/src/fs/test_fs_unindex.c
@@ -210,7 +210,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
diff --git a/src/fs/test_fs_unindex_persistence.c b/src/fs/test_fs_unindex_persistence.c
index 575e171..c6b1062 100644
--- a/src/fs/test_fs_unindex_persistence.c
+++ b/src/fs/test_fs_unindex_persistence.c
@@ -272,7 +272,7 @@ stop_arm (struct PeerContext *p)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
GNUNET_OS_process_get_pid (p->arm_proc));
- GNUNET_OS_process_close (p->arm_proc);
+ GNUNET_OS_process_destroy (p->arm_proc);
p->arm_proc = NULL;
}
#endif
diff --git a/src/fs/test_gnunet_fs_idx.py.in b/src/fs/test_gnunet_fs_idx.py.in
index 6bb7d0d..6bb7d0d 100755..100644
--- a/src/fs/test_gnunet_fs_idx.py.in
+++ b/src/fs/test_gnunet_fs_idx.py.in
diff --git a/src/fs/test_gnunet_fs_ns.py.in b/src/fs/test_gnunet_fs_ns.py.in
index ff892b4..ff892b4 100755..100644
--- a/src/fs/test_gnunet_fs_ns.py.in
+++ b/src/fs/test_gnunet_fs_ns.py.in
diff --git a/src/fs/test_gnunet_fs_psd.py.in b/src/fs/test_gnunet_fs_psd.py.in
index 9790e13..9790e13 100755..100644
--- a/src/fs/test_gnunet_fs_psd.py.in
+++ b/src/fs/test_gnunet_fs_psd.py.in
diff --git a/src/fs/test_gnunet_fs_rec.py.in b/src/fs/test_gnunet_fs_rec.py.in
index e86bb0a..e86bb0a 100755..100644
--- a/src/fs/test_gnunet_fs_rec.py.in
+++ b/src/fs/test_gnunet_fs_rec.py.in
diff --git a/src/fs/test_gnunet_service_fs_migration.c b/src/fs/test_gnunet_service_fs_migration.c
index 8b85e5e..00aab4f 100644
--- a/src/fs/test_gnunet_service_fs_migration.c
+++ b/src/fs/test_gnunet_service_fs_migration.c
@@ -66,7 +66,7 @@ do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
cc = NULL;
}
GNUNET_FS_TEST_daemons_stop (2, daemons);
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
+ if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
{
del = GNUNET_TIME_absolute_get_duration (start_time);
if (del.rel_value == 0)
@@ -146,7 +146,7 @@ static void
do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
cc = NULL;
- if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
{
GNUNET_FS_TEST_daemons_stop (2, daemons);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/fs/test_gnunet_service_fs_p2p.c b/src/fs/test_gnunet_service_fs_p2p.c
index a853897..7ca786e 100644
--- a/src/fs/test_gnunet_service_fs_p2p.c
+++ b/src/fs/test_gnunet_service_fs_p2p.c
@@ -62,7 +62,7 @@ do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
cc = NULL;
}
GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons);
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
+ if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
{
del = GNUNET_TIME_absolute_get_duration (start_time);
if (del.rel_value == 0)