diff options
author | David Barksdale <amatus.amongus@gmail.com> | 2013-07-22 08:26:16 -0500 |
---|---|---|
committer | David Barksdale <amatus.amongus@gmail.com> | 2013-07-22 08:26:16 -0500 |
commit | 7450bd0b6c6c05ee6425e2c63e9b79beb94bfbfa (patch) | |
tree | dfde89b41437def7ce23af24db53a11a9b5f1075 /src/fs | |
parent | 740b30688bd745a527f96f9116c19acb3480971a (diff) |
Imported Upstream version 0.9.5aupstream
Diffstat (limited to 'src/fs')
94 files changed, 7045 insertions, 3903 deletions
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am index b916e4e..84c0a61 100644 --- a/src/fs/Makefile.am +++ b/src/fs/Makefile.am @@ -11,6 +11,8 @@ endif pkgcfgdir= $(pkgdatadir)/config.d/ +libexecdir= $(pkglibdir)/libexec/ + pkgcfg_DATA = \ fs.conf @@ -50,23 +52,31 @@ libgnunetfs_la_LIBADD = \ libgnunetfs_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 2:1:0 + -version-info 3:0:1 libgnunetfstest_a_SOURCES = \ fs_test_lib.c fs_test_lib.h libgnunetfstest_a_LIBADD = \ - $(top_builddir)/src/testing/libgnunettesting.la + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la + +libexec_PROGRAMS = \ + gnunet-helper-fs-publish \ + gnunet-service-fs + +noinst_PROGRAMS = \ + gnunet-fs-profiler \ + gnunet-daemon-fsprofiler bin_PROGRAMS = \ + gnunet-auto-share \ gnunet-directory \ gnunet-download \ gnunet-publish \ - gnunet-helper-fs-publish \ gnunet-pseudonym \ gnunet-search \ - gnunet-service-fs \ gnunet-fs \ gnunet-unindex @@ -83,6 +93,13 @@ gnunet_directory_LDADD = \ gnunet_directory_DEPENDENCIES = \ libgnunetfs.la +gnunet_fs_profiler_SOURCES = \ + gnunet-fs-profiler.c +gnunet_fs_profiler_LDADD = \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) + gnunet_fs_SOURCES = \ gnunet-fs.c gnunet_fs_LDADD = \ @@ -112,6 +129,15 @@ gnunet_publish_LDADD = \ gnunet_publish_DEPENDENCIES = \ libgnunetfs.la +gnunet_auto_share_SOURCES = \ + gnunet-auto-share.c +gnunet_auto_share_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + -lextractor \ + $(GN_LIBINTL) +gnunet_auto_share_DEPENDENCIES = \ + libgnunetfs.la + gnunet_helper_fs_publish_SOURCES = \ gnunet-helper-fs-publish.c gnunet_helper_fs_publish_LDADD = \ @@ -141,6 +167,16 @@ gnunet_search_LDADD = \ gnunet_search_DEPENDENCIES = \ libgnunetfs.la +gnunet_daemon_fsprofiler_SOURCES = \ + gnunet-daemon-fsprofiler.c +gnunet_daemon_fsprofiler_LDADD = \ + $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) +gnunet_daemon_fsprofiler_DEPENDENCIES = \ + libgnunetfs.la + gnunet_service_fs_SOURCES = \ gnunet-service-fs.c gnunet-service-fs.h \ gnunet-service-fs_cp.c gnunet-service-fs_cp.h \ @@ -149,13 +185,15 @@ gnunet_service_fs_SOURCES = \ gnunet-service-fs_pe.c gnunet-service-fs_pe.h \ gnunet-service-fs_pr.c gnunet-service-fs_pr.h \ gnunet-service-fs_push.c gnunet-service-fs_push.h \ - gnunet-service-fs_put.c gnunet-service-fs_put.h + gnunet-service-fs_put.c gnunet-service-fs_put.h \ + gnunet-service-fs_stream.c gnunet-service-fs_stream.h gnunet_service_fs_LDADD = \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/dht/libgnunetdht.la \ $(top_builddir)/src/block/libgnunetblock.la \ $(top_builddir)/src/datastore/libgnunetdatastore.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/stream/libgnunetstream.la \ $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -177,7 +215,8 @@ libgnunet_plugin_block_fs_la_SOURCES = \ plugin_block_fs.c libgnunet_plugin_block_fs_la_LIBADD = \ $(top_builddir)/src/block/libgnunetblock.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_block_fs_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) libgnunet_plugin_block_fs_la_DEPENDENCIES = \ @@ -190,12 +229,14 @@ if HAVE_BENCHMARKS perf_gnunet_service_fs_p2p \ perf_gnunet_service_fs_p2p_dht \ perf_gnunet_service_fs_p2p_index \ - perf_gnunet_service_fs_p2p_trust + perf_gnunet_service_fs_p2p_respect endif check_PROGRAMS = \ + test_plugin_block_fs \ test_fs_directory \ test_fs_download \ + test_fs_download_stream \ test_fs_download_indexed \ test_fs_download_persistence \ test_fs_file_information \ @@ -215,10 +256,16 @@ check_PROGRAMS = \ test_fs_uri \ test_gnunet_service_fs_migration \ test_gnunet_service_fs_p2p \ + test_gnunet_service_fs_p2p_stream \ $(FS_BENCHMARKS) +test_plugin_block_fs_SOURCES = \ + test_plugin_block_fs.c +test_plugin_block_fs_LDADD = \ + $(top_builddir)/src/block/libgnunetblock.la \ + $(top_builddir)/src/util/libgnunetutil.la -if HAVE_PYTHON_PEXPECT +if HAVE_PYTHON check_SCRIPTS = \ test_gnunet_fs_psd.py \ test_gnunet_fs_rec.py \ @@ -254,15 +301,14 @@ TESTS = \ test_fs_test_lib \ test_gnunet_service_fs_migration \ test_gnunet_service_fs_p2p \ + test_gnunet_service_fs_p2p_stream \ perf_gnunet_service_fs_p2p \ perf_gnunet_service_fs_p2p_index \ - perf_gnunet_service_fs_p2p_trust \ + perf_gnunet_service_fs_p2p_respect \ $(check_SCRIPTS) endif - - test_fs_directory_SOURCES = \ test_fs_directory.c test_fs_directory_LDADD = \ @@ -273,18 +319,28 @@ test_fs_directory_LDADD = \ test_fs_download_SOURCES = \ test_fs_download.c test_fs_download_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_download_indexed_SOURCES = \ - test_fs_download_indexed.c + test_fs_download.c test_fs_download_indexed_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_fs_download_stream_SOURCES = \ + test_fs_download.c +test_fs_download_stream_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_download_persistence_SOURCES = \ test_fs_download_persistence.c test_fs_download_persistence_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -304,64 +360,78 @@ test_fs_getopt_LDADD = \ test_fs_list_indexed_SOURCES = \ test_fs_list_indexed.c test_fs_list_indexed_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_namespace_SOURCES = \ test_fs_namespace.c test_fs_namespace_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_namespace_list_updateable_SOURCES = \ test_fs_namespace_list_updateable.c test_fs_namespace_list_updateable_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_publish_SOURCES = \ test_fs_publish.c test_fs_publish_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_publish_persistence_SOURCES = \ test_fs_publish_persistence.c test_fs_publish_persistence_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_search_SOURCES = \ test_fs_search.c -test_fs_search_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \ +test_fs_search_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(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 \ +test_fs_search_probes_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(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 \ +test_fs_search_persistence_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_start_stop_SOURCES = \ test_fs_start_stop.c test_fs_start_stop_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_unindex_SOURCES = \ test_fs_unindex.c test_fs_unindex_LDADD = \ - $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_unindex_persistence_SOURCES = \ test_fs_unindex_persistence.c test_fs_unindex_persistence_LDADD = \ - $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_uri_SOURCES = \ @@ -374,7 +444,7 @@ test_fs_test_lib_SOURCES = \ test_fs_test_lib.c test_fs_test_lib_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -382,7 +452,15 @@ test_gnunet_service_fs_p2p_SOURCES = \ test_gnunet_service_fs_p2p.c test_gnunet_service_fs_p2p_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_gnunet_service_fs_p2p_stream_SOURCES = \ + test_gnunet_service_fs_p2p.c +test_gnunet_service_fs_p2p_stream_LDADD = \ + $(top_builddir)/src/fs/libgnunetfstest.a \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -390,7 +468,7 @@ test_gnunet_service_fs_migration_SOURCES = \ test_gnunet_service_fs_migration.c test_gnunet_service_fs_migration_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -399,7 +477,7 @@ perf_gnunet_service_fs_p2p_SOURCES = \ perf_gnunet_service_fs_p2p_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -408,7 +486,7 @@ perf_gnunet_service_fs_p2p_index_SOURCES = \ perf_gnunet_service_fs_p2p_index_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -417,16 +495,16 @@ perf_gnunet_service_fs_p2p_dht_SOURCES = \ perf_gnunet_service_fs_p2p_dht_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la -perf_gnunet_service_fs_p2p_trust_SOURCES = \ - perf_gnunet_service_fs_p2p_trust.c -perf_gnunet_service_fs_p2p_trust_LDADD = \ +perf_gnunet_service_fs_p2p_respect_SOURCES = \ + perf_gnunet_service_fs_p2p_respect.c +perf_gnunet_service_fs_p2p_respect_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -455,6 +533,8 @@ EXTRA_DIST = \ fs_test_lib_data.conf \ test_fs_data.conf \ test_fs_download_data.conf \ + test_fs_download_indexed.conf \ + test_fs_download_stream.conf \ test_fs_file_information_data.conf \ fs_test_lib_data.conf \ test_fs_list_indexed_data.conf \ @@ -464,10 +544,12 @@ EXTRA_DIST = \ test_fs_unindex_data.conf \ test_fs_uri_data.conf \ test_gnunet_service_fs_migration_data.conf \ + test_gnunet_service_fs_p2p_stream.conf \ test_gnunet_fs_idx_data.conf \ test_gnunet_fs_ns_data.conf \ test_gnunet_fs_psd_data.conf \ test_gnunet_fs_rec_data.conf \ + perf_gnunet_service_fs_p2p.conf \ test_gnunet_fs_rec_data.tgz \ test_gnunet_fs_psd.py.in \ test_gnunet_fs_rec.py.in \ diff --git a/src/fs/Makefile.in b/src/fs/Makefile.in index 1dc8dba..2f24490 100644 --- a/src/fs/Makefile.in +++ b/src/fs/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -20,6 +20,23 @@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -39,12 +56,17 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -bin_PROGRAMS = gnunet-directory$(EXEEXT) gnunet-download$(EXEEXT) \ - gnunet-publish$(EXEEXT) gnunet-helper-fs-publish$(EXEEXT) \ +libexec_PROGRAMS = gnunet-helper-fs-publish$(EXEEXT) \ + gnunet-service-fs$(EXEEXT) +noinst_PROGRAMS = gnunet-fs-profiler$(EXEEXT) \ + gnunet-daemon-fsprofiler$(EXEEXT) +bin_PROGRAMS = gnunet-auto-share$(EXEEXT) gnunet-directory$(EXEEXT) \ + gnunet-download$(EXEEXT) gnunet-publish$(EXEEXT) \ gnunet-pseudonym$(EXEEXT) gnunet-search$(EXEEXT) \ - gnunet-service-fs$(EXEEXT) gnunet-fs$(EXEEXT) \ - gnunet-unindex$(EXEEXT) -check_PROGRAMS = test_fs_directory$(EXEEXT) test_fs_download$(EXEEXT) \ + gnunet-fs$(EXEEXT) gnunet-unindex$(EXEEXT) +check_PROGRAMS = test_plugin_block_fs$(EXEEXT) \ + test_fs_directory$(EXEEXT) test_fs_download$(EXEEXT) \ + test_fs_download_stream$(EXEEXT) \ test_fs_download_indexed$(EXEEXT) \ test_fs_download_persistence$(EXEEXT) \ test_fs_file_information$(EXEEXT) test_fs_getopt$(EXEEXT) \ @@ -56,7 +78,8 @@ check_PROGRAMS = test_fs_directory$(EXEEXT) test_fs_download$(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) \ - test_gnunet_service_fs_p2p$(EXEEXT) $(am__EXEEXT_1) + test_gnunet_service_fs_p2p$(EXEEXT) \ + test_gnunet_service_fs_p2p_stream$(EXEEXT) $(am__EXEEXT_1) @ENABLE_TEST_RUN_TRUE@TESTS = test_fs_directory$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_fs_download$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_fs_download_indexed$(EXEEXT) \ @@ -77,9 +100,10 @@ check_PROGRAMS = test_fs_directory$(EXEEXT) test_fs_download$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_fs_test_lib$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_gnunet_service_fs_migration$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_gnunet_service_fs_p2p$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_gnunet_service_fs_p2p_stream$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ perf_gnunet_service_fs_p2p$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ perf_gnunet_service_fs_p2p_index$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ perf_gnunet_service_fs_p2p_trust$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ perf_gnunet_service_fs_p2p_respect$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ $(check_SCRIPTS) subdir = src/fs DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ @@ -87,14 +111,15 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \ $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \ - $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glib-2.0.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/libunistring.m4 \ + $(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ @@ -105,15 +130,16 @@ CONFIG_CLEAN_FILES = fs.conf CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru -AM_V_AR = $(am__v_AR_$(V)) -am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY)) +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ libgnunetfstest_a_AR = $(AR) $(ARFLAGS) libgnunetfstest_a_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la am_libgnunetfstest_a_OBJECTS = fs_test_lib.$(OBJEXT) libgnunetfstest_a_OBJECTS = $(am_libgnunetfstest_a_OBJECTS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -137,21 +163,27 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" \ - "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" \ - "$(DESTDIR)$(pkgcfgdir)" + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" \ + "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = am_libgnunet_plugin_block_fs_la_OBJECTS = plugin_block_fs.lo libgnunet_plugin_block_fs_la_OBJECTS = \ $(am_libgnunet_plugin_block_fs_la_OBJECTS) -AM_V_lt = $(am__v_lt_$(V)) -am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent libgnunet_plugin_block_fs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgnunet_plugin_block_fs_la_LDFLAGS) \ $(LDFLAGS) -o $@ -am__DEPENDENCIES_1 = libgnunetfs_la_DEPENDENCIES = \ $(top_builddir)/src/datastore/libgnunetdatastore.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -171,14 +203,26 @@ libgnunetfs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @HAVE_BENCHMARKS_TRUE@ perf_gnunet_service_fs_p2p$(EXEEXT) \ @HAVE_BENCHMARKS_TRUE@ perf_gnunet_service_fs_p2p_dht$(EXEEXT) \ @HAVE_BENCHMARKS_TRUE@ perf_gnunet_service_fs_p2p_index$(EXEEXT) \ -@HAVE_BENCHMARKS_TRUE@ perf_gnunet_service_fs_p2p_trust$(EXEEXT) -PROGRAMS = $(bin_PROGRAMS) +@HAVE_BENCHMARKS_TRUE@ perf_gnunet_service_fs_p2p_respect$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) $(noinst_PROGRAMS) +am_gnunet_auto_share_OBJECTS = gnunet-auto-share.$(OBJEXT) +gnunet_auto_share_OBJECTS = $(am_gnunet_auto_share_OBJECTS) +am_gnunet_daemon_fsprofiler_OBJECTS = \ + gnunet-daemon-fsprofiler.$(OBJEXT) +gnunet_daemon_fsprofiler_OBJECTS = \ + $(am_gnunet_daemon_fsprofiler_OBJECTS) am_gnunet_directory_OBJECTS = gnunet-directory.$(OBJEXT) gnunet_directory_OBJECTS = $(am_gnunet_directory_OBJECTS) am_gnunet_download_OBJECTS = gnunet-download.$(OBJEXT) gnunet_download_OBJECTS = $(am_gnunet_download_OBJECTS) am_gnunet_fs_OBJECTS = gnunet-fs.$(OBJEXT) gnunet_fs_OBJECTS = $(am_gnunet_fs_OBJECTS) +am_gnunet_fs_profiler_OBJECTS = gnunet-fs-profiler.$(OBJEXT) +gnunet_fs_profiler_OBJECTS = $(am_gnunet_fs_profiler_OBJECTS) +gnunet_fs_profiler_DEPENDENCIES = \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(am__DEPENDENCIES_1) am_gnunet_helper_fs_publish_OBJECTS = \ gnunet-helper-fs-publish.$(OBJEXT) gnunet_helper_fs_publish_OBJECTS = \ @@ -195,7 +239,8 @@ am_gnunet_service_fs_OBJECTS = gnunet-service-fs.$(OBJEXT) \ gnunet-service-fs_lc.$(OBJEXT) gnunet-service-fs_pe.$(OBJEXT) \ gnunet-service-fs_pr.$(OBJEXT) \ gnunet-service-fs_push.$(OBJEXT) \ - gnunet-service-fs_put.$(OBJEXT) + gnunet-service-fs_put.$(OBJEXT) \ + gnunet-service-fs_stream.$(OBJEXT) gnunet_service_fs_OBJECTS = $(am_gnunet_service_fs_OBJECTS) am_gnunet_unindex_OBJECTS = gnunet-unindex.$(OBJEXT) gnunet_unindex_OBJECTS = $(am_gnunet_unindex_OBJECTS) @@ -206,7 +251,7 @@ perf_gnunet_service_fs_p2p_OBJECTS = \ perf_gnunet_service_fs_p2p_DEPENDENCIES = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_perf_gnunet_service_fs_p2p_dht_OBJECTS = \ @@ -216,7 +261,7 @@ perf_gnunet_service_fs_p2p_dht_OBJECTS = \ perf_gnunet_service_fs_p2p_dht_DEPENDENCIES = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_perf_gnunet_service_fs_p2p_index_OBJECTS = \ @@ -226,17 +271,17 @@ perf_gnunet_service_fs_p2p_index_OBJECTS = \ perf_gnunet_service_fs_p2p_index_DEPENDENCIES = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la -am_perf_gnunet_service_fs_p2p_trust_OBJECTS = \ - perf_gnunet_service_fs_p2p_trust.$(OBJEXT) -perf_gnunet_service_fs_p2p_trust_OBJECTS = \ - $(am_perf_gnunet_service_fs_p2p_trust_OBJECTS) -perf_gnunet_service_fs_p2p_trust_DEPENDENCIES = \ +am_perf_gnunet_service_fs_p2p_respect_OBJECTS = \ + perf_gnunet_service_fs_p2p_respect.$(OBJEXT) +perf_gnunet_service_fs_p2p_respect_OBJECTS = \ + $(am_perf_gnunet_service_fs_p2p_respect_OBJECTS) +perf_gnunet_service_fs_p2p_respect_DEPENDENCIES = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_directory_OBJECTS = test_fs_directory.$(OBJEXT) @@ -246,13 +291,15 @@ test_fs_directory_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_download_OBJECTS = test_fs_download.$(OBJEXT) test_fs_download_OBJECTS = $(am_test_fs_download_OBJECTS) -test_fs_download_DEPENDENCIES = $(top_builddir)/src/fs/libgnunetfs.la \ +test_fs_download_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la -am_test_fs_download_indexed_OBJECTS = \ - test_fs_download_indexed.$(OBJEXT) +am_test_fs_download_indexed_OBJECTS = test_fs_download.$(OBJEXT) test_fs_download_indexed_OBJECTS = \ $(am_test_fs_download_indexed_OBJECTS) test_fs_download_indexed_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_download_persistence_OBJECTS = \ @@ -260,6 +307,14 @@ am_test_fs_download_persistence_OBJECTS = \ test_fs_download_persistence_OBJECTS = \ $(am_test_fs_download_persistence_OBJECTS) test_fs_download_persistence_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/util/libgnunetutil.la +am_test_fs_download_stream_OBJECTS = test_fs_download.$(OBJEXT) +test_fs_download_stream_OBJECTS = \ + $(am_test_fs_download_stream_OBJECTS) +test_fs_download_stream_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_file_information_OBJECTS = \ @@ -276,11 +331,13 @@ test_fs_getopt_DEPENDENCIES = $(top_builddir)/src/fs/libgnunetfs.la \ am_test_fs_list_indexed_OBJECTS = test_fs_list_indexed.$(OBJEXT) test_fs_list_indexed_OBJECTS = $(am_test_fs_list_indexed_OBJECTS) test_fs_list_indexed_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_namespace_OBJECTS = test_fs_namespace.$(OBJEXT) test_fs_namespace_OBJECTS = $(am_test_fs_namespace_OBJECTS) test_fs_namespace_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_namespace_list_updateable_OBJECTS = \ @@ -288,56 +345,68 @@ am_test_fs_namespace_list_updateable_OBJECTS = \ test_fs_namespace_list_updateable_OBJECTS = \ $(am_test_fs_namespace_list_updateable_OBJECTS) test_fs_namespace_list_updateable_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_publish_OBJECTS = test_fs_publish.$(OBJEXT) test_fs_publish_OBJECTS = $(am_test_fs_publish_OBJECTS) -test_fs_publish_DEPENDENCIES = $(top_builddir)/src/fs/libgnunetfs.la \ +test_fs_publish_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_publish_persistence_OBJECTS = \ test_fs_publish_persistence.$(OBJEXT) test_fs_publish_persistence_OBJECTS = \ $(am_test_fs_publish_persistence_OBJECTS) test_fs_publish_persistence_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_search_OBJECTS = test_fs_search.$(OBJEXT) test_fs_search_OBJECTS = $(am_test_fs_search_OBJECTS) -test_fs_search_DEPENDENCIES = $(top_builddir)/src/fs/libgnunetfs.la \ +test_fs_search_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_search_persistence_OBJECTS = \ test_fs_search_persistence.$(OBJEXT) test_fs_search_persistence_OBJECTS = \ $(am_test_fs_search_persistence_OBJECTS) test_fs_search_persistence_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(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/testing/libgnunettesting.la \ $(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 = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_test_lib_OBJECTS = test_fs_test_lib.$(OBJEXT) test_fs_test_lib_OBJECTS = $(am_test_fs_test_lib_OBJECTS) test_fs_test_lib_DEPENDENCIES = \ $(top_builddir)/src/fs/libgnunetfstest.a \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_unindex_OBJECTS = test_fs_unindex.$(OBJEXT) test_fs_unindex_OBJECTS = $(am_test_fs_unindex_OBJECTS) -test_fs_unindex_DEPENDENCIES = $(top_builddir)/src/fs/libgnunetfs.la \ +test_fs_unindex_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_unindex_persistence_OBJECTS = \ test_fs_unindex_persistence.$(OBJEXT) test_fs_unindex_persistence_OBJECTS = \ $(am_test_fs_unindex_persistence_OBJECTS) test_fs_unindex_persistence_DEPENDENCIES = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_fs_uri_OBJECTS = test_fs_uri.$(OBJEXT) @@ -350,7 +419,7 @@ test_gnunet_service_fs_migration_OBJECTS = \ $(am_test_gnunet_service_fs_migration_OBJECTS) test_gnunet_service_fs_migration_DEPENDENCIES = \ $(top_builddir)/src/fs/libgnunetfstest.a \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la am_test_gnunet_service_fs_p2p_OBJECTS = \ @@ -359,9 +428,23 @@ test_gnunet_service_fs_p2p_OBJECTS = \ $(am_test_gnunet_service_fs_p2p_OBJECTS) test_gnunet_service_fs_p2p_DEPENDENCIES = \ $(top_builddir)/src/fs/libgnunetfstest.a \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/util/libgnunetutil.la +am_test_gnunet_service_fs_p2p_stream_OBJECTS = \ + test_gnunet_service_fs_p2p.$(OBJEXT) +test_gnunet_service_fs_p2p_stream_OBJECTS = \ + $(am_test_gnunet_service_fs_p2p_stream_OBJECTS) +test_gnunet_service_fs_p2p_stream_DEPENDENCIES = \ + $(top_builddir)/src/fs/libgnunetfstest.a \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la +am_test_plugin_block_fs_OBJECTS = test_plugin_block_fs.$(OBJEXT) +test_plugin_block_fs_OBJECTS = $(am_test_plugin_block_fs_OBJECTS) +test_plugin_block_fs_DEPENDENCIES = \ + $(top_builddir)/src/block/libgnunetblock.la \ + $(top_builddir)/src/util/libgnunetutil.la SCRIPTS = $(bin_SCRIPTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -373,23 +456,25 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_$(V)) -am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_$(V)) -am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; -AM_V_GEN = $(am__v_GEN_$(V)) -am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libgnunetfstest_a_SOURCES) \ $(libgnunet_plugin_block_fs_la_SOURCES) \ - $(libgnunetfs_la_SOURCES) $(gnunet_directory_SOURCES) \ - $(gnunet_download_SOURCES) $(gnunet_fs_SOURCES) \ + $(libgnunetfs_la_SOURCES) $(gnunet_auto_share_SOURCES) \ + $(gnunet_daemon_fsprofiler_SOURCES) \ + $(gnunet_directory_SOURCES) $(gnunet_download_SOURCES) \ + $(gnunet_fs_SOURCES) $(gnunet_fs_profiler_SOURCES) \ $(gnunet_helper_fs_publish_SOURCES) \ $(gnunet_pseudonym_SOURCES) $(gnunet_publish_SOURCES) \ $(gnunet_search_SOURCES) $(gnunet_service_fs_SOURCES) \ @@ -397,10 +482,11 @@ SOURCES = $(libgnunetfstest_a_SOURCES) \ $(perf_gnunet_service_fs_p2p_SOURCES) \ $(perf_gnunet_service_fs_p2p_dht_SOURCES) \ $(perf_gnunet_service_fs_p2p_index_SOURCES) \ - $(perf_gnunet_service_fs_p2p_trust_SOURCES) \ + $(perf_gnunet_service_fs_p2p_respect_SOURCES) \ $(test_fs_directory_SOURCES) $(test_fs_download_SOURCES) \ $(test_fs_download_indexed_SOURCES) \ $(test_fs_download_persistence_SOURCES) \ + $(test_fs_download_stream_SOURCES) \ $(test_fs_file_information_SOURCES) $(test_fs_getopt_SOURCES) \ $(test_fs_list_indexed_SOURCES) $(test_fs_namespace_SOURCES) \ $(test_fs_namespace_list_updateable_SOURCES) \ @@ -412,11 +498,15 @@ SOURCES = $(libgnunetfstest_a_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) + $(test_gnunet_service_fs_p2p_SOURCES) \ + $(test_gnunet_service_fs_p2p_stream_SOURCES) \ + $(test_plugin_block_fs_SOURCES) DIST_SOURCES = $(libgnunetfstest_a_SOURCES) \ $(libgnunet_plugin_block_fs_la_SOURCES) \ - $(libgnunetfs_la_SOURCES) $(gnunet_directory_SOURCES) \ - $(gnunet_download_SOURCES) $(gnunet_fs_SOURCES) \ + $(libgnunetfs_la_SOURCES) $(gnunet_auto_share_SOURCES) \ + $(gnunet_daemon_fsprofiler_SOURCES) \ + $(gnunet_directory_SOURCES) $(gnunet_download_SOURCES) \ + $(gnunet_fs_SOURCES) $(gnunet_fs_profiler_SOURCES) \ $(gnunet_helper_fs_publish_SOURCES) \ $(gnunet_pseudonym_SOURCES) $(gnunet_publish_SOURCES) \ $(gnunet_search_SOURCES) $(gnunet_service_fs_SOURCES) \ @@ -424,10 +514,11 @@ DIST_SOURCES = $(libgnunetfstest_a_SOURCES) \ $(perf_gnunet_service_fs_p2p_SOURCES) \ $(perf_gnunet_service_fs_p2p_dht_SOURCES) \ $(perf_gnunet_service_fs_p2p_index_SOURCES) \ - $(perf_gnunet_service_fs_p2p_trust_SOURCES) \ + $(perf_gnunet_service_fs_p2p_respect_SOURCES) \ $(test_fs_directory_SOURCES) $(test_fs_download_SOURCES) \ $(test_fs_download_indexed_SOURCES) \ $(test_fs_download_persistence_SOURCES) \ + $(test_fs_download_stream_SOURCES) \ $(test_fs_file_information_SOURCES) $(test_fs_getopt_SOURCES) \ $(test_fs_list_indexed_SOURCES) $(test_fs_namespace_SOURCES) \ $(test_fs_namespace_list_updateable_SOURCES) \ @@ -439,7 +530,14 @@ DIST_SOURCES = $(libgnunetfstest_a_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) + $(test_gnunet_service_fs_p2p_SOURCES) \ + $(test_gnunet_service_fs_p2p_stream_SOURCES) \ + $(test_plugin_block_fs_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac DATA = $(pkgcfg_DATA) ETAGS = etags CTAGS = ctags @@ -481,6 +579,10 @@ EXEEXT = @EXEEXT@ EXT_LIBS = @EXT_LIBS@ EXT_LIB_PATH = @EXT_LIB_PATH@ FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_LIBS = @GLIB_LIBS@ +GLIB_MKENUMS = @GLIB_MKENUMS@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GNUNETDNS_GROUP = @GNUNETDNS_GROUP@ @@ -491,6 +593,7 @@ GN_LIBINTL = @GN_LIBINTL@ GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@ GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@ GN_USER_HOME_DIR = @GN_USER_HOME_DIR@ +GOBJECT_QUERY = @GOBJECT_QUERY@ GREP = @GREP@ HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ INCLTDL = @INCLTDL@ @@ -513,6 +616,8 @@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBGTOP_CFLAGS = @LIBGTOP_CFLAGS@ +LIBGTOP_LIBS = @LIBGTOP_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBLTDL = @LIBLTDL@ @@ -534,6 +639,7 @@ LT_CONFIG_H = @LT_CONFIG_H@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MONKEYPREFIX = @MONKEYPREFIX@ MSGFMT = @MSGFMT@ @@ -543,6 +649,7 @@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ NM = @NM@ NMEDIT = @NMEDIT@ +NSS_DIR = @NSS_DIR@ OBJC = @OBJC@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ @@ -558,6 +665,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@ POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@ POSUB = @POSUB@ @@ -589,6 +697,7 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ @@ -611,6 +720,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ +gitcommand = @gitcommand@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -621,10 +731,9 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ -libexecdir = @libexecdir@ +libexecdir = $(pkglibdir)/libexec/ localedir = @localedir@ localstatedir = @localstatedir@ -lt_ECHO = @lt_ECHO@ ltdl_LIBOBJS = @ltdl_LIBOBJS@ ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ mandir = @mandir@ @@ -642,6 +751,7 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ +svnversioncommand = @svnversioncommand@ sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target = @target@ @@ -692,13 +802,14 @@ libgnunetfs_la_LIBADD = \ libgnunetfs_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 2:1:0 + -version-info 3:0:1 libgnunetfstest_a_SOURCES = \ fs_test_lib.c fs_test_lib.h libgnunetfstest_a_LIBADD = \ - $(top_builddir)/src/testing/libgnunettesting.la + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la bin_SCRIPTS = \ gnunet-download-manager.scm @@ -715,6 +826,14 @@ gnunet_directory_LDADD = \ gnunet_directory_DEPENDENCIES = \ libgnunetfs.la +gnunet_fs_profiler_SOURCES = \ + gnunet-fs-profiler.c + +gnunet_fs_profiler_LDADD = \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) + gnunet_fs_SOURCES = \ gnunet-fs.c @@ -750,6 +869,17 @@ gnunet_publish_LDADD = \ gnunet_publish_DEPENDENCIES = \ libgnunetfs.la +gnunet_auto_share_SOURCES = \ + gnunet-auto-share.c + +gnunet_auto_share_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + -lextractor \ + $(GN_LIBINTL) + +gnunet_auto_share_DEPENDENCIES = \ + libgnunetfs.la + gnunet_helper_fs_publish_SOURCES = \ gnunet-helper-fs-publish.c @@ -785,6 +915,18 @@ gnunet_search_LDADD = \ gnunet_search_DEPENDENCIES = \ libgnunetfs.la +gnunet_daemon_fsprofiler_SOURCES = \ + gnunet-daemon-fsprofiler.c + +gnunet_daemon_fsprofiler_LDADD = \ + $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) + +gnunet_daemon_fsprofiler_DEPENDENCIES = \ + libgnunetfs.la + gnunet_service_fs_SOURCES = \ gnunet-service-fs.c gnunet-service-fs.h \ gnunet-service-fs_cp.c gnunet-service-fs_cp.h \ @@ -793,7 +935,8 @@ gnunet_service_fs_SOURCES = \ gnunet-service-fs_pe.c gnunet-service-fs_pe.h \ gnunet-service-fs_pr.c gnunet-service-fs_pr.h \ gnunet-service-fs_push.c gnunet-service-fs_push.h \ - gnunet-service-fs_put.c gnunet-service-fs_put.h + gnunet-service-fs_put.c gnunet-service-fs_put.h \ + gnunet-service-fs_stream.c gnunet-service-fs_stream.h gnunet_service_fs_LDADD = \ $(top_builddir)/src/fs/libgnunetfs.la \ @@ -801,6 +944,7 @@ gnunet_service_fs_LDADD = \ $(top_builddir)/src/block/libgnunetblock.la \ $(top_builddir)/src/datastore/libgnunetdatastore.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/stream/libgnunetstream.la \ $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -825,7 +969,8 @@ libgnunet_plugin_block_fs_la_SOURCES = \ libgnunet_plugin_block_fs_la_LIBADD = \ $(top_builddir)/src/block/libgnunetblock.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_block_fs_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) @@ -837,13 +982,20 @@ libgnunet_plugin_block_fs_la_DEPENDENCIES = \ @HAVE_BENCHMARKS_TRUE@ perf_gnunet_service_fs_p2p \ @HAVE_BENCHMARKS_TRUE@ perf_gnunet_service_fs_p2p_dht \ @HAVE_BENCHMARKS_TRUE@ perf_gnunet_service_fs_p2p_index \ -@HAVE_BENCHMARKS_TRUE@ perf_gnunet_service_fs_p2p_trust +@HAVE_BENCHMARKS_TRUE@ perf_gnunet_service_fs_p2p_respect -@HAVE_PYTHON_PEXPECT_TRUE@check_SCRIPTS = \ -@HAVE_PYTHON_PEXPECT_TRUE@ test_gnunet_fs_psd.py \ -@HAVE_PYTHON_PEXPECT_TRUE@ test_gnunet_fs_rec.py \ -@HAVE_PYTHON_PEXPECT_TRUE@ test_gnunet_fs_idx.py \ -@HAVE_PYTHON_PEXPECT_TRUE@ test_gnunet_fs_ns.py +test_plugin_block_fs_SOURCES = \ + test_plugin_block_fs.c + +test_plugin_block_fs_LDADD = \ + $(top_builddir)/src/block/libgnunetblock.la \ + $(top_builddir)/src/util/libgnunetutil.la + +@HAVE_PYTHON_TRUE@check_SCRIPTS = \ +@HAVE_PYTHON_TRUE@ test_gnunet_fs_psd.py \ +@HAVE_PYTHON_TRUE@ test_gnunet_fs_rec.py \ +@HAVE_PYTHON_TRUE@ test_gnunet_fs_idx.py \ +@HAVE_PYTHON_TRUE@ test_gnunet_fs_ns.py @ENABLE_MONKEY_TRUE@TESTS_ENVIRONMENT = @MONKEYPREFIX@ @ENABLE_MONKEY_TRUE@AM_LDFLAGS = -no-install @@ -859,13 +1011,23 @@ test_fs_download_SOURCES = \ test_fs_download.c test_fs_download_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_download_indexed_SOURCES = \ - test_fs_download_indexed.c + test_fs_download.c test_fs_download_indexed_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_fs_download_stream_SOURCES = \ + test_fs_download.c + +test_fs_download_stream_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -873,6 +1035,7 @@ test_fs_download_persistence_SOURCES = \ test_fs_download_persistence.c test_fs_download_persistence_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -895,6 +1058,7 @@ test_fs_list_indexed_SOURCES = \ test_fs_list_indexed.c test_fs_list_indexed_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -902,6 +1066,7 @@ test_fs_namespace_SOURCES = \ test_fs_namespace.c test_fs_namespace_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -909,6 +1074,7 @@ test_fs_namespace_list_updateable_SOURCES = \ test_fs_namespace_list_updateable.c test_fs_namespace_list_updateable_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -916,6 +1082,7 @@ test_fs_publish_SOURCES = \ test_fs_publish.c test_fs_publish_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -923,31 +1090,39 @@ test_fs_publish_persistence_SOURCES = \ test_fs_publish_persistence.c test_fs_publish_persistence_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_search_SOURCES = \ test_fs_search.c -test_fs_search_LDADD = $(top_builddir)/src/fs/libgnunetfs.la \ +test_fs_search_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(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 \ +test_fs_search_probes_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(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 \ +test_fs_search_persistence_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_start_stop_SOURCES = \ test_fs_start_stop.c test_fs_start_stop_LDADD = \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -955,14 +1130,16 @@ test_fs_unindex_SOURCES = \ test_fs_unindex.c test_fs_unindex_LDADD = \ - $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_unindex_persistence_SOURCES = \ test_fs_unindex_persistence.c test_fs_unindex_persistence_LDADD = \ - $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la test_fs_uri_SOURCES = \ @@ -977,7 +1154,7 @@ test_fs_test_lib_SOURCES = \ test_fs_test_lib_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -986,7 +1163,16 @@ test_gnunet_service_fs_p2p_SOURCES = \ test_gnunet_service_fs_p2p_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/fs/libgnunetfs.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_gnunet_service_fs_p2p_stream_SOURCES = \ + test_gnunet_service_fs_p2p.c + +test_gnunet_service_fs_p2p_stream_LDADD = \ + $(top_builddir)/src/fs/libgnunetfstest.a \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -995,7 +1181,7 @@ test_gnunet_service_fs_migration_SOURCES = \ test_gnunet_service_fs_migration_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -1005,7 +1191,7 @@ perf_gnunet_service_fs_p2p_SOURCES = \ perf_gnunet_service_fs_p2p_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -1015,7 +1201,7 @@ perf_gnunet_service_fs_p2p_index_SOURCES = \ perf_gnunet_service_fs_p2p_index_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -1025,17 +1211,17 @@ perf_gnunet_service_fs_p2p_dht_SOURCES = \ perf_gnunet_service_fs_p2p_dht_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la -perf_gnunet_service_fs_p2p_trust_SOURCES = \ - perf_gnunet_service_fs_p2p_trust.c +perf_gnunet_service_fs_p2p_respect_SOURCES = \ + perf_gnunet_service_fs_p2p_respect.c -perf_gnunet_service_fs_p2p_trust_LDADD = \ +perf_gnunet_service_fs_p2p_respect_LDADD = \ $(top_builddir)/src/fs/libgnunetfstest.a \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/fs/libgnunetfs.la \ $(top_builddir)/src/util/libgnunetutil.la @@ -1045,6 +1231,8 @@ EXTRA_DIST = \ fs_test_lib_data.conf \ test_fs_data.conf \ test_fs_download_data.conf \ + test_fs_download_indexed.conf \ + test_fs_download_stream.conf \ test_fs_file_information_data.conf \ fs_test_lib_data.conf \ test_fs_list_indexed_data.conf \ @@ -1054,10 +1242,12 @@ EXTRA_DIST = \ test_fs_unindex_data.conf \ test_fs_uri_data.conf \ test_gnunet_service_fs_migration_data.conf \ + test_gnunet_service_fs_p2p_stream.conf \ test_gnunet_fs_idx_data.conf \ test_gnunet_fs_ns_data.conf \ test_gnunet_fs_psd_data.conf \ test_gnunet_fs_rec_data.conf \ + perf_gnunet_service_fs_p2p.conf \ test_gnunet_fs_rec_data.tgz \ test_gnunet_fs_psd.py.in \ test_gnunet_fs_rec.py.in \ @@ -1105,13 +1295,12 @@ fs.conf: $(top_builddir)/config.status $(srcdir)/fs.conf.in clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -libgnunetfstest.a: $(libgnunetfstest_a_OBJECTS) $(libgnunetfstest_a_DEPENDENCIES) +libgnunetfstest.a: $(libgnunetfstest_a_OBJECTS) $(libgnunetfstest_a_DEPENDENCIES) $(EXTRA_libgnunetfstest_a_DEPENDENCIES) $(AM_V_at)-rm -f libgnunetfstest.a $(AM_V_AR)$(libgnunetfstest_a_AR) libgnunetfstest.a $(libgnunetfstest_a_OBJECTS) $(libgnunetfstest_a_LIBADD) $(AM_V_at)$(RANLIB) libgnunetfstest.a install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -1119,6 +1308,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } @@ -1142,7 +1333,6 @@ clean-libLTLIBRARIES: done install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -1150,6 +1340,8 @@ install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } @@ -1171,14 +1363,17 @@ clean-pluginLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libgnunet_plugin_block_fs.la: $(libgnunet_plugin_block_fs_la_OBJECTS) $(libgnunet_plugin_block_fs_la_DEPENDENCIES) +libgnunet_plugin_block_fs.la: $(libgnunet_plugin_block_fs_la_OBJECTS) $(libgnunet_plugin_block_fs_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_block_fs_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunet_plugin_block_fs_la_LINK) -rpath $(plugindir) $(libgnunet_plugin_block_fs_la_OBJECTS) $(libgnunet_plugin_block_fs_la_LIBADD) $(LIBS) -libgnunetfs.la: $(libgnunetfs_la_OBJECTS) $(libgnunetfs_la_DEPENDENCIES) +libgnunetfs.la: $(libgnunetfs_la_OBJECTS) $(libgnunetfs_la_DEPENDENCIES) $(EXTRA_libgnunetfs_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunetfs_la_LINK) -rpath $(libdir) $(libgnunetfs_la_OBJECTS) $(libgnunetfs_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ @@ -1227,112 +1422,188 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -gnunet-directory$(EXEEXT): $(gnunet_directory_OBJECTS) $(gnunet_directory_DEPENDENCIES) +install-libexecPROGRAMS: $(libexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-libexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files + +clean-libexecPROGRAMS: + @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +gnunet-auto-share$(EXEEXT): $(gnunet_auto_share_OBJECTS) $(gnunet_auto_share_DEPENDENCIES) $(EXTRA_gnunet_auto_share_DEPENDENCIES) + @rm -f gnunet-auto-share$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_auto_share_OBJECTS) $(gnunet_auto_share_LDADD) $(LIBS) +gnunet-daemon-fsprofiler$(EXEEXT): $(gnunet_daemon_fsprofiler_OBJECTS) $(gnunet_daemon_fsprofiler_DEPENDENCIES) $(EXTRA_gnunet_daemon_fsprofiler_DEPENDENCIES) + @rm -f gnunet-daemon-fsprofiler$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_daemon_fsprofiler_OBJECTS) $(gnunet_daemon_fsprofiler_LDADD) $(LIBS) +gnunet-directory$(EXEEXT): $(gnunet_directory_OBJECTS) $(gnunet_directory_DEPENDENCIES) $(EXTRA_gnunet_directory_DEPENDENCIES) @rm -f gnunet-directory$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_directory_OBJECTS) $(gnunet_directory_LDADD) $(LIBS) -gnunet-download$(EXEEXT): $(gnunet_download_OBJECTS) $(gnunet_download_DEPENDENCIES) +gnunet-download$(EXEEXT): $(gnunet_download_OBJECTS) $(gnunet_download_DEPENDENCIES) $(EXTRA_gnunet_download_DEPENDENCIES) @rm -f gnunet-download$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_download_OBJECTS) $(gnunet_download_LDADD) $(LIBS) -gnunet-fs$(EXEEXT): $(gnunet_fs_OBJECTS) $(gnunet_fs_DEPENDENCIES) +gnunet-fs$(EXEEXT): $(gnunet_fs_OBJECTS) $(gnunet_fs_DEPENDENCIES) $(EXTRA_gnunet_fs_DEPENDENCIES) @rm -f gnunet-fs$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_fs_OBJECTS) $(gnunet_fs_LDADD) $(LIBS) -gnunet-helper-fs-publish$(EXEEXT): $(gnunet_helper_fs_publish_OBJECTS) $(gnunet_helper_fs_publish_DEPENDENCIES) +gnunet-fs-profiler$(EXEEXT): $(gnunet_fs_profiler_OBJECTS) $(gnunet_fs_profiler_DEPENDENCIES) $(EXTRA_gnunet_fs_profiler_DEPENDENCIES) + @rm -f gnunet-fs-profiler$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_fs_profiler_OBJECTS) $(gnunet_fs_profiler_LDADD) $(LIBS) +gnunet-helper-fs-publish$(EXEEXT): $(gnunet_helper_fs_publish_OBJECTS) $(gnunet_helper_fs_publish_DEPENDENCIES) $(EXTRA_gnunet_helper_fs_publish_DEPENDENCIES) @rm -f gnunet-helper-fs-publish$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_helper_fs_publish_OBJECTS) $(gnunet_helper_fs_publish_LDADD) $(LIBS) -gnunet-pseudonym$(EXEEXT): $(gnunet_pseudonym_OBJECTS) $(gnunet_pseudonym_DEPENDENCIES) +gnunet-pseudonym$(EXEEXT): $(gnunet_pseudonym_OBJECTS) $(gnunet_pseudonym_DEPENDENCIES) $(EXTRA_gnunet_pseudonym_DEPENDENCIES) @rm -f gnunet-pseudonym$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_pseudonym_OBJECTS) $(gnunet_pseudonym_LDADD) $(LIBS) -gnunet-publish$(EXEEXT): $(gnunet_publish_OBJECTS) $(gnunet_publish_DEPENDENCIES) +gnunet-publish$(EXEEXT): $(gnunet_publish_OBJECTS) $(gnunet_publish_DEPENDENCIES) $(EXTRA_gnunet_publish_DEPENDENCIES) @rm -f gnunet-publish$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_publish_OBJECTS) $(gnunet_publish_LDADD) $(LIBS) -gnunet-search$(EXEEXT): $(gnunet_search_OBJECTS) $(gnunet_search_DEPENDENCIES) +gnunet-search$(EXEEXT): $(gnunet_search_OBJECTS) $(gnunet_search_DEPENDENCIES) $(EXTRA_gnunet_search_DEPENDENCIES) @rm -f gnunet-search$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_search_OBJECTS) $(gnunet_search_LDADD) $(LIBS) -gnunet-service-fs$(EXEEXT): $(gnunet_service_fs_OBJECTS) $(gnunet_service_fs_DEPENDENCIES) +gnunet-service-fs$(EXEEXT): $(gnunet_service_fs_OBJECTS) $(gnunet_service_fs_DEPENDENCIES) $(EXTRA_gnunet_service_fs_DEPENDENCIES) @rm -f gnunet-service-fs$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_service_fs_OBJECTS) $(gnunet_service_fs_LDADD) $(LIBS) -gnunet-unindex$(EXEEXT): $(gnunet_unindex_OBJECTS) $(gnunet_unindex_DEPENDENCIES) +gnunet-unindex$(EXEEXT): $(gnunet_unindex_OBJECTS) $(gnunet_unindex_DEPENDENCIES) $(EXTRA_gnunet_unindex_DEPENDENCIES) @rm -f gnunet-unindex$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_unindex_OBJECTS) $(gnunet_unindex_LDADD) $(LIBS) -perf_gnunet_service_fs_p2p$(EXEEXT): $(perf_gnunet_service_fs_p2p_OBJECTS) $(perf_gnunet_service_fs_p2p_DEPENDENCIES) +perf_gnunet_service_fs_p2p$(EXEEXT): $(perf_gnunet_service_fs_p2p_OBJECTS) $(perf_gnunet_service_fs_p2p_DEPENDENCIES) $(EXTRA_perf_gnunet_service_fs_p2p_DEPENDENCIES) @rm -f perf_gnunet_service_fs_p2p$(EXEEXT) $(AM_V_CCLD)$(LINK) $(perf_gnunet_service_fs_p2p_OBJECTS) $(perf_gnunet_service_fs_p2p_LDADD) $(LIBS) -perf_gnunet_service_fs_p2p_dht$(EXEEXT): $(perf_gnunet_service_fs_p2p_dht_OBJECTS) $(perf_gnunet_service_fs_p2p_dht_DEPENDENCIES) +perf_gnunet_service_fs_p2p_dht$(EXEEXT): $(perf_gnunet_service_fs_p2p_dht_OBJECTS) $(perf_gnunet_service_fs_p2p_dht_DEPENDENCIES) $(EXTRA_perf_gnunet_service_fs_p2p_dht_DEPENDENCIES) @rm -f perf_gnunet_service_fs_p2p_dht$(EXEEXT) $(AM_V_CCLD)$(LINK) $(perf_gnunet_service_fs_p2p_dht_OBJECTS) $(perf_gnunet_service_fs_p2p_dht_LDADD) $(LIBS) -perf_gnunet_service_fs_p2p_index$(EXEEXT): $(perf_gnunet_service_fs_p2p_index_OBJECTS) $(perf_gnunet_service_fs_p2p_index_DEPENDENCIES) +perf_gnunet_service_fs_p2p_index$(EXEEXT): $(perf_gnunet_service_fs_p2p_index_OBJECTS) $(perf_gnunet_service_fs_p2p_index_DEPENDENCIES) $(EXTRA_perf_gnunet_service_fs_p2p_index_DEPENDENCIES) @rm -f perf_gnunet_service_fs_p2p_index$(EXEEXT) $(AM_V_CCLD)$(LINK) $(perf_gnunet_service_fs_p2p_index_OBJECTS) $(perf_gnunet_service_fs_p2p_index_LDADD) $(LIBS) -perf_gnunet_service_fs_p2p_trust$(EXEEXT): $(perf_gnunet_service_fs_p2p_trust_OBJECTS) $(perf_gnunet_service_fs_p2p_trust_DEPENDENCIES) - @rm -f perf_gnunet_service_fs_p2p_trust$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(perf_gnunet_service_fs_p2p_trust_OBJECTS) $(perf_gnunet_service_fs_p2p_trust_LDADD) $(LIBS) -test_fs_directory$(EXEEXT): $(test_fs_directory_OBJECTS) $(test_fs_directory_DEPENDENCIES) +perf_gnunet_service_fs_p2p_respect$(EXEEXT): $(perf_gnunet_service_fs_p2p_respect_OBJECTS) $(perf_gnunet_service_fs_p2p_respect_DEPENDENCIES) $(EXTRA_perf_gnunet_service_fs_p2p_respect_DEPENDENCIES) + @rm -f perf_gnunet_service_fs_p2p_respect$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(perf_gnunet_service_fs_p2p_respect_OBJECTS) $(perf_gnunet_service_fs_p2p_respect_LDADD) $(LIBS) +test_fs_directory$(EXEEXT): $(test_fs_directory_OBJECTS) $(test_fs_directory_DEPENDENCIES) $(EXTRA_test_fs_directory_DEPENDENCIES) @rm -f test_fs_directory$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_directory_OBJECTS) $(test_fs_directory_LDADD) $(LIBS) -test_fs_download$(EXEEXT): $(test_fs_download_OBJECTS) $(test_fs_download_DEPENDENCIES) +test_fs_download$(EXEEXT): $(test_fs_download_OBJECTS) $(test_fs_download_DEPENDENCIES) $(EXTRA_test_fs_download_DEPENDENCIES) @rm -f test_fs_download$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_download_OBJECTS) $(test_fs_download_LDADD) $(LIBS) -test_fs_download_indexed$(EXEEXT): $(test_fs_download_indexed_OBJECTS) $(test_fs_download_indexed_DEPENDENCIES) +test_fs_download_indexed$(EXEEXT): $(test_fs_download_indexed_OBJECTS) $(test_fs_download_indexed_DEPENDENCIES) $(EXTRA_test_fs_download_indexed_DEPENDENCIES) @rm -f test_fs_download_indexed$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_download_indexed_OBJECTS) $(test_fs_download_indexed_LDADD) $(LIBS) -test_fs_download_persistence$(EXEEXT): $(test_fs_download_persistence_OBJECTS) $(test_fs_download_persistence_DEPENDENCIES) +test_fs_download_persistence$(EXEEXT): $(test_fs_download_persistence_OBJECTS) $(test_fs_download_persistence_DEPENDENCIES) $(EXTRA_test_fs_download_persistence_DEPENDENCIES) @rm -f test_fs_download_persistence$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_download_persistence_OBJECTS) $(test_fs_download_persistence_LDADD) $(LIBS) -test_fs_file_information$(EXEEXT): $(test_fs_file_information_OBJECTS) $(test_fs_file_information_DEPENDENCIES) +test_fs_download_stream$(EXEEXT): $(test_fs_download_stream_OBJECTS) $(test_fs_download_stream_DEPENDENCIES) $(EXTRA_test_fs_download_stream_DEPENDENCIES) + @rm -f test_fs_download_stream$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_fs_download_stream_OBJECTS) $(test_fs_download_stream_LDADD) $(LIBS) +test_fs_file_information$(EXEEXT): $(test_fs_file_information_OBJECTS) $(test_fs_file_information_DEPENDENCIES) $(EXTRA_test_fs_file_information_DEPENDENCIES) @rm -f test_fs_file_information$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_file_information_OBJECTS) $(test_fs_file_information_LDADD) $(LIBS) -test_fs_getopt$(EXEEXT): $(test_fs_getopt_OBJECTS) $(test_fs_getopt_DEPENDENCIES) +test_fs_getopt$(EXEEXT): $(test_fs_getopt_OBJECTS) $(test_fs_getopt_DEPENDENCIES) $(EXTRA_test_fs_getopt_DEPENDENCIES) @rm -f test_fs_getopt$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_getopt_OBJECTS) $(test_fs_getopt_LDADD) $(LIBS) -test_fs_list_indexed$(EXEEXT): $(test_fs_list_indexed_OBJECTS) $(test_fs_list_indexed_DEPENDENCIES) +test_fs_list_indexed$(EXEEXT): $(test_fs_list_indexed_OBJECTS) $(test_fs_list_indexed_DEPENDENCIES) $(EXTRA_test_fs_list_indexed_DEPENDENCIES) @rm -f test_fs_list_indexed$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_list_indexed_OBJECTS) $(test_fs_list_indexed_LDADD) $(LIBS) -test_fs_namespace$(EXEEXT): $(test_fs_namespace_OBJECTS) $(test_fs_namespace_DEPENDENCIES) +test_fs_namespace$(EXEEXT): $(test_fs_namespace_OBJECTS) $(test_fs_namespace_DEPENDENCIES) $(EXTRA_test_fs_namespace_DEPENDENCIES) @rm -f test_fs_namespace$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_namespace_OBJECTS) $(test_fs_namespace_LDADD) $(LIBS) -test_fs_namespace_list_updateable$(EXEEXT): $(test_fs_namespace_list_updateable_OBJECTS) $(test_fs_namespace_list_updateable_DEPENDENCIES) +test_fs_namespace_list_updateable$(EXEEXT): $(test_fs_namespace_list_updateable_OBJECTS) $(test_fs_namespace_list_updateable_DEPENDENCIES) $(EXTRA_test_fs_namespace_list_updateable_DEPENDENCIES) @rm -f test_fs_namespace_list_updateable$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_namespace_list_updateable_OBJECTS) $(test_fs_namespace_list_updateable_LDADD) $(LIBS) -test_fs_publish$(EXEEXT): $(test_fs_publish_OBJECTS) $(test_fs_publish_DEPENDENCIES) +test_fs_publish$(EXEEXT): $(test_fs_publish_OBJECTS) $(test_fs_publish_DEPENDENCIES) $(EXTRA_test_fs_publish_DEPENDENCIES) @rm -f test_fs_publish$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_publish_OBJECTS) $(test_fs_publish_LDADD) $(LIBS) -test_fs_publish_persistence$(EXEEXT): $(test_fs_publish_persistence_OBJECTS) $(test_fs_publish_persistence_DEPENDENCIES) +test_fs_publish_persistence$(EXEEXT): $(test_fs_publish_persistence_OBJECTS) $(test_fs_publish_persistence_DEPENDENCIES) $(EXTRA_test_fs_publish_persistence_DEPENDENCIES) @rm -f test_fs_publish_persistence$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_publish_persistence_OBJECTS) $(test_fs_publish_persistence_LDADD) $(LIBS) -test_fs_search$(EXEEXT): $(test_fs_search_OBJECTS) $(test_fs_search_DEPENDENCIES) +test_fs_search$(EXEEXT): $(test_fs_search_OBJECTS) $(test_fs_search_DEPENDENCIES) $(EXTRA_test_fs_search_DEPENDENCIES) @rm -f test_fs_search$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_search_OBJECTS) $(test_fs_search_LDADD) $(LIBS) -test_fs_search_persistence$(EXEEXT): $(test_fs_search_persistence_OBJECTS) $(test_fs_search_persistence_DEPENDENCIES) +test_fs_search_persistence$(EXEEXT): $(test_fs_search_persistence_OBJECTS) $(test_fs_search_persistence_DEPENDENCIES) $(EXTRA_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) +test_fs_search_probes$(EXEEXT): $(test_fs_search_probes_OBJECTS) $(test_fs_search_probes_DEPENDENCIES) $(EXTRA_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) +test_fs_start_stop$(EXEEXT): $(test_fs_start_stop_OBJECTS) $(test_fs_start_stop_DEPENDENCIES) $(EXTRA_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) -test_fs_test_lib$(EXEEXT): $(test_fs_test_lib_OBJECTS) $(test_fs_test_lib_DEPENDENCIES) +test_fs_test_lib$(EXEEXT): $(test_fs_test_lib_OBJECTS) $(test_fs_test_lib_DEPENDENCIES) $(EXTRA_test_fs_test_lib_DEPENDENCIES) @rm -f test_fs_test_lib$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_test_lib_OBJECTS) $(test_fs_test_lib_LDADD) $(LIBS) -test_fs_unindex$(EXEEXT): $(test_fs_unindex_OBJECTS) $(test_fs_unindex_DEPENDENCIES) +test_fs_unindex$(EXEEXT): $(test_fs_unindex_OBJECTS) $(test_fs_unindex_DEPENDENCIES) $(EXTRA_test_fs_unindex_DEPENDENCIES) @rm -f test_fs_unindex$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_unindex_OBJECTS) $(test_fs_unindex_LDADD) $(LIBS) -test_fs_unindex_persistence$(EXEEXT): $(test_fs_unindex_persistence_OBJECTS) $(test_fs_unindex_persistence_DEPENDENCIES) +test_fs_unindex_persistence$(EXEEXT): $(test_fs_unindex_persistence_OBJECTS) $(test_fs_unindex_persistence_DEPENDENCIES) $(EXTRA_test_fs_unindex_persistence_DEPENDENCIES) @rm -f test_fs_unindex_persistence$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_unindex_persistence_OBJECTS) $(test_fs_unindex_persistence_LDADD) $(LIBS) -test_fs_uri$(EXEEXT): $(test_fs_uri_OBJECTS) $(test_fs_uri_DEPENDENCIES) +test_fs_uri$(EXEEXT): $(test_fs_uri_OBJECTS) $(test_fs_uri_DEPENDENCIES) $(EXTRA_test_fs_uri_DEPENDENCIES) @rm -f test_fs_uri$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_fs_uri_OBJECTS) $(test_fs_uri_LDADD) $(LIBS) -test_gnunet_service_fs_migration$(EXEEXT): $(test_gnunet_service_fs_migration_OBJECTS) $(test_gnunet_service_fs_migration_DEPENDENCIES) +test_gnunet_service_fs_migration$(EXEEXT): $(test_gnunet_service_fs_migration_OBJECTS) $(test_gnunet_service_fs_migration_DEPENDENCIES) $(EXTRA_test_gnunet_service_fs_migration_DEPENDENCIES) @rm -f test_gnunet_service_fs_migration$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_gnunet_service_fs_migration_OBJECTS) $(test_gnunet_service_fs_migration_LDADD) $(LIBS) -test_gnunet_service_fs_p2p$(EXEEXT): $(test_gnunet_service_fs_p2p_OBJECTS) $(test_gnunet_service_fs_p2p_DEPENDENCIES) +test_gnunet_service_fs_p2p$(EXEEXT): $(test_gnunet_service_fs_p2p_OBJECTS) $(test_gnunet_service_fs_p2p_DEPENDENCIES) $(EXTRA_test_gnunet_service_fs_p2p_DEPENDENCIES) @rm -f test_gnunet_service_fs_p2p$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_gnunet_service_fs_p2p_OBJECTS) $(test_gnunet_service_fs_p2p_LDADD) $(LIBS) +test_gnunet_service_fs_p2p_stream$(EXEEXT): $(test_gnunet_service_fs_p2p_stream_OBJECTS) $(test_gnunet_service_fs_p2p_stream_DEPENDENCIES) $(EXTRA_test_gnunet_service_fs_p2p_stream_DEPENDENCIES) + @rm -f test_gnunet_service_fs_p2p_stream$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gnunet_service_fs_p2p_stream_OBJECTS) $(test_gnunet_service_fs_p2p_stream_LDADD) $(LIBS) +test_plugin_block_fs$(EXEEXT): $(test_plugin_block_fs_OBJECTS) $(test_plugin_block_fs_DEPENDENCIES) $(EXTRA_test_plugin_block_fs_DEPENDENCIES) + @rm -f test_plugin_block_fs$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_plugin_block_fs_OBJECTS) $(test_plugin_block_fs_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ @@ -1360,9 +1631,7 @@ uninstall-binSCRIPTS: @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -1388,8 +1657,11 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs_tree.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs_unindex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs_uri.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-auto-share.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-daemon-fsprofiler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-directory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-download.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-fs-profiler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-fs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-helper-fs-publish.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-pseudonym.Po@am__quote@ @@ -1403,13 +1675,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-fs_pr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-fs_push.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-fs_put.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-fs_stream.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-unindex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf_gnunet_service_fs_p2p.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf_gnunet_service_fs_p2p_trust.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf_gnunet_service_fs_p2p_respect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_block_fs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_directory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_download.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_download_indexed.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_download_persistence.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_file_information.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_getopt.Po@am__quote@ @@ -1428,30 +1700,28 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_fs_uri.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gnunet_service_fs_migration.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gnunet_service_fs_p2p.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_plugin_block_fs.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -1460,8 +1730,11 @@ clean-libtool: -rm -rf .libs _libs install-pkgcfgDATA: $(pkgcfg_DATA) @$(NORMAL_INSTALL) - test -z "$(pkgcfgdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)" @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgcfgdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)" || exit 1; \ + fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ @@ -1475,9 +1748,7 @@ uninstall-pkgcfgDATA: @$(NORMAL_UNINSTALL) @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - echo " ( cd '$(DESTDIR)$(pkgcfgdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(pkgcfgdir)" && rm -f $$files + dir='$(DESTDIR)$(pkgcfgdir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -1612,14 +1883,15 @@ check-TESTS: $(TESTS) fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ - echo "$$grn$$dashes"; \ + col="$$grn"; \ else \ - echo "$$red$$dashes"; \ + col="$$red"; \ fi; \ - echo "$$banner"; \ - test -z "$$skipped" || echo "$$skipped"; \ - test -z "$$report" || echo "$$report"; \ - echo "$$dashes$$std"; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ test "$$failed" -eq 0; \ else :; fi @@ -1662,7 +1934,7 @@ all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) \ install-binPROGRAMS: install-libLTLIBRARIES installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -1675,10 +1947,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: @@ -1694,7 +1971,8 @@ maintainer-clean-generic: clean: clean-am clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-noinstLIBRARIES \ + clean-libLTLIBRARIES clean-libexecPROGRAMS clean-libtool \ + clean-noinstLIBRARIES clean-noinstPROGRAMS \ clean-pluginLTLIBRARIES mostlyclean-am distclean: distclean-am @@ -1722,7 +2000,7 @@ install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-binSCRIPTS \ - install-libLTLIBRARIES + install-libLTLIBRARIES install-libexecPROGRAMS install-html: install-html-am @@ -1763,28 +2041,30 @@ ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ - uninstall-libLTLIBRARIES uninstall-pkgcfgDATA \ - uninstall-pluginLTLIBRARIES + uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS \ + uninstall-pkgcfgDATA uninstall-pluginLTLIBRARIES .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-noinstLIBRARIES \ + clean-libLTLIBRARIES clean-libexecPROGRAMS clean-libtool \ + clean-noinstLIBRARIES clean-noinstPROGRAMS \ clean-pluginLTLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-libtool distclean-tags distdir dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-binSCRIPTS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ - install-info-am install-libLTLIBRARIES install-man install-pdf \ - install-pdf-am install-pkgcfgDATA install-pluginLTLIBRARIES \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-binPROGRAMS \ - uninstall-binSCRIPTS uninstall-libLTLIBRARIES \ + install-info-am install-libLTLIBRARIES install-libexecPROGRAMS \ + install-man install-pdf install-pdf-am install-pkgcfgDATA \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-binSCRIPTS \ + uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS \ uninstall-pkgcfgDATA uninstall-pluginLTLIBRARIES diff --git a/src/fs/fs.conf.in b/src/fs/fs.conf.in index a908b1f..f45a78f 100644 --- a/src/fs/fs.conf.in +++ b/src/fs/fs.conf.in @@ -1,33 +1,71 @@ [fs] AUTOSTART = YES INDEXDB = $SERVICEHOME/fs/idxinfo.lst -TRUST = $SERVICEHOME/fs/credit/ +RESPECT = $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 -CONFIG = $DEFAULTCONFIG BINARY = gnunet-service-fs ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; +# Do we introduce artificial delays? (may improve anonymity) DELAY = YES + +# Do we cache content from other nodes? (may improve anonymity) CONTENT_CACHING = YES + +# Do we send unsolicited data to other nodes if we have excess bandwidth? +# (may improve anonymity, probably not a good idea if content_caching is NO) CONTENT_PUSHING = YES UNIXPATH = /tmp/gnunet-service-fs.sock + +# Do we require users that want to access file-sharing to run this process +# (usually not a good idea) UNIX_MATCH_UID = NO + +# Do we require users that want to access file-sharing to be in the 'gnunet' group? UNIX_MATCH_GID = YES -# DEBUG = YES + +# Maximum number of requests this peer tracks (important for +# memory consumption; 2k RAM/request is not unusual) MAX_PENDING_REQUESTS = 65536 + +# How many requests do we have at most waiting in the queue towards +# the datastore? (important for memory consumption) +DATASTORE_QUEUE_SIZE = 1024 + # Maximum frequency we're allowed to poll the datastore # for content for migration (can be used to reduce # GNUnet's disk-IO rate) MIN_MIGRATION_DELAY = 100 ms + +# For how many neighbouring peers should we allocate hash maps? EXPECTED_NEIGHBOUR_COUNT = 128 # Enable monkey? -PREFIX = @MONKEYPREFIX@ +# PREFIX = @MONKEYPREFIX@ + +# Disable anonymous file-sharing (but keep non-anonymous transfers)? +# This option is mostly for testing. +DISABLE_ANON_TRANSFER = NO + +# Maximum number of non-anonymous transfers this peer will support +# at the same time. Excessive values mostly have the problem that +# the service might use more memory, so we need to bound this at +# some reasonable level. And if we have a very, very large +# number, we probably won't have enough bandwidth to suppor them +# well anyway, so better have a moderate cap. +MAX_STREAM_CLIENTS = 128 + + +[gnunet-auto-share] +BINARY = gnunet-auto-share +# Note: MUST specify path to auto-share directory and CAN specify other options +# to gnunet-auto-share here! +OPTIONS = $SERVICEHOME/fs/share/ diff --git a/src/fs/fs.h b/src/fs/fs.h index 059b892..ffd448d 100644 --- a/src/fs/fs.h +++ b/src/fs/fs.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors) + (C) 2003--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 @@ -55,12 +55,12 @@ struct ContentHashKey /** * Hash of the original content, used for encryption. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /** * Hash of the encrypted content, used for querying. */ - GNUNET_HashCode query; + struct GNUNET_HashCode query; }; @@ -112,7 +112,7 @@ struct IndexStartMessage /** * Hash of the file that we would like to index. */ - GNUNET_HashCode file_id; + struct GNUNET_HashCode file_id; /* this is followed by a 0-terminated * filename of a file with the hash @@ -141,7 +141,7 @@ struct IndexInfoMessage /** * Hash of the indexed file. */ - GNUNET_HashCode file_id; + struct GNUNET_HashCode file_id; /* this is followed by a 0-terminated * filename of a file with the hash @@ -174,7 +174,7 @@ struct UnindexMessage /** * Hash of the file that we will unindex. */ - GNUNET_HashCode file_id; + struct GNUNET_HashCode file_id; }; @@ -245,7 +245,7 @@ struct SearchMessage * <p> * If the request is for a KBLOCK, "target" must be all zeros. */ - GNUNET_HashCode target; + struct GNUNET_HashCode target; /** * Hash of the keyword (aka query) for KBLOCKs; Hash of @@ -253,7 +253,7 @@ struct SearchMessage * and hash of the identifier XORed with the target for * SBLOCKS (aka query). */ - GNUNET_HashCode query; + struct GNUNET_HashCode query; /* this is followed by the hash codes of already-known * results (which should hence be excluded from what @@ -321,6 +321,18 @@ struct ClientPutMessage */ struct GNUNET_TIME_AbsoluteNBO last_transmission; + /** + * How often did we transmit this query before getting an + * answer (estimate). + */ + uint32_t num_transmissions; + + /** + * How much respect did we offer (in total) before getting an + * answer (estimate). + */ + uint32_t respect_offered; + /* this is followed by the actual encrypted content */ }; diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c index 651c174..2770e86 100644 --- a/src/fs/fs_api.c +++ b/src/fs/fs_api.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2009, 2010, 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 @@ -51,7 +51,7 @@ start_job (struct GNUNET_FS_QueueEntry *qe) { GNUNET_assert (NULL == qe->client); qe->client = GNUNET_CLIENT_connect ("fs", qe->h->cfg); - if (qe->client == NULL) + if (NULL == qe->client) { GNUNET_break (0); return; @@ -59,7 +59,12 @@ start_job (struct GNUNET_FS_QueueEntry *qe) qe->start (qe->cls, qe->client); qe->start_times++; qe->h->active_blocks += qe->blocks; + qe->h->active_downloads++; qe->start_time = GNUNET_TIME_absolute_get (); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting job %p (%u active)\n", + qe, + qe->h->active_downloads); GNUNET_CONTAINER_DLL_remove (qe->h->pending_head, qe->h->pending_tail, qe); GNUNET_CONTAINER_DLL_insert_after (qe->h->running_head, qe->h->running_tail, qe->h->running_tail, qe); @@ -77,12 +82,17 @@ stop_job (struct GNUNET_FS_QueueEntry *qe) { qe->client = NULL; qe->stop (qe->cls); + GNUNET_assert (0 < qe->h->active_downloads); qe->h->active_downloads--; qe->h->active_blocks -= qe->blocks; qe->run_time = GNUNET_TIME_relative_add (qe->run_time, GNUNET_TIME_absolute_get_duration (qe->start_time)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Stopping job %p (%u active)\n", + qe, + qe->h->active_downloads); GNUNET_CONTAINER_DLL_remove (qe->h->running_head, qe->h->running_tail, qe); GNUNET_CONTAINER_DLL_insert_after (qe->h->pending_head, qe->h->pending_tail, qe->h->pending_tail, qe); @@ -106,71 +116,180 @@ process_job_queue (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_TIME_Relative restart_at; struct GNUNET_TIME_Relative rst; struct GNUNET_TIME_Absolute end_time; + unsigned int num_downloads_waiting; + unsigned int num_downloads_active; + unsigned int num_downloads_expired; + unsigned int num_probes_active; + unsigned int num_probes_waiting; + unsigned int num_probes_expired; + int num_probes_change; + int num_downloads_change; + int block_limit_hit; h->queue_job = GNUNET_SCHEDULER_NO_TASK; + /* restart_at will be set to the time when it makes sense to + re-evaluate the job queue (unless, of course, jobs complete + or are added, then we'll be triggered immediately */ restart_at = GNUNET_TIME_UNIT_FOREVER_REL; - /* first, see if we can start all the jobs */ - next = h->pending_head; - while (NULL != (qe = next)) + /* first, calculate some basic statistics on pending jobs */ + num_probes_waiting = 0; + num_downloads_waiting = 0; + for (qe = h->pending_head; NULL != qe; qe = qe->next) { - next = qe->next; - if (h->running_head == NULL) - { - start_job (qe); - continue; - } - if ((qe->blocks + h->active_blocks <= h->max_parallel_requests) && - (h->active_downloads < h->max_parallel_downloads)) + switch (qe->priority) { - start_job (qe); - continue; + case GNUNET_FS_QUEUE_PRIORITY_PROBE: + num_probes_waiting++; + break; + case GNUNET_FS_QUEUE_PRIORITY_NORMAL: + num_downloads_waiting++; + break; + default: + GNUNET_break (0); + break; } } - if (h->pending_head == NULL) - return; /* no need to stop anything */ - /* then, check if we should stop some jobs */ + /* now, calculate some basic statistics on running jobs */ + num_probes_active = 0; + num_probes_expired = 0; + num_downloads_active = 0; + num_downloads_expired = 0; next = h->running_head; while (NULL != (qe = next)) { next = qe->next; - run_time = + switch (qe->priority) + { + case GNUNET_FS_QUEUE_PRIORITY_PROBE: + run_time = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2); + end_time = GNUNET_TIME_absolute_add (qe->start_time, run_time); + rst = GNUNET_TIME_absolute_get_remaining (end_time); + if (0 == rst.rel_value) + { + num_probes_expired++; + stop_job (qe); + } + else + { + num_probes_active++; + restart_at = GNUNET_TIME_relative_min (rst, restart_at); + } + break; + case GNUNET_FS_QUEUE_PRIORITY_NORMAL: + run_time = GNUNET_TIME_relative_multiply (h->avg_block_latency, qe->blocks * qe->start_times); - switch (qe->priority) + end_time = GNUNET_TIME_absolute_add (qe->start_time, run_time); + rst = GNUNET_TIME_absolute_get_remaining (end_time); + if (0 == rst.rel_value) { - 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); + num_downloads_expired++; + stop_job (qe); + } + else + { + num_downloads_active++; + restart_at = GNUNET_TIME_relative_min (rst, restart_at); } - 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); - if (rst.rel_value > 0) + break; + default: + GNUNET_break (0); + break; + } + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "PA: %u, PE: %u, PW: %u; DA: %u, DE: %u, DW: %u\n", + num_probes_active, + num_probes_expired, + num_probes_waiting, + num_downloads_active, + num_downloads_expired, + num_downloads_waiting); + /* calculate start/stop decisions */ + if (h->active_downloads + num_downloads_waiting > h->max_parallel_requests) + { + /* stop probes if possible */ + num_probes_change = - num_probes_active; + num_downloads_change = h->max_parallel_requests - h->active_downloads; + } + else + { + /* start all downloads */ + num_downloads_change = num_downloads_waiting; + /* start as many probes as we can */ + num_probes_change = GNUNET_MIN (num_probes_waiting, + h->max_parallel_requests - (h->active_downloads + num_downloads_waiting)); + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Changing %d probes and %d downloads\n", + num_probes_change, + num_downloads_change); + /* actually stop probes */ + next = h->running_head; + while (NULL != (qe = next)) + { + next = qe->next; + if (GNUNET_FS_QUEUE_PRIORITY_PROBE != qe->priority) continue; - stop_job (qe); + if (num_probes_change < 0) + { + stop_job (qe); + num_probes_change++; + if (0 == num_probes_change) + break; + } } - /* finally, start some more tasks if we now have empty slots */ + GNUNET_break (0 <= num_probes_change); + + /* start some more tasks if we now have empty slots */ + block_limit_hit = GNUNET_NO; next = h->pending_head; - while (NULL != (qe = next)) + while ( (NULL != (qe = next)) && + ( (num_probes_change > 0) || + (num_downloads_change > 0) ) ) { next = qe->next; - if ((qe->blocks + h->active_blocks <= h->max_parallel_requests) && - (h->active_downloads < h->max_parallel_downloads)) + switch (qe->priority) { - start_job (qe); - continue; + case GNUNET_FS_QUEUE_PRIORITY_PROBE: + if (num_probes_change > 0) + { + start_job (qe); + num_probes_change--; + run_time = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2); + restart_at = GNUNET_TIME_relative_min (run_time, restart_at); + } + break; + case GNUNET_FS_QUEUE_PRIORITY_NORMAL: + if ( (num_downloads_change > 0) && + ( (qe->blocks + h->active_blocks <= h->max_parallel_requests) || + ( (qe->blocks > h->max_parallel_requests) && + (0 == h->active_downloads) ) ) ) + { + start_job (qe); + num_downloads_change--; + } + else if (num_downloads_change > 0) + block_limit_hit = GNUNET_YES; + break; + default: + GNUNET_break (0); + break; } } + GNUNET_break ( (0 == num_downloads_change) || (GNUNET_YES == block_limit_hit) ); + GNUNET_break (0 == num_probes_change); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "AD: %u, MP: %u; %d probes and %d downloads to start, will run again in %s\n", + h->active_downloads, + h->max_parallel_requests, + num_probes_change, + num_downloads_change, + GNUNET_STRINGS_relative_time_to_string (restart_at, GNUNET_YES)); + + /* make sure we run again */ h->queue_job = GNUNET_SCHEDULER_add_delayed (restart_at, &process_job_queue, h); } @@ -207,24 +326,31 @@ GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, GNUNET_FS_QueueStart start, if (h->queue_job != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (h->queue_job); h->queue_job = GNUNET_SCHEDULER_add_now (&process_job_queue, h); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Queueing job %p\n", + qe); return qe; } /** * Dequeue a job from the queue. - * @param qh handle for the job + * + * @param qe handle for the job */ void -GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qh) +GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qe) { struct GNUNET_FS_Handle *h; - h = qh->h; - if (qh->client != NULL) - stop_job (qh); - GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, qh); - GNUNET_free (qh); + h = qe->h; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Dequeueing job %p\n", + qe); + if (NULL != qe->client) + stop_job (qe); + GNUNET_CONTAINER_DLL_remove (h->pending_head, h->pending_tail, qe); + GNUNET_free (qe); if (h->queue_job != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (h->queue_job); h->queue_job = GNUNET_SCHEDULER_add_now (&process_job_queue, h); @@ -341,9 +467,9 @@ GNUNET_FS_data_reader_file_ (void *cls, uint64_t offset, size_t max, void *buf, return 0; } } - GNUNET_DISK_file_seek (fi->fd, offset, GNUNET_DISK_SEEK_SET); - ret = GNUNET_DISK_file_read (fi->fd, buf, max); - if (-1 == ret) + if ( (GNUNET_SYSERR == + GNUNET_DISK_file_seek (fi->fd, offset, GNUNET_DISK_SEEK_SET)) || + (-1 == (ret = GNUNET_DISK_file_read (fi->fd, buf, max))) ) { GNUNET_asprintf (emsg, _("Could not read file `%s': %s"), fi->filename, STRERROR (errno)); @@ -372,7 +498,7 @@ GNUNET_FS_make_file_reader_context_ (const char *filename) fi = GNUNET_malloc (sizeof (struct FileInfo)); fi->filename = GNUNET_STRINGS_filename_expand (filename); - if (fi->filename == NULL) + if (NULL == fi->filename) { GNUNET_free (fi); return NULL; @@ -409,7 +535,7 @@ GNUNET_FS_data_reader_copy_ (void *cls, uint64_t offset, size_t max, void *buf, if (UINT64_MAX == offset) return 0; - if (max == 0) + if (0 == max) { GNUNET_free_non_null (data); return 0; @@ -496,7 +622,7 @@ get_read_handle (struct GNUNET_FS_Handle *h, const char *ext, const char *ent) struct GNUNET_BIO_ReadHandle *ret; fn = get_serialization_file_name (h, ext, ent); - if (fn == NULL) + if (NULL == fn) return NULL; ret = GNUNET_BIO_read_open (fn); GNUNET_free (fn); @@ -519,13 +645,10 @@ get_write_handle (struct GNUNET_FS_Handle *h, const char *ext, const char *ent) struct GNUNET_BIO_WriteHandle *ret; fn = get_serialization_file_name (h, ext, ent); - if (fn == NULL) - { + if (NULL == fn) return NULL; - } ret = GNUNET_BIO_write_open (fn); - if (ret == NULL) - GNUNET_break (0); + GNUNET_break (NULL != ret); GNUNET_free (fn); return ret; } @@ -548,7 +671,7 @@ get_write_handle_in_dir (struct GNUNET_FS_Handle *h, const char *ext, struct GNUNET_BIO_WriteHandle *ret; fn = get_serialization_file_name_in_dir (h, ext, uni, ent); - if (fn == NULL) + if (NULL == fn) return NULL; ret = GNUNET_BIO_write_open (fn); GNUNET_free (fn); @@ -575,7 +698,7 @@ GNUNET_FS_remove_sync_file_ (struct GNUNET_FS_Handle *h, const char *ext, return; } filename = get_serialization_file_name (h, ext, ent); - if (filename != NULL) + if (NULL != filename) { if (0 != UNLINK (filename)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); @@ -604,12 +727,11 @@ remove_sync_file_in_dir (struct GNUNET_FS_Handle *h, const char *ext, return; } filename = get_serialization_file_name_in_dir (h, ext, uni, ent); - if (filename != NULL) - { - if (0 != UNLINK (filename)) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); - GNUNET_free (filename); - } + if (NULL == filename) + return; + if (0 != UNLINK (filename)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); + GNUNET_free (filename); } @@ -626,12 +748,12 @@ GNUNET_FS_remove_sync_dir_ (struct GNUNET_FS_Handle *h, const char *ext, { char *dn; - if (uni == NULL) + if (NULL == uni) return; dn = get_serialization_file_name_in_dir (h, ext, uni, ""); - if (dn == NULL) + if (NULL == dn) return; - if ((GNUNET_OK == GNUNET_DISK_directory_test (dn)) && + if ((GNUNET_YES == GNUNET_DISK_directory_test (dn, GNUNET_YES)) && (GNUNET_OK != GNUNET_DISK_directory_remove (dn))) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "rmdir", dn); GNUNET_free (dn); @@ -822,7 +944,7 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h, const char *fn, if ((GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size)) || (GNUNET_OK != GNUNET_BIO_read (rh, "fileid", &ret->data.file.file_id, - sizeof (GNUNET_HashCode)))) + sizeof (struct GNUNET_HashCode)))) { GNUNET_break (0); goto cleanup; @@ -844,7 +966,7 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h, const char *fn, if ((GNUNET_OK != GNUNET_BIO_read_int64 (rh, &ret->data.file.file_size)) || (GNUNET_OK != GNUNET_BIO_read (rh, "fileid", &ret->data.file.file_id, - sizeof (GNUNET_HashCode)))) + sizeof (struct GNUNET_HashCode)))) { GNUNET_break (0); goto cleanup; @@ -870,13 +992,13 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h, const char *fn, goto cleanup; } ret->data.dir.dir_size = (uint32_t) dsize; - if (filename != NULL) + if (NULL != filename) { ret->data.dir.entries = deserialize_file_information (h, filename); GNUNET_free (filename); filename = NULL; nxt = ret->data.dir.entries; - while (nxt != NULL) + while (NULL != nxt) { nxt->dir = ret; nxt = nxt->next; @@ -894,7 +1016,7 @@ deserialize_fi_node (struct GNUNET_FS_Handle *h, const char *fn, GNUNET_break (0); goto cleanup; } - if (filename != NULL) + if (NULL != filename) { ret->next = deserialize_file_information (h, filename); GNUNET_free (filename); @@ -927,9 +1049,10 @@ deserialize_file_information (struct GNUNET_FS_Handle *h, const char *filename) struct GNUNET_FS_FileInformation *ret; struct GNUNET_BIO_ReadHandle *rh; char *emsg; + char *fn; rh = get_read_handle (h, GNUNET_FS_SYNC_PATH_FILE_INFO, filename); - if (rh == NULL) + if (NULL == rh) return NULL; ret = deserialize_fi_node (h, filename, rh); if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg)) @@ -939,10 +1062,15 @@ deserialize_file_information (struct GNUNET_FS_Handle *h, const char *filename) filename, emsg); GNUNET_free (emsg); } - if (ret == NULL) + if (NULL == ret) { - if (0 != UNLINK (filename)) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); + fn = get_serialization_file_name (h, GNUNET_FS_SYNC_PATH_FILE_INFO, filename); + if (NULL != fn) + { + if (0 != UNLINK (fn)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); + GNUNET_free (fn); + } } return ret; } @@ -972,7 +1100,7 @@ get_serialization_short_name (const char *fullname) end = nxt + 1; nxt++; } - if ((end == NULL) || (strlen (end) == 0)) + if ((NULL == end) || (0 == strlen (end))) { GNUNET_break (0); return NULL; @@ -1000,7 +1128,7 @@ make_serialization_file_name (struct GNUNET_FS_Handle *h, const char *ext) if (0 == (h->flags & GNUNET_FS_FLAGS_PERSISTENCE)) return NULL; /* persistence not requested */ dn = get_serialization_file_name (h, ext, ""); - if (dn == NULL) + if (NULL == dn) return NULL; if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (dn)) { @@ -1009,7 +1137,7 @@ make_serialization_file_name (struct GNUNET_FS_Handle *h, const char *ext) } fn = GNUNET_DISK_mktemp (dn); GNUNET_free (dn); - if (fn == NULL) + if (NULL == fn) return NULL; /* epic fail */ ret = get_serialization_short_name (fn); GNUNET_free (fn); @@ -1037,7 +1165,7 @@ make_serialization_file_name_in_dir (struct GNUNET_FS_Handle *h, if (0 == (h->flags & GNUNET_FS_FLAGS_PERSISTENCE)) return NULL; /* persistence not requested */ dn = get_serialization_file_name_in_dir (h, ext, uni, ""); - if (dn == NULL) + if (NULL == dn) return NULL; if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (dn)) { @@ -1046,7 +1174,7 @@ make_serialization_file_name_in_dir (struct GNUNET_FS_Handle *h, } fn = GNUNET_DISK_mktemp (dn); GNUNET_free (dn); - if (fn == NULL) + if (NULL == fn) return NULL; /* epic fail */ ret = get_serialization_short_name (fn); GNUNET_free (fn); @@ -1078,7 +1206,7 @@ copy_from_reader (struct GNUNET_BIO_WriteHandle *wh, left = GNUNET_MIN (sizeof (buf), fi->data.file.file_size - off); ret = fi->data.file.reader (fi->data.file.reader_cls, off, left, buf, &emsg); - if (ret == 0) + if (0 == ret) { GNUNET_free (emsg); return GNUNET_SYSERR; @@ -1113,7 +1241,7 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi) return; wh = get_write_handle (fi->h, GNUNET_FS_SYNC_PATH_FILE_INFO, fi->serialization); - if (wh == NULL) + if (NULL == wh) { GNUNET_free (fi->serialization); fi->serialization = NULL; @@ -1129,11 +1257,11 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi) b = 1; else b = 0; - if (fi->keywords != NULL) + if (NULL != fi->keywords) ksks = GNUNET_FS_uri_to_string (fi->keywords); else ksks = NULL; - if (fi->chk_uri != NULL) + if (NULL != fi->chk_uri) chks = GNUNET_FS_uri_to_string (fi->chk_uri); else chks = NULL; @@ -1195,7 +1323,7 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi) if ((GNUNET_OK != GNUNET_BIO_write_int64 (wh, fi->data.file.file_size)) || (GNUNET_OK != GNUNET_BIO_write (wh, &fi->data.file.file_id, - sizeof (GNUNET_HashCode)))) + sizeof (struct GNUNET_HashCode)))) { GNUNET_break (0); goto cleanup; @@ -1236,7 +1364,7 @@ GNUNET_FS_file_information_sync_ (struct GNUNET_FS_FileInformation *fi) } return; /* done! */ cleanup: - if (wh != NULL) + if (NULL != wh) (void) GNUNET_BIO_write_close (wh); GNUNET_free_non_null (chks); GNUNET_free_non_null (ksks); @@ -1267,16 +1395,13 @@ find_file_position (struct GNUNET_FS_FileInformation *pos, const char *srch) { struct GNUNET_FS_FileInformation *r; - while (pos != NULL) + while (NULL != pos) { if (0 == strcmp (srch, pos->serialization)) return pos; - if (pos->is_directory == GNUNET_YES) - { - r = find_file_position (pos->data.dir.entries, srch); - if (r != NULL) - return r; - } + if ( (GNUNET_YES == pos->is_directory) && + (NULL != (r = find_file_position (pos->data.dir.entries, srch))) ) + return r; pos = pos->next; } return NULL; @@ -1354,7 +1479,7 @@ deserialize_publish_file (void *cls, const char *filename) fi_pos = NULL; ns = NULL; rh = GNUNET_BIO_read_open (filename); - if (rh == NULL) + if (NULL == rh) { GNUNET_break (0); goto cleanup; @@ -1380,15 +1505,15 @@ deserialize_publish_file (void *cls, const char *filename) goto cleanup; } pc->fi = deserialize_file_information (h, fi_root); - if (pc->fi == NULL) + if (NULL == pc->fi) { GNUNET_break (0); goto cleanup; } - if (ns != NULL) + if (NULL != ns) { - pc->namespace = GNUNET_FS_namespace_create (h, ns); - if (pc->namespace == NULL) + pc->ns = GNUNET_FS_namespace_create (h, ns); + if (NULL == pc->ns) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ @@ -1404,16 +1529,16 @@ deserialize_publish_file (void *cls, const char *filename) if (NULL == pc->dsh) goto cleanup; } - if (fi_pos != NULL) + if (NULL != fi_pos) { pc->fi_pos = find_file_position (pc->fi, fi_pos); GNUNET_free (fi_pos); fi_pos = NULL; - if (pc->fi_pos == NULL) + if (NULL == pc->fi_pos) { /* failed to find position for resuming, outch! Will start from root! */ GNUNET_break (0); - if (pc->all_done != GNUNET_YES) + if (GNUNET_YES != pc->all_done) pc->fi_pos = pc->fi; } } @@ -1423,7 +1548,7 @@ deserialize_publish_file (void *cls, const char *filename) GNUNET_FS_file_information_inspect (pc->fi, &fip_signal_resume, pc); /* re-start publishing (if needed)... */ - if (pc->all_done != GNUNET_YES) + if (GNUNET_YES != pc->all_done) { GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == pc->upload_task); pc->upload_task = @@ -1447,14 +1572,14 @@ cleanup: GNUNET_free_non_null (fi_root); GNUNET_free_non_null (fi_pos); GNUNET_free_non_null (ns); - if ((rh != NULL) && (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))) + if ((NULL != rh) && (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to resume publishing operation `%s': %s\n"), filename, emsg); GNUNET_free (emsg); } - if (pc->fi != NULL) + if (NULL != pc->fi) GNUNET_FS_file_information_destroy (pc->fi, NULL, NULL); if (0 != UNLINK (filename)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); @@ -1492,7 +1617,7 @@ GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc) } wh = get_write_handle (pc->h, GNUNET_FS_SYNC_PATH_MASTER_PUBLISH, pc->serialization); - if (wh == NULL) + if (NULL == wh) { GNUNET_break (0); goto cleanup; @@ -1504,12 +1629,10 @@ GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc) (GNUNET_OK != GNUNET_BIO_write_string (wh, pc->fi->serialization)) || (GNUNET_OK != GNUNET_BIO_write_string (wh, - (pc->fi_pos == - NULL) ? NULL : pc->fi_pos->serialization)) || + (NULL == pc->fi_pos) ? NULL : pc->fi_pos->serialization)) || (GNUNET_OK != GNUNET_BIO_write_string (wh, - (pc->namespace == - NULL) ? NULL : pc->namespace->name))) + (NULL == pc->ns) ? NULL : pc->ns->name))) { GNUNET_break (0); goto cleanup; @@ -1522,7 +1645,7 @@ GNUNET_FS_publish_sync_ (struct GNUNET_FS_PublishContext *pc) } return; cleanup: - if (wh != NULL) + if (NULL != wh) (void) GNUNET_BIO_write_close (wh); GNUNET_FS_remove_sync_file_ (pc->h, GNUNET_FS_SYNC_PATH_MASTER_PUBLISH, pc->serialization); @@ -1553,7 +1676,7 @@ GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc) return; wh = get_write_handle (uc->h, GNUNET_FS_SYNC_PATH_MASTER_UNINDEX, uc->serialization); - if (wh == NULL) + if (NULL == wh) { GNUNET_break (0); goto cleanup; @@ -1572,7 +1695,7 @@ GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc) (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)))) || + GNUNET_BIO_write (wh, &uc->file_id, sizeof (struct GNUNET_HashCode)))) || ((uc->state == UNINDEX_STATE_ERROR) && (GNUNET_OK != GNUNET_BIO_write_string (wh, uc->emsg)))) { @@ -1587,7 +1710,7 @@ GNUNET_FS_unindex_sync_ (struct GNUNET_FS_UnindexContext *uc) } return; cleanup: - if (wh != NULL) + if (NULL != wh) (void) GNUNET_BIO_write_close (wh); GNUNET_FS_remove_sync_file_ (uc->h, GNUNET_FS_SYNC_PATH_MASTER_UNINDEX, uc->serialization); @@ -1614,7 +1737,7 @@ write_download_request (struct GNUNET_BIO_WriteHandle *wh, (GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->num_children)) || (GNUNET_OK != GNUNET_BIO_write_int32 (wh, dr->depth))) return GNUNET_NO; - if ((dr->state == BRS_CHK_SET) && + if ((BRS_CHK_SET == dr->state) && (GNUNET_OK != GNUNET_BIO_write (wh, &dr->chk, sizeof (struct ContentHashKey)))) return GNUNET_NO; @@ -1638,16 +1761,15 @@ read_download_request (struct GNUNET_BIO_ReadHandle *rh) unsigned int i; dr = GNUNET_malloc (sizeof (struct DownloadRequest)); - if ((GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->state)) || (GNUNET_OK != GNUNET_BIO_read_int64 (rh, &dr->offset)) || (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->num_children)) || (dr->num_children > CHK_PER_INODE) || - (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->depth)) || ((dr->depth == 0) + (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &dr->depth)) || ((0 == dr->depth) && (dr->num_children > 0)) || - ((dr->depth > 0) && (dr->num_children == 0))) + ((dr->depth > 0) && (0 == dr->num_children))) { GNUNET_break (0); dr->num_children = 0; @@ -1655,7 +1777,7 @@ read_download_request (struct GNUNET_BIO_ReadHandle *rh) } if (dr->num_children > 0) dr->children = - GNUNET_malloc (dr->num_children * sizeof (struct ContentHashKey)); + GNUNET_malloc (dr->num_children * sizeof (struct DownloadRequest *)); switch (dr->state) { case BRS_INIT: @@ -1711,10 +1833,10 @@ get_download_sync_filename (struct GNUNET_FS_DownloadContext *dc, GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD : GNUNET_FS_SYNC_PATH_MASTER_DOWNLOAD, uni); - if (dc->parent->serialization == NULL) + if (NULL == dc->parent->serialization) return NULL; par = get_download_sync_filename (dc->parent, dc->parent->serialization, ""); - if (par == NULL) + if (NULL == par) return NULL; GNUNET_asprintf (&epar, "%s.dir%s%s%s", par, DIR_SEPARATOR_STR, uni, ext); GNUNET_free (par); @@ -1743,7 +1865,7 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc) if (NULL == dc->serialization) { dir = get_download_sync_filename (dc, "", ""); - if (dir == NULL) + if (NULL == dir) return; if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (dir)) { @@ -1752,14 +1874,14 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc) } fn = GNUNET_DISK_mktemp (dir); GNUNET_free (dir); - if (fn == NULL) + if (NULL == fn) return; dc->serialization = get_serialization_short_name (fn); } else { fn = get_download_sync_filename (dc, dc->serialization, ""); - if (fn == NULL) + if (NULL == fn) { GNUNET_free (dc->serialization); dc->serialization = NULL; @@ -1768,7 +1890,7 @@ GNUNET_FS_download_sync_ (struct GNUNET_FS_DownloadContext *dc) } } wh = GNUNET_BIO_write_open (fn); - if (wh == NULL) + if (NULL == wh) { GNUNET_free (dc->serialization); dc->serialization = NULL; @@ -1856,7 +1978,7 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr) NULL) ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, sr->sc->serialization, sr->serialization); - if (wh == NULL) + if (NULL == wh) { GNUNET_break (0); goto cleanup; @@ -1872,7 +1994,7 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr) sr->update_search != NULL ? sr->update_search->serialization : NULL)) || (GNUNET_OK != GNUNET_BIO_write_meta_data (wh, sr->meta)) || - (GNUNET_OK != GNUNET_BIO_write (wh, &sr->key, sizeof (GNUNET_HashCode))) + (GNUNET_OK != GNUNET_BIO_write (wh, &sr->key, sizeof (struct GNUNET_HashCode))) || (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->mandatory_missing)) || (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->optional_support)) || (GNUNET_OK != GNUNET_BIO_write_int32 (wh, sr->availability_success)) || @@ -1881,8 +2003,8 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr) GNUNET_break (0); goto cleanup; } - if ( (sr->uri != NULL) && - (sr->sc->uri->type == ksk) && + if ( (NULL != sr->uri) && + (ksk == sr->sc->uri->type) && (GNUNET_OK != GNUNET_BIO_write (wh, sr->keyword_bitmap, (sr->sc->uri->data.ksk.keywordCount + 7) / 8)) ) { @@ -1899,12 +2021,12 @@ GNUNET_FS_search_result_sync_ (struct GNUNET_FS_SearchResult *sr) return; cleanup: GNUNET_free_non_null (uris); - if (wh != NULL) + if (NULL != wh) (void) GNUNET_BIO_write_close (wh); remove_sync_file_in_dir (sr->sc->h, - (sr->sc->psearch_result == - NULL) ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH : - GNUNET_FS_SYNC_PATH_CHILD_SEARCH, + (NULL == sr->sc->psearch_result) + ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH + : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, sr->sc->serialization, sr->serialization); GNUNET_free (sr->serialization); sr->serialization = NULL; @@ -1928,16 +2050,16 @@ GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc) const char *category; category = - (sc->psearch_result == - NULL) ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH : - GNUNET_FS_SYNC_PATH_CHILD_SEARCH; + (NULL == sc->psearch_result) + ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH + : GNUNET_FS_SYNC_PATH_CHILD_SEARCH; if (NULL == sc->serialization) sc->serialization = make_serialization_file_name (sc->h, category); if (NULL == sc->serialization) return; uris = NULL; wh = get_write_handle (sc->h, category, sc->serialization); - if (wh == NULL) + if (NULL == wh) { GNUNET_break (0); goto cleanup; @@ -1966,7 +2088,7 @@ GNUNET_FS_search_sync_ (struct GNUNET_FS_SearchContext *sc) } return; cleanup: - if (wh != NULL) + if (NULL != wh) (void) GNUNET_BIO_write_close (wh); GNUNET_free_non_null (uris); GNUNET_FS_remove_sync_file_ (sc->h, category, sc->serialization); @@ -1998,7 +2120,7 @@ deserialize_unindex_file (void *cls, const char *filename) uc->h = h; uc->serialization = get_serialization_short_name (filename); rh = GNUNET_BIO_read_open (filename); - if (rh == NULL) + if (NULL == rh) { GNUNET_break (0); goto cleanup; @@ -2024,6 +2146,7 @@ deserialize_unindex_file (void *cls, const char *filename) if (NULL == uc->ksk_uri) { GNUNET_break (0); + GNUNET_free_non_null (emsg); goto cleanup; } } @@ -2042,7 +2165,7 @@ deserialize_unindex_file (void *cls, const char *filename) case UNINDEX_STATE_FS_NOTIFY: if (GNUNET_OK != GNUNET_BIO_read (rh, "unindex-hash", &uc->file_id, - sizeof (GNUNET_HashCode))) + sizeof (struct GNUNET_HashCode))) { GNUNET_break (0); goto cleanup; @@ -2110,14 +2233,14 @@ deserialize_unindex_file (void *cls, const char *filename) return GNUNET_OK; cleanup: GNUNET_free_non_null (uc->filename); - if ((rh != NULL) && (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))) + if ((NULL != rh) && (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to resume unindexing operation `%s': %s\n"), filename, emsg); GNUNET_free (emsg); } - if (uc->serialization != NULL) + if (NULL != uc->serialization) GNUNET_FS_remove_sync_file_ (h, GNUNET_FS_SYNC_PATH_MASTER_UNINDEX, uc->serialization); GNUNET_free_non_null (uc->serialization); @@ -2181,14 +2304,14 @@ deserialize_search_result (void *cls, const char *filename) ser = get_serialization_short_name (filename); rh = GNUNET_BIO_read_open (filename); - if (rh == NULL) + if (NULL == rh) { - if (ser != NULL) + if (NULL != ser) { remove_sync_file_in_dir (sc->h, - (sc->psearch_result == - NULL) ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH : - GNUNET_FS_SYNC_PATH_CHILD_SEARCH, + (NULL == sc->psearch_result) + ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH + : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, sc->serialization, ser); GNUNET_free (ser); } @@ -2208,7 +2331,7 @@ deserialize_search_result (void *cls, const char *filename) GNUNET_BIO_read_string (rh, "search-lnk", &update_srch, 16)) || (GNUNET_OK != GNUNET_BIO_read_meta_data (rh, "result-meta", &sr->meta)) || (GNUNET_OK != - GNUNET_BIO_read (rh, "result-key", &sr->key, sizeof (GNUNET_HashCode))) + GNUNET_BIO_read (rh, "result-key", &sr->key, sizeof (struct GNUNET_HashCode))) || (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->mandatory_missing)) || (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->optional_support)) || (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &sr->availability_success)) || @@ -2217,7 +2340,7 @@ deserialize_search_result (void *cls, const char *filename) GNUNET_break (0); goto cleanup; } - if (sr->sc->uri->type == ksk) + if (ksk == sr->sc->uri->type) { sr->keyword_bitmap = GNUNET_malloc ((sr->sc->uri->data.ksk.keywordCount + 7) / 8); /* round up, count bits */ if (GNUNET_OK != GNUNET_BIO_read (rh, "keyword-bitmap", @@ -2229,10 +2352,10 @@ deserialize_search_result (void *cls, const char *filename) } } GNUNET_free (uris); - if (download != NULL) + if (NULL != download) { drh = get_read_handle (sc->h, GNUNET_FS_SYNC_PATH_CHILD_DOWNLOAD, download); - if (drh != NULL) + if (NULL != drh) { deserialize_download (sc->h, drh, NULL, sr, download); if (GNUNET_OK != GNUNET_BIO_read_close (drh, &emsg)) @@ -2245,11 +2368,11 @@ deserialize_search_result (void *cls, const char *filename) } GNUNET_free (download); } - if (update_srch != NULL) + if (NULL != update_srch) { drh = get_read_handle (sc->h, GNUNET_FS_SYNC_PATH_CHILD_SEARCH, update_srch); - if (drh != NULL) + if (NULL != drh) { deserialize_search (sc->h, drh, sr, update_srch); if (GNUNET_OK != GNUNET_BIO_read_close (drh, &emsg)) @@ -2262,8 +2385,9 @@ deserialize_search_result (void *cls, const char *filename) } GNUNET_free (update_srch); } - GNUNET_CONTAINER_multihashmap_put (sc->master_result_map, &sr->key, sr, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + GNUNET_break (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_put (sc->master_result_map, &sr->key, sr, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg)) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -2277,9 +2401,9 @@ cleanup: GNUNET_free_non_null (emsg); GNUNET_free_non_null (uris); GNUNET_free_non_null (update_srch); - if (sr->uri != NULL) + if (NULL != sr->uri) GNUNET_FS_uri_destroy (sr->uri); - if (sr->meta != NULL) + if (NULL != sr->meta) GNUNET_CONTAINER_meta_data_destroy (sr->meta); GNUNET_free (sr->serialization); GNUNET_free (sr); @@ -2318,7 +2442,7 @@ signal_download_resume (struct GNUNET_FS_DownloadContext *dc) signal_download_resume (dcc); dcc = dcc->next; } - if (dc->pending_head != NULL) + if (NULL != dc->pending_head) GNUNET_FS_download_start_downloading_ (dc); } @@ -2343,7 +2467,7 @@ signal_search_resume (struct GNUNET_FS_SearchContext *sc); * @return GNUNET_YES (we should continue to iterate) */ static int -signal_result_resume (void *cls, const GNUNET_HashCode * key, void *value) +signal_result_resume (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GNUNET_FS_SearchContext *sc = cls; struct GNUNET_FS_ProgressInfo pi; @@ -2363,7 +2487,7 @@ signal_result_resume (void *cls, const GNUNET_HashCode * key, void *value) sr->optional_support; sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc); } - if (sr->download != NULL) + if (NULL != sr->download) { signal_download_resume (sr->download); } @@ -2371,7 +2495,7 @@ signal_result_resume (void *cls, const GNUNET_HashCode * key, void *value) { GNUNET_FS_search_start_probe_ (sr); } - if (sr->update_search != NULL) + if (NULL != sr->update_search) signal_search_resume (sr->update_search); return GNUNET_YES; } @@ -2395,11 +2519,11 @@ free_search_context (struct GNUNET_FS_SearchContext *sc); * @return GNUNET_YES (we should continue to iterate) */ static int -free_result (void *cls, const GNUNET_HashCode * key, void *value) +free_result (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GNUNET_FS_SearchResult *sr = value; - if (sr->update_search != NULL) + if (NULL != sr->update_search) { free_search_context (sr->update_search); GNUNET_assert (NULL == sr->update_search); @@ -2419,7 +2543,7 @@ free_result (void *cls, const GNUNET_HashCode * key, void *value) static void free_search_context (struct GNUNET_FS_SearchContext *sc) { - if (sc->serialization != NULL) + if (NULL != sc->serialization) { GNUNET_FS_remove_sync_file_ (sc->h, (sc->psearch_result == @@ -2434,9 +2558,9 @@ free_search_context (struct GNUNET_FS_SearchContext *sc) } GNUNET_free_non_null (sc->serialization); GNUNET_free_non_null (sc->emsg); - if (sc->uri != NULL) + if (NULL != sc->uri) GNUNET_FS_uri_destroy (sc->uri); - if (sc->master_result_map != NULL) + if (NULL != sc->master_result_map) { GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, &free_result, sc); @@ -2464,7 +2588,7 @@ deserialize_subdownload (void *cls, const char *filename) ser = get_serialization_short_name (filename); rh = GNUNET_BIO_read_open (filename); - if (rh == NULL) + if (NULL == rh) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ @@ -2497,9 +2621,9 @@ free_download_context (struct GNUNET_FS_DownloadContext *dc) { struct GNUNET_FS_DownloadContext *dcc; - if (dc->meta != NULL) + if (NULL != dc->meta) GNUNET_CONTAINER_meta_data_destroy (dc->meta); - if (dc->uri != NULL) + if (NULL != dc->uri) GNUNET_FS_uri_destroy (dc->uri); GNUNET_free_non_null (dc->temp_filename); GNUNET_free_non_null (dc->emsg); @@ -2573,40 +2697,40 @@ deserialize_download (struct GNUNET_FS_Handle *h, } dc->options = (enum GNUNET_FS_DownloadOptions) options; dc->active = - GNUNET_CONTAINER_multihashmap_create (1 + 2 * (dc->length / DBLOCK_SIZE)); + GNUNET_CONTAINER_multihashmap_create (1 + 2 * (dc->length / DBLOCK_SIZE), GNUNET_NO); dc->has_finished = (int) status; dc->treedepth = GNUNET_FS_compute_depth (GNUNET_FS_uri_chk_get_file_size (dc->uri)); if (GNUNET_FS_uri_test_loc (dc->uri)) GNUNET_assert (GNUNET_OK == GNUNET_FS_uri_loc_get_peer_identity (dc->uri, &dc->target)); - if (dc->emsg == NULL) + if (NULL == dc->emsg) { dc->top_request = read_download_request (rh); - if (dc->top_request == NULL) + if (NULL == dc->top_request) { GNUNET_break (0); goto cleanup; } } dn = get_download_sync_filename (dc, dc->serialization, ".dir"); - if (dn != NULL) + if (NULL != dn) { - if (GNUNET_YES == GNUNET_DISK_directory_test (dn)) + if (GNUNET_YES == GNUNET_DISK_directory_test (dn, GNUNET_YES)) GNUNET_DISK_directory_scan (dn, &deserialize_subdownload, dc); GNUNET_free (dn); } - if (parent != NULL) + if (NULL != parent) { GNUNET_abort (); // for debugging for now - FIXME GNUNET_CONTAINER_DLL_insert (parent->child_head, parent->child_tail, dc); } - if (search != NULL) + if (NULL != search) { dc->search = search; search->download = dc; } - if ((parent == NULL) && (search == NULL)) + if ((NULL == parent) && (NULL == search)) { dc->top = GNUNET_FS_make_top (dc->h, &GNUNET_FS_download_signal_suspend_, dc); @@ -2636,7 +2760,7 @@ signal_search_resume (struct GNUNET_FS_SearchContext *sc) pi.status = GNUNET_FS_STATUS_SEARCH_RESUME; pi.value.search.specifics.resume.message = sc->emsg; pi.value.search.specifics.resume.is_paused = - (sc->client == NULL) ? GNUNET_YES : GNUNET_NO; + (NULL == sc->client) ? GNUNET_YES : GNUNET_NO; sc->client_info = GNUNET_FS_search_make_status_ (&pi, sc); GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, &signal_result_resume, sc); @@ -2665,7 +2789,7 @@ deserialize_search (struct GNUNET_FS_Handle *h, uint32_t options; char in_pause; - if ((psearch_result != NULL) && (psearch_result->update_search != NULL)) + if ((NULL != psearch_result) && (NULL != psearch_result->update_search)) { GNUNET_break (0); return NULL; @@ -2673,7 +2797,7 @@ deserialize_search (struct GNUNET_FS_Handle *h, uris = NULL; emsg = NULL; sc = GNUNET_malloc (sizeof (struct GNUNET_FS_SearchContext)); - if (psearch_result != NULL) + if (NULL != psearch_result) { sc->psearch_result = psearch_result; psearch_result->update_search = sc; @@ -2696,16 +2820,16 @@ deserialize_search (struct GNUNET_FS_Handle *h, goto cleanup; } sc->options = (enum GNUNET_FS_SearchOptions) options; - sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16); + sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO); dn = get_serialization_file_name_in_dir (h, (sc->psearch_result == NULL) ? GNUNET_FS_SYNC_PATH_MASTER_SEARCH : GNUNET_FS_SYNC_PATH_CHILD_SEARCH, sc->serialization, ""); - if (dn != NULL) + if (NULL != dn) { - if (GNUNET_YES == GNUNET_DISK_directory_test (dn)) + if (GNUNET_YES == GNUNET_DISK_directory_test (dn, GNUNET_YES)) GNUNET_DISK_directory_scan (dn, &deserialize_search_result, sc); GNUNET_free (dn); } @@ -2754,9 +2878,9 @@ deserialize_search_file (void *cls, const char *filename) return GNUNET_OK; /* skip directories */ ser = get_serialization_short_name (filename); rh = GNUNET_BIO_read_open (filename); - if (rh == NULL) + if (NULL == rh) { - if (ser != NULL) + if (NULL != ser) { GNUNET_FS_remove_sync_file_ (h, GNUNET_FS_SYNC_PATH_MASTER_SEARCH, ser); GNUNET_free (ser); @@ -2764,7 +2888,7 @@ deserialize_search_file (void *cls, const char *filename) return GNUNET_OK; } sc = deserialize_search (h, rh, NULL, ser); - if (sc != NULL) + if (NULL != sc) sc->top = GNUNET_FS_make_top (h, &GNUNET_FS_search_signal_suspend_, sc); GNUNET_free (ser); if (GNUNET_OK != GNUNET_BIO_read_close (rh, &emsg)) @@ -2796,7 +2920,7 @@ deserialize_download_file (void *cls, const char *filename) ser = get_serialization_short_name (filename); rh = GNUNET_BIO_read_open (filename); - if (rh == NULL) + if (NULL == rh) { if (0 != UNLINK (filename)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); @@ -2830,9 +2954,9 @@ deserialization_master (const char *master_path, GNUNET_FileNameCallback proc, char *dn; dn = get_serialization_file_name (h, master_path, ""); - if (dn == NULL) + if (NULL == dn) return; - if (GNUNET_YES == GNUNET_DISK_directory_test (dn)) + if (GNUNET_YES == GNUNET_DISK_directory_test (dn, GNUNET_YES)) GNUNET_DISK_directory_scan (dn, proc, h); GNUNET_free (dn); } diff --git a/src/fs/fs_api.h b/src/fs/fs_api.h index e75b75f..12d4ae4 100644 --- a/src/fs/fs_api.h +++ b/src/fs/fs_api.h @@ -205,7 +205,7 @@ struct GNUNET_FS_Uri /** * Hash of the public key for the namespace. */ - GNUNET_HashCode namespace; + struct GNUNET_HashCode ns; /** * Human-readable identifier chosen for this @@ -333,7 +333,7 @@ struct GNUNET_FS_FileInformation * over the entire file (when the indexing process is started). * Otherwise this field is not used. */ - GNUNET_HashCode file_id; + struct GNUNET_HashCode file_id; /** * Size of the file (in bytes). @@ -568,7 +568,7 @@ struct GNUNET_FS_SearchResult /** * Key for the search result */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /** * ID of the task that will clean up the probe_ctx should it not @@ -578,6 +578,12 @@ struct GNUNET_FS_SearchResult GNUNET_SCHEDULER_TaskIdentifier probe_cancel_task; /** + * Task we use to report periodically to the application that the + * probe is still running. + */ + GNUNET_SCHEDULER_TaskIdentifier probe_ping_task; + + /** * When did the current probe become active? */ struct GNUNET_TIME_Absolute probe_active_time; @@ -633,10 +639,11 @@ GNUNET_FS_queue_ (struct GNUNET_FS_Handle *h, GNUNET_FS_QueueStart start, /** * Dequeue a job from the queue. - * @param qh handle for the job + * + * @param qe handle for the job */ void -GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qh); +GNUNET_FS_dequeue_ (struct GNUNET_FS_QueueEntry *qe); /** @@ -730,7 +737,7 @@ GNUNET_FS_publish_main_ (void *cls, * @param file_id computed hash, NULL on error */ void -GNUNET_FS_unindex_process_hash_ (void *cls, const GNUNET_HashCode * file_id); +GNUNET_FS_unindex_process_hash_ (void *cls, const struct GNUNET_HashCode * file_id); /** @@ -1159,7 +1166,7 @@ struct GNUNET_FS_PublishContext /** * Namespace that we are publishing in, NULL if we have no namespace. */ - struct GNUNET_FS_Namespace *namespace; + struct GNUNET_FS_Namespace *ns; /** * ID of the content in the namespace, NULL if we have no namespace. @@ -1384,12 +1391,12 @@ struct GNUNET_FS_UnindexContext /** * Current key for decrypting KBLocks from 'get_key' operation. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /** * Current query of 'get_key' operation. */ - GNUNET_HashCode query; + struct GNUNET_HashCode query; /** * First content UID, 0 for none. @@ -1424,7 +1431,7 @@ struct GNUNET_FS_UnindexContext /** * Hash of the file's contents (once computed). */ - GNUNET_HashCode file_id; + struct GNUNET_HashCode file_id; /** * Current operatinonal phase. @@ -1444,12 +1451,12 @@ struct SearchRequestEntry * Hash of the original keyword, also known as the * key (for decrypting the KBlock). */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /** * Hash of the public key, also known as the query. */ - GNUNET_HashCode query; + struct GNUNET_HashCode query; /** * Map that contains a "struct GNUNET_FS_SearchResult" for each result that @@ -1536,6 +1543,11 @@ struct GNUNET_FS_SearchContext struct GNUNET_TIME_Absolute start_time; /** + * How long to wait before we try to reconnect to FS service? + */ + struct GNUNET_TIME_Relative reconnect_backoff; + + /** * ID of a task that is using this struct and that must be cancelled * when the search is being stopped (if not * GNUNET_SCHEDULER_NO_TASK). Used for the task that adds some @@ -1900,6 +1912,11 @@ struct GNUNET_FS_DownloadContext struct GNUNET_TIME_Absolute start_time; /** + * How long to wait before we try to reconnect to FS service? + */ + struct GNUNET_TIME_Relative reconnect_backoff; + + /** * Desired level of anonymity. */ uint32_t anonymity; diff --git a/src/fs/fs_dirmetascan.c b/src/fs/fs_dirmetascan.c index 6dac690..e5a575a 100644 --- a/src/fs/fs_dirmetascan.c +++ b/src/fs/fs_dirmetascan.c @@ -232,8 +232,11 @@ finish_scan (void *cls, struct GNUNET_FS_DirScanner *ds = cls; ds->stop_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_HELPER_stop (ds->helper); - ds->helper = NULL; + if (NULL != ds->helper) + { + GNUNET_HELPER_stop (ds->helper); + ds->helper = NULL; + } ds->progress_callback (ds->progress_callback_cls, NULL, GNUNET_SYSERR, GNUNET_FS_DIRSCANNER_FINISHED); @@ -415,6 +418,25 @@ process_helper_msgs (void *cls, /** + * Function called if our helper process died. + * + * @param cls the 'struct GNUNET_FS_DirScanner' callback. + */ +static void +helper_died_cb (void *cls) +{ + struct GNUNET_FS_DirScanner *ds = cls; + + ds->helper = NULL; + if (GNUNET_SCHEDULER_NO_TASK != ds->stop_task) + return; /* normal death, was finished */ + ds->progress_callback (ds->progress_callback_cls, + NULL, GNUNET_SYSERR, + GNUNET_FS_DIRSCANNER_INTERNAL_ERROR); +} + + +/** * Start a directory scanner thread. * * @param filename name of the directory to scan @@ -454,12 +476,13 @@ GNUNET_FS_directory_scan_start (const char *filename, ds->args[1] = ds->filename_expanded; ds->args[2] = ds->ex_arg; ds->args[3] = NULL; - ds->helper = GNUNET_HELPER_start ("gnunet-helper-fs-publish", + ds->helper = GNUNET_HELPER_start (GNUNET_NO, + "gnunet-helper-fs-publish", ds->args, &process_helper_msgs, - ds); + &helper_died_cb, ds); if (NULL == ds->helper) - { + { GNUNET_free (filename_expanded); GNUNET_free (ds); return NULL; diff --git a/src/fs/fs_download.c b/src/fs/fs_download.c index 7c4dccb..82fc391 100644 --- a/src/fs/fs_download.c +++ b/src/fs/fs_download.c @@ -153,7 +153,7 @@ struct ProcessResultClosure /** * Hash of data. */ - GNUNET_HashCode query; + struct GNUNET_HashCode query; /** * Data found in P2P network. @@ -166,6 +166,11 @@ struct ProcessResultClosure struct GNUNET_FS_DownloadContext *dc; /** + * When did we last transmit the request? + */ + struct GNUNET_TIME_Absolute last_transmission; + + /** * Number of bytes in data. */ size_t size; @@ -181,9 +186,14 @@ struct ProcessResultClosure int do_store; /** - * When did we last transmit the request? + * how much respect did we offer to get this reply? */ - struct GNUNET_TIME_Absolute last_transmission; + uint32_t respect_offered; + + /** + * how often did we transmit the query? + */ + uint32_t num_transmissions; }; @@ -198,7 +208,7 @@ struct ProcessResultClosure * @return GNUNET_YES (we should continue to iterate); unless serious error */ static int -process_result_with_request (void *cls, const GNUNET_HashCode * key, +process_result_with_request (void *cls, const struct GNUNET_HashCode * key, void *value); @@ -225,7 +235,7 @@ encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc, char enc[len]; struct GNUNET_CRYPTO_AesSessionKey sk; struct GNUNET_CRYPTO_AesInitializationVector iv; - GNUNET_HashCode query; + struct GNUNET_HashCode query; GNUNET_CRYPTO_hash_to_aes_key (&chk->key, &sk, &iv); if (-1 == GNUNET_CRYPTO_aes_encrypt (block, len, &sk, &iv, enc)) @@ -234,7 +244,7 @@ encrypt_existing_match (struct GNUNET_FS_DownloadContext *dc, return GNUNET_SYSERR; } GNUNET_CRYPTO_hash (enc, len, &query); - if (0 != memcmp (&query, &chk->query, sizeof (GNUNET_HashCode))) + if (0 != memcmp (&query, &chk->query, sizeof (struct GNUNET_HashCode))) { GNUNET_break_op (0); return GNUNET_SYSERR; @@ -525,7 +535,7 @@ try_match_block (struct GNUNET_FS_DownloadContext *dc, pi.value.download.specifics.progress.offset = 0; 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.respect_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) && @@ -624,7 +634,7 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, { uint64_t off; char block[DBLOCK_SIZE]; - GNUNET_HashCode key; + struct GNUNET_HashCode key; uint64_t total; size_t len; unsigned int i; @@ -653,7 +663,7 @@ try_top_down_reconstruction (struct GNUNET_FS_DownloadContext *dc, return; /* failure */ } GNUNET_CRYPTO_hash (block, len, &key); - if (0 != memcmp (&key, &dr->chk.key, sizeof (GNUNET_HashCode))) + if (0 != memcmp (&key, &dr->chk.key, sizeof (struct GNUNET_HashCode))) return; /* mismatch */ if (GNUNET_OK != encrypt_existing_match (dc, &dr->chk, dr, block, len, GNUNET_NO)) @@ -926,7 +936,7 @@ GNUNET_FS_free_download_request_ (struct DownloadRequest *dr) * @return GNUNET_YES (we should continue to iterate); unless serious error */ static int -process_result_with_request (void *cls, const GNUNET_HashCode * key, +process_result_with_request (void *cls, const struct GNUNET_HashCode * key, void *value) { struct ProcessResultClosure *prc = cls; @@ -1069,7 +1079,8 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, pi.value.download.specifics.progress.offset = dr->offset; pi.value.download.specifics.progress.data_len = prc->size; pi.value.download.specifics.progress.depth = dr->depth; - pi.value.download.specifics.progress.trust_offered = 0; + pi.value.download.specifics.progress.respect_offered = prc->respect_offered; + pi.value.download.specifics.progress.num_transmissions = prc->num_transmissions; 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); @@ -1121,7 +1132,7 @@ process_result_with_request (void *cls, const GNUNET_HashCode * key, { /* 'chkarr' does not have enough space for this chk_idx; internal error! */ - GNUNET_break (0); + GNUNET_break (0); GNUNET_assert (0); dc->emsg = GNUNET_strdup (_("internal error decoding tree")); goto signal_error; } @@ -1178,6 +1189,11 @@ signal_error: dc->top_request = NULL; GNUNET_CONTAINER_multihashmap_destroy (dc->active); dc->active = NULL; + if (NULL != dc->job_queue) + { + GNUNET_FS_dequeue_ (dc->job_queue); + dc->job_queue = NULL; + } dc->pending_head = NULL; dc->pending_tail = NULL; GNUNET_FS_download_sync_ (dc); @@ -1190,6 +1206,8 @@ signal_error: * * @param dc our download context * @param type type of the result + * @param respect_offered how much respect did we offer to get this reply? + * @param num_transmissions how often did we transmit the query? * @param last_transmission when was this block requested the last time? (FOREVER if unknown/not applicable) * @param data the (encrypted) response * @param size size of data @@ -1197,6 +1215,8 @@ signal_error: static void process_result (struct GNUNET_FS_DownloadContext *dc, enum GNUNET_BLOCK_Type type, + uint32_t respect_offered, + uint32_t num_transmissions, struct GNUNET_TIME_Absolute last_transmission, const void *data, size_t size) { @@ -1204,10 +1224,12 @@ process_result (struct GNUNET_FS_DownloadContext *dc, prc.dc = dc; prc.data = data; + prc.last_transmission = last_transmission; prc.size = size; prc.type = type; prc.do_store = GNUNET_YES; - prc.last_transmission = last_transmission; + prc.respect_offered = respect_offered; + prc.num_transmissions = num_transmissions; GNUNET_CRYPTO_hash (data, size, &prc.query); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received result for query `%s' from `%s'-service\n", @@ -1242,6 +1264,8 @@ receive_results (void *cls, const struct GNUNET_MessageHeader *msg) msize = ntohs (msg->size); cm = (const struct ClientPutMessage *) msg; process_result (dc, ntohl (cm->type), + ntohl (cm->respect_offered), + ntohl (cm->num_transmissions), GNUNET_TIME_absolute_ntoh (cm->last_transmission), &cm[1], msize - sizeof (struct ClientPutMessage)); if (NULL == dc->client) @@ -1371,7 +1395,7 @@ do_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @return GNUNET_OK */ static int -retry_entry (void *cls, const GNUNET_HashCode * key, void *entry) +retry_entry (void *cls, const struct GNUNET_HashCode * key, void *entry) { struct GNUNET_FS_DownloadContext *dc = cls; struct DownloadRequest *dr = entry; @@ -1412,10 +1436,17 @@ try_reconnect (struct GNUNET_FS_DownloadContext *dc) dc->in_receive = GNUNET_NO; dc->client = NULL; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Will try to reconnect in 1s\n"); + if (0 == dc->reconnect_backoff.rel_value) + dc->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS; + else + dc->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (dc->reconnect_backoff); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Will try to reconnect in %s\n", + GNUNET_STRINGS_relative_time_to_string (dc->reconnect_backoff, GNUNET_YES)); dc->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &do_reconnect, - dc); + GNUNET_SCHEDULER_add_delayed (dc->reconnect_backoff, + &do_reconnect, + dc); } @@ -1435,6 +1466,7 @@ activate_fs_download (void *cls, struct GNUNET_CLIENT_Connection *client) GNUNET_assert (NULL != client); GNUNET_assert (NULL == dc->client); GNUNET_assert (NULL == dc->th); + GNUNET_assert (NULL != dc->active); dc->client = client; pi.status = GNUNET_FS_STATUS_DOWNLOAD_ACTIVE; GNUNET_FS_download_make_status_ (&pi, dc); @@ -1530,15 +1562,20 @@ create_download_request (struct DownloadRequest *parent, * 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; + { + head_skip = (file_start_offset - dr_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 */ + GNUNET_assert (dr->num_children > head_skip); dr->num_children -= head_skip; if (dr->num_children > CHK_PER_INODE) dr->num_children = CHK_PER_INODE; /* cap at max */ @@ -1556,10 +1593,12 @@ create_download_request (struct DownloadRequest *parent, 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; } @@ -1712,7 +1751,7 @@ reconstruct_cb (void *cls, const struct ContentHashKey *chk, uint64_t offset, pi.value.download.specifics.progress.offset = 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.respect_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 */ @@ -2000,6 +2039,7 @@ GNUNET_FS_download_signal_suspend_ (void *cls) GNUNET_FS_uri_destroy (dc->uri); GNUNET_free_non_null (dc->temp_filename); GNUNET_free_non_null (dc->serialization); + GNUNET_assert (NULL == dc->job_queue); GNUNET_free (dc); } @@ -2041,6 +2081,11 @@ create_download_context (struct GNUNET_FS_Handle *h, return NULL; } dc = GNUNET_malloc (sizeof (struct GNUNET_FS_DownloadContext)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting download %p, %u bytes at offset %llu\n", + dc, + (unsigned long long) length, + (unsigned long long) offset); dc->h = h; dc->uri = GNUNET_FS_uri_dup (uri); dc->meta = GNUNET_CONTAINER_meta_data_duplicate (meta); @@ -2060,7 +2105,7 @@ create_download_context (struct GNUNET_FS_Handle *h, dc->anonymity = anonymity; dc->options = options; dc->active = - GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE)); + GNUNET_CONTAINER_multihashmap_create (1 + 2 * (length / DBLOCK_SIZE), GNUNET_NO); dc->treedepth = GNUNET_FS_compute_depth (GNUNET_FS_uri_chk_get_file_size (dc->uri)); if ((NULL == filename) && (is_recursive_download (dc))) @@ -2128,7 +2173,7 @@ GNUNET_FS_download_start (struct GNUNET_FS_Handle *h, dc->parent = parent; if (NULL != parent) GNUNET_CONTAINER_DLL_insert (parent->child_head, parent->child_tail, dc); - else + else if (0 == (GNUNET_FS_DOWNLOAD_IS_PROBE & options) ) dc->top = GNUNET_FS_make_top (dc->h, &GNUNET_FS_download_signal_suspend_, dc); return dc; @@ -2196,6 +2241,11 @@ GNUNET_FS_download_start_from_search (struct GNUNET_FS_Handle *h, GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); sr->probe_ctx = NULL; } + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_ping_task) + { + GNUNET_SCHEDULER_cancel (sr->probe_ping_task); + sr->probe_ping_task = GNUNET_SCHEDULER_NO_TASK; + } return dc; } @@ -2211,12 +2261,17 @@ GNUNET_FS_download_start_downloading_ (struct GNUNET_FS_DownloadContext *dc) if (dc->completed == dc->length) return; GNUNET_assert (NULL == dc->job_queue); + GNUNET_assert (NULL != dc->active); dc->job_queue = GNUNET_FS_queue_ (dc->h, &activate_fs_download, &deactivate_fs_download, 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); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Download %p put into queue as job %p\n", + dc, + dc->job_queue); } @@ -2287,7 +2342,8 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete) { if ((dc->completed != dc->length) && (GNUNET_YES == do_delete)) { - if (0 != UNLINK (dc->filename)) + if ( (0 != UNLINK (dc->filename)) && + (ENOENT != errno) ) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", dc->filename); } @@ -2303,6 +2359,7 @@ GNUNET_FS_download_stop (struct GNUNET_FS_DownloadContext *dc, int do_delete) GNUNET_free (dc->temp_filename); } GNUNET_free_non_null (dc->serialization); + GNUNET_assert (NULL == dc->job_queue); GNUNET_free (dc); } diff --git a/src/fs/fs_file_information.c b/src/fs/fs_file_information.c index 8065927..7726fc7 100644 --- a/src/fs/fs_file_information.c +++ b/src/fs/fs_file_information.c @@ -367,7 +367,8 @@ GNUNET_FS_file_information_inspect (struct GNUNET_FS_FileInformation *dir, if (GNUNET_OK != proc (proc_cls, dir, (dir->is_directory == GNUNET_YES) ? dir->data.dir.dir_size : dir->data. - file.file_size, dir->meta, &dir->keywords, &dir->bo, + file.file_size, + dir->meta, &dir->keywords, &dir->bo, (dir->is_directory == GNUNET_YES) ? &no : &dir->data.file.do_index, &dir->client_info)) return; diff --git a/src/fs/fs_getopt.c b/src/fs/fs_getopt.c index 0374774..6cc4021 100644 --- a/src/fs/fs_getopt.c +++ b/src/fs/fs_getopt.c @@ -139,11 +139,12 @@ GNUNET_FS_getopt_set_metadata (struct GNUNET_GETOPT_CommandLineProcessorContext *mm = meta; } -#if ENABLE_NLS - tmp = GNUNET_STRINGS_to_utf8 (value, strlen (value), nl_langinfo (CODESET)); -#else - tmp = GNUNET_STRINGS_to_utf8 (value, strlen (value), "utf-8"); -#endif + /* Use GNUNET_STRINGS_get_utf8_args() in main() to acquire utf-8-encoded + * commandline arguments, so that the following line is not needed. + */ + /*tmp = GNUNET_STRINGS_to_utf8 (value, strlen (value), locale_charset ());*/ + tmp = GNUNET_strdup (value); + type = EXTRACTOR_metatype_get_max (); while (type > 0) { diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c index bfd7594..5c16ea4 100644 --- a/src/fs/fs_namespace.c +++ b/src/fs/fs_namespace.c @@ -53,9 +53,8 @@ get_namespace_directory (struct GNUNET_FS_Handle *h) GNUNET_CONFIGURATION_get_value_filename (h->cfg, "FS", "IDENTITY_DIR", &dn)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Configuration fails to specify `%s' in section `%s'\n"), - "IDENTITY_DIR", "fs"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "fs", "IDENTITY_DIR"); return NULL; } return dn; @@ -79,9 +78,8 @@ get_update_information_directory (struct GNUNET_FS_Namespace *ns) GNUNET_CONFIGURATION_get_value_filename (ns->h->cfg, "FS", "UPDATE_DIR", &dn)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Configuration fails to specify `%s' in section `%s'\n"), - "UPDATE_DIR", "fs"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "fs", "UPDATE_DIR"); return NULL; } GNUNET_asprintf (&ret, "%s%s%s", dn, DIR_SEPARATOR_STR, ns->name); @@ -106,7 +104,7 @@ write_update_information_graph (struct GNUNET_FS_Namespace *ns) fn = get_update_information_directory (ns); wh = GNUNET_BIO_write_open (fn); - if (wh == NULL) + if (NULL == wh) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to open `%s' for writing: %s\n"), STRERROR (errno)); @@ -160,7 +158,7 @@ read_update_information_graph (struct GNUNET_FS_Namespace *ns) return; } rh = GNUNET_BIO_read_open (fn); - if (rh == NULL) + if (NULL == rh) { GNUNET_free (fn); return; @@ -175,7 +173,7 @@ read_update_information_graph (struct GNUNET_FS_Namespace *ns) GNUNET_break (0); goto END; } - if (count == 0) + if (0 == count) { GNUNET_break (GNUNET_OK == GNUNET_BIO_read_close (rh, NULL)); GNUNET_free (fn); @@ -226,15 +224,13 @@ END: } - - /** * Create a namespace with the given name; if one already * exists, return a handle to the existing namespace. * * @param h handle to the file sharing subsystem * @param name name to use for the namespace - * @return handle to the namespace, NULL on error + * @return handle to the namespace, NULL on error (i.e. invalid filename) */ struct GNUNET_FS_Namespace * GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, const char *name) @@ -250,7 +246,7 @@ GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h, const char *name) ret->h = h; ret->rc = 1; ret->key = GNUNET_CRYPTO_rsa_key_create_from_file (fn); - if (ret->key == NULL) + if (NULL == ret->key) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to create or read private key for namespace `%s'\n"), @@ -284,44 +280,44 @@ GNUNET_FS_namespace_dup (struct GNUNET_FS_Namespace *ns) * memory) or also to freeze the namespace to prevent further * insertions by anyone. * - * @param namespace handle to the namespace that should be deleted / freed + * @param ns handle to the namespace that should be deleted / freed * @param freeze prevents future insertions; creating a namespace * with the same name again will create a fresh namespace instead * * @return GNUNET_OK on success, GNUNET_SYSERR on error */ int -GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *namespace, int freeze) +GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *ns, int freeze) { unsigned int i; struct NamespaceUpdateNode *nsn; - namespace->rc--; + ns->rc--; if (freeze) { - if (0 != UNLINK (namespace->filename)) + if (0 != UNLINK (ns->filename)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "unlink", - namespace->filename); + ns->filename); } - if (0 != namespace->rc) + if (0 != ns->rc) return GNUNET_OK; - GNUNET_CRYPTO_rsa_key_free (namespace->key); - GNUNET_free (namespace->filename); - GNUNET_free (namespace->name); - for (i = 0; i < namespace->update_node_count; i++) + GNUNET_CRYPTO_rsa_key_free (ns->key); + GNUNET_free (ns->filename); + GNUNET_free (ns->name); + for (i = 0; i < ns->update_node_count; i++) { - nsn = namespace->update_nodes[i]; + nsn = ns->update_nodes[i]; GNUNET_CONTAINER_meta_data_destroy (nsn->md); GNUNET_FS_uri_destroy (nsn->uri); GNUNET_free (nsn->id); GNUNET_free (nsn->update); GNUNET_free (nsn); } - GNUNET_array_grow (namespace->update_nodes, namespace->update_node_count, + GNUNET_array_grow (ns->update_nodes, ns->update_node_count, 0); - if (namespace->update_map != NULL) - GNUNET_CONTAINER_multihashmap_destroy (namespace->update_map); - GNUNET_free (namespace); + if (ns->update_map != NULL) + GNUNET_CONTAINER_multihashmap_destroy (ns->update_map); + GNUNET_free (ns); return GNUNET_OK; } @@ -359,12 +355,12 @@ process_namespace (void *cls, const char *filename) struct ProcessNamespaceContext *pnc = cls; struct GNUNET_CRYPTO_RsaPrivateKey *key; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk; - GNUNET_HashCode id; + struct GNUNET_HashCode id; const char *name; const char *t; key = GNUNET_CRYPTO_rsa_key_create_from_file (filename); - if (key == NULL) + if (NULL == key) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ @@ -402,7 +398,7 @@ GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h, struct ProcessNamespaceContext ctx; dn = get_namespace_directory (h); - if (dn == NULL) + if (NULL == dn) return; ctx.cb = cb; ctx.cb_cls = cb_cls; @@ -431,7 +427,7 @@ struct GNUNET_FS_PublishSksContext /** * Namespace we're publishing to. */ - struct GNUNET_FS_Namespace *namespace; + struct GNUNET_FS_Namespace *ns; /** * Handle to the datastore. @@ -470,7 +466,7 @@ sb_put_cont (void *cls, int success, const char *msg) { struct GNUNET_FS_PublishSksContext *psc = cls; - GNUNET_HashCode hc; + struct GNUNET_HashCode hc; psc->dqe = NULL; if (GNUNET_OK != success) @@ -485,19 +481,19 @@ sb_put_cont (void *cls, int success, /* FIXME: this can be done much more * efficiently by simply appending to the * file and overwriting the 4-byte header */ - if (psc->namespace->update_nodes == NULL) - read_update_information_graph (psc->namespace); - GNUNET_array_append (psc->namespace->update_nodes, - psc->namespace->update_node_count, psc->nsn); - if (psc->namespace->update_map != NULL) + if (psc->ns->update_nodes == NULL) + read_update_information_graph (psc->ns); + GNUNET_array_append (psc->ns->update_nodes, + psc->ns->update_node_count, psc->nsn); + if (psc->ns->update_map != NULL) { GNUNET_CRYPTO_hash (psc->nsn->id, strlen (psc->nsn->id), &hc); - GNUNET_CONTAINER_multihashmap_put (psc->namespace->update_map, &hc, + GNUNET_CONTAINER_multihashmap_put (psc->ns->update_map, &hc, psc->nsn, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); } psc->nsn = NULL; - write_update_information_graph (psc->namespace); + write_update_information_graph (psc->ns); } if (NULL != psc->cont) psc->cont (psc->cont_cls, psc->uri, NULL); @@ -509,7 +505,7 @@ sb_put_cont (void *cls, int success, * Publish an SBlock on GNUnet. * * @param h handle to the file sharing subsystem - * @param namespace namespace to publish in + * @param ns namespace to publish in * @param identifier identifier to use * @param update update identifier to use * @param meta metadata to use @@ -522,7 +518,7 @@ sb_put_cont (void *cls, int success, */ struct GNUNET_FS_PublishSksContext * GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, - struct GNUNET_FS_Namespace *namespace, + struct GNUNET_FS_Namespace *ns, const char *identifier, const char *update, const struct GNUNET_CONTAINER_MetaData *meta, const struct GNUNET_FS_Uri *uri, @@ -544,31 +540,40 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, struct SBlock *sb_enc; char *dest; struct GNUNET_CONTAINER_MetaData *mmeta; - GNUNET_HashCode key; /* hash of thisId = key */ - GNUNET_HashCode id; /* hash of hc = identifier */ - GNUNET_HashCode query; /* id ^ nsid = DB query */ + struct GNUNET_HashCode key; /* hash of thisId = key */ + struct GNUNET_HashCode id; /* hash of hc = identifier */ + struct GNUNET_HashCode query; /* id ^ nsid = DB query */ - if (NULL == meta) - mmeta = GNUNET_CONTAINER_meta_data_create (); - else - mmeta = GNUNET_CONTAINER_meta_data_duplicate (meta); - uris = GNUNET_FS_uri_to_string (uri); - slen = strlen (uris) + 1; idlen = strlen (identifier); - if (update != NULL) + if (NULL != update) nidlen = strlen (update) + 1; else nidlen = 1; + uris = GNUNET_FS_uri_to_string (uri); + slen = strlen (uris) + 1; + if ( (slen >= MAX_SBLOCK_SIZE - sizeof (struct SBlock)) || + (nidlen >= MAX_SBLOCK_SIZE - sizeof (struct SBlock) - slen) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Identifiers or URI too long to create SBlock")); + GNUNET_free (uris); + return NULL; + } + if (NULL == meta) + mmeta = GNUNET_CONTAINER_meta_data_create (); + else + mmeta = GNUNET_CONTAINER_meta_data_duplicate (meta); mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (mmeta); size = sizeof (struct SBlock) + slen + nidlen + mdsize; - if (size > MAX_SBLOCK_SIZE) + if ( (size > MAX_SBLOCK_SIZE) || + (size < sizeof (struct SBlock) + slen + nidlen) ) { size = MAX_SBLOCK_SIZE; - mdsize = size - (sizeof (struct SBlock) + slen + nidlen); + mdsize = MAX_SBLOCK_SIZE - (sizeof (struct SBlock) + slen + nidlen); } sb = GNUNET_malloc (sizeof (struct SBlock) + size); dest = (char *) &sb[1]; - if (update != NULL) + if (NULL != update) memcpy (dest, update, nidlen); else memset (dest, 0, 1); @@ -580,7 +585,7 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, GNUNET_CONTAINER_meta_data_serialize (mmeta, &dest, mdsize, GNUNET_CONTAINER_META_DATA_SERIALIZE_PART); GNUNET_CONTAINER_meta_data_destroy (mmeta); - if (mdsize == -1) + if (-1 == mdsize) { GNUNET_break (0); GNUNET_free (sb); @@ -591,15 +596,15 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, size = sizeof (struct SBlock) + mdsize + slen + nidlen; sb_enc = GNUNET_malloc (size); GNUNET_CRYPTO_hash (identifier, idlen, &key); - GNUNET_CRYPTO_hash (&key, sizeof (GNUNET_HashCode), &id); + GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &id); sks_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); sks_uri->type = sks; - GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &sb_enc->subspace); + GNUNET_CRYPTO_rsa_key_get_public (ns->key, &sb_enc->subspace); GNUNET_CRYPTO_hash (&sb_enc->subspace, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &sks_uri->data.sks.namespace); + &sks_uri->data.sks.ns); sks_uri->data.sks.identifier = GNUNET_strdup (identifier); - GNUNET_CRYPTO_hash_xor (&id, &sks_uri->data.sks.namespace, + GNUNET_CRYPTO_hash_xor (&id, &sks_uri->data.sks.ns, &sb_enc->identifier); GNUNET_CRYPTO_hash_to_aes_key (&key, &sk, &iv); GNUNET_CRYPTO_aes_encrypt (&sb[1], size - sizeof (struct SBlock), &sk, &iv, @@ -609,12 +614,12 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, htonl (slen + mdsize + nidlen + sizeof (struct SBlock) - sizeof (struct GNUNET_CRYPTO_RsaSignature)); GNUNET_assert (GNUNET_OK == - GNUNET_CRYPTO_rsa_sign (namespace->key, &sb_enc->purpose, + GNUNET_CRYPTO_rsa_sign (ns->key, &sb_enc->purpose, &sb_enc->signature)); psc = GNUNET_malloc (sizeof (struct GNUNET_FS_PublishSksContext)); psc->uri = sks_uri; psc->cont = cont; - psc->namespace = GNUNET_FS_namespace_dup (namespace); + psc->ns = GNUNET_FS_namespace_dup (ns); psc->cont_cls = cont_cls; if (0 != (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY)) { @@ -631,7 +636,7 @@ GNUNET_FS_publish_sks (struct GNUNET_FS_Handle *h, sb_put_cont (psc, GNUNET_NO, GNUNET_TIME_UNIT_ZERO_ABS, _("Failed to connect to datastore.")); return NULL; } - GNUNET_CRYPTO_hash_xor (&sks_uri->data.sks.namespace, &id, &query); + GNUNET_CRYPTO_hash_xor (&sks_uri->data.sks.ns, &id, &query); if (NULL != update) { psc->nsn = GNUNET_malloc (sizeof (struct NamespaceUpdateNode)); @@ -669,7 +674,7 @@ GNUNET_FS_publish_sks_cancel (struct GNUNET_FS_PublishSksContext *psc) GNUNET_DATASTORE_disconnect (psc->dsh, GNUNET_NO); psc->dsh = NULL; } - GNUNET_FS_namespace_delete (psc->namespace, GNUNET_NO); + GNUNET_FS_namespace_delete (psc->ns, GNUNET_NO); GNUNET_FS_uri_destroy (psc->uri); if (NULL != psc->nsn) { @@ -711,7 +716,7 @@ struct ProcessUpdateClosure * GNUNET_NO if not. */ static int -process_update_node (void *cls, const GNUNET_HashCode * key, void *value) +process_update_node (void *cls, const struct GNUNET_HashCode * key, void *value) { struct ProcessUpdateClosure *pc = cls; struct NamespaceUpdateNode *nsn = value; @@ -729,7 +734,7 @@ struct FindTreeClosure /** * Namespace we are operating on. */ - struct GNUNET_FS_Namespace *namespace; + struct GNUNET_FS_Namespace *ns; /** * Array with 'head's of TREEs. @@ -774,15 +779,15 @@ struct FindTreeClosure * GNUNET_NO if not. */ static int -find_trees (void *cls, const GNUNET_HashCode * key, void *value) +find_trees (void *cls, const struct GNUNET_HashCode * key, void *value) { struct FindTreeClosure *fc = cls; struct NamespaceUpdateNode *nsn = value; - GNUNET_HashCode hc; + struct GNUNET_HashCode hc; if (nsn->nug == fc->nug) { - if (nsn->tree_id == UINT_MAX) + if (UINT_MAX == nsn->tree_id) return GNUNET_YES; /* circular */ GNUNET_assert (nsn->tree_id < fc->tree_array_size); if (fc->tree_array[nsn->tree_id] != nsn) @@ -792,7 +797,7 @@ find_trees (void *cls, const GNUNET_HashCode * key, void *value) return GNUNET_YES; /* that's our own root (can this be?) */ /* merge existing TREE, we have a root for both */ fc->tree_array[nsn->tree_id] = NULL; - if (fc->id == UINT_MAX) + if (UINT_MAX == fc->id) fc->id = nsn->tree_id; /* take over ID */ } else @@ -801,7 +806,7 @@ find_trees (void *cls, const GNUNET_HashCode * key, void *value) nsn->tree_id = UINT_MAX; /* mark as undef */ /* trace */ GNUNET_CRYPTO_hash (nsn->update, strlen (nsn->update), &hc); - GNUNET_CONTAINER_multihashmap_get_multiple (fc->namespace->update_map, &hc, + GNUNET_CONTAINER_multihashmap_get_multiple (fc->ns->update_map, &hc, &find_trees, fc); } return GNUNET_YES; @@ -825,66 +830,67 @@ find_trees (void *cls, const GNUNET_HashCode * key, void *value) * I know, odd definition of a tree, but the GUI will display an actual * tree (GtkTreeView), so that's what counts for the term here. * - * @param namespace namespace to inspect for updateable content + * @param ns namespace to inspect for updateable content * @param next_id ID to look for; use NULL to look for tree roots * @param ip function to call on each updateable identifier * @param ip_cls closure for ip */ void -GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, +GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *ns, const char *next_id, GNUNET_FS_IdentifierProcessor ip, void *ip_cls) { unsigned int i; unsigned int nug; - GNUNET_HashCode hc; + struct GNUNET_HashCode hc; struct NamespaceUpdateNode *nsn; struct ProcessUpdateClosure pc; struct FindTreeClosure fc; - if (namespace->update_nodes == NULL) - read_update_information_graph (namespace); - if (namespace->update_nodes == NULL) + if (NULL == ns->update_nodes) + read_update_information_graph (ns); + if (NULL == ns->update_nodes) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No updateable nodes found for ID `%s'\n", next_id); return; /* no nodes */ } - if (namespace->update_map == NULL) + if (NULL == ns->update_map) { /* need to construct */ - namespace->update_map = + ns->update_map = GNUNET_CONTAINER_multihashmap_create (2 + - 3 * namespace->update_node_count / - 4); - for (i = 0; i < namespace->update_node_count; i++) + 3 * ns->update_node_count / + 4, + GNUNET_NO); + for (i = 0; i < ns->update_node_count; i++) { - nsn = namespace->update_nodes[i]; + nsn = ns->update_nodes[i]; GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); - GNUNET_CONTAINER_multihashmap_put (namespace->update_map, &hc, nsn, + GNUNET_CONTAINER_multihashmap_put (ns->update_map, &hc, nsn, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); } } - if (next_id != NULL) + if (NULL != next_id) { GNUNET_CRYPTO_hash (next_id, strlen (next_id), &hc); pc.ip = ip; pc.ip_cls = ip_cls; - GNUNET_CONTAINER_multihashmap_get_multiple (namespace->update_map, &hc, + GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, &process_update_node, &pc); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Calculating TREEs to find roots of update trees\n"); /* Find heads of TREEs in update graph */ - nug = ++namespace->nug_gen; + nug = ++ns->nug_gen; fc.tree_array = NULL; fc.tree_array_size = 0; - for (i = 0; i < namespace->update_node_count; i++) + for (i = 0; i < ns->update_node_count; i++) { - nsn = namespace->update_nodes[i]; + nsn = ns->update_nodes[i]; if (nsn->nug == nug) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TREE of node `%s' is %u\n", nsn->id, @@ -896,10 +902,10 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, nsn->tree_id = UINT_MAX; fc.id = UINT_MAX; fc.nug = nug; - fc.namespace = namespace; - GNUNET_CONTAINER_multihashmap_get_multiple (namespace->update_map, &hc, + fc.ns = ns; + GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, &find_trees, &fc); - if (fc.id == UINT_MAX) + if (UINT_MAX == fc.id) { /* start new TREE */ for (fc.id = 0; fc.id < fc.tree_array_size; fc.id++) @@ -923,8 +929,8 @@ GNUNET_FS_namespace_list_updateable (struct GNUNET_FS_Namespace *namespace, GNUNET_CRYPTO_hash (nsn->id, strlen (nsn->id), &hc); fc.id = nsn->tree_id; fc.nug = nug; - fc.namespace = namespace; - GNUNET_CONTAINER_multihashmap_get_multiple (namespace->update_map, &hc, + fc.ns = ns; + GNUNET_CONTAINER_multihashmap_get_multiple (ns->update_map, &hc, &find_trees, &fc); } else diff --git a/src/fs/fs_namespace_advertise.c b/src/fs/fs_namespace_advertise.c index e0226ca..3b64e61 100644 --- a/src/fs/fs_namespace_advertise.c +++ b/src/fs/fs_namespace_advertise.c @@ -132,8 +132,8 @@ advertisement_cont (void *cls, int success, { struct GNUNET_FS_AdvertisementContext *ac = cls; const char *keyword; - GNUNET_HashCode key; - GNUNET_HashCode query; + struct GNUNET_HashCode key; + struct GNUNET_HashCode query; struct GNUNET_CRYPTO_AesSessionKey skey; struct GNUNET_CRYPTO_AesInitializationVector iv; struct GNUNET_CRYPTO_RsaPrivateKey *pk; @@ -204,7 +204,7 @@ advertisement_cont (void *cls, int success, * * @param h handle to the file sharing subsystem * @param ksk_uri keywords to use for advertisment - * @param namespace handle for the namespace that should be advertised + * @param ns handle for the namespace that should be advertised * @param meta meta-data for the namespace advertisement * @param bo block options * @param rootEntry name of the root of the namespace @@ -215,7 +215,7 @@ advertisement_cont (void *cls, int success, struct GNUNET_FS_AdvertisementContext * GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h, struct GNUNET_FS_Uri *ksk_uri, - struct GNUNET_FS_Namespace *namespace, + struct GNUNET_FS_Namespace *ns, const struct GNUNET_CONTAINER_MetaData *meta, const struct GNUNET_FS_BlockOptions *bo, const char *rootEntry, @@ -261,7 +261,7 @@ GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h, } size = mdsize + sizeof (struct NBlock) + reslen; nb = GNUNET_malloc (size); - GNUNET_CRYPTO_rsa_key_get_public (namespace->key, &nb->subspace); + GNUNET_CRYPTO_rsa_key_get_public (ns->key, &nb->subspace); nb->ns_purpose.size = htonl (mdsize + reslen + sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + @@ -286,7 +286,7 @@ GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h, ctx->nb = nb; ctx->pt = pt; ctx->pt_size = mdsize + reslen; - ctx->ns = namespace; + ctx->ns = ns; ctx->ns->rc++; ctx->bo = *bo; advertisement_cont (ctx, GNUNET_OK, GNUNET_TIME_UNIT_ZERO_ABS, NULL); diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index 93c3046..30ab1ee 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c @@ -83,10 +83,10 @@ publish_cleanup (struct GNUNET_FS_PublishContext *pc) pc->fhc = NULL; } GNUNET_FS_file_information_destroy (pc->fi, NULL, NULL); - if (pc->namespace != NULL) + if (pc->ns != NULL) { - GNUNET_FS_namespace_delete (pc->namespace, GNUNET_NO); - pc->namespace = NULL; + GNUNET_FS_namespace_delete (pc->ns, GNUNET_NO); + pc->ns = NULL; } GNUNET_free_non_null (pc->nid); GNUNET_free_non_null (pc->nuid); @@ -269,8 +269,8 @@ publish_sblocks_cont (void *cls, const struct GNUNET_FS_Uri *uri, static void publish_sblock (struct GNUNET_FS_PublishContext *pc) { - if (NULL != pc->namespace) - pc->sks_pc = GNUNET_FS_publish_sks (pc->h, pc->namespace, pc->nid, pc->nuid, + if (NULL != pc->ns) + pc->sks_pc = GNUNET_FS_publish_sks (pc->h, pc->ns, pc->nid, pc->nuid, pc->fi->meta, pc->fi->chk_uri, &pc->fi->bo, pc->options, &publish_sblocks_cont, pc); else @@ -569,6 +569,7 @@ publish_content (struct GNUNET_FS_PublishContext *pc) GNUNET_free (raw_data); raw_data = NULL; } + dirpos->data.file.reader (dirpos->data.file.reader_cls, UINT64_MAX, 0, 0, NULL); } } GNUNET_FS_directory_builder_add (db, dirpos->chk_uri, dirpos->meta, @@ -657,7 +658,7 @@ process_index_start_response (void *cls, const struct GNUNET_MessageHeader *msg) * @param res resulting hash, NULL on error */ static void -hash_for_index_cb (void *cls, const GNUNET_HashCode * res) +hash_for_index_cb (void *cls, const struct GNUNET_HashCode * res) { struct GNUNET_FS_PublishContext *pc = cls; struct GNUNET_FS_FileInformation *p; @@ -958,41 +959,19 @@ fip_signal_start (void *cls, struct GNUNET_FS_FileInformation *fi, /** - * Signal the FS's progress function that we are suspending + * Actually signal the FS's progress function that we are suspending * an upload. * - * @param cls closure (of type "struct GNUNET_FS_PublishContext*") * @param fi the entry in the publish-structure - * @param length length of the file or directory - * @param meta metadata for the file or directory (can be modified) - * @param uri pointer to the keywords that will be used for this entry (can be modified) - * @param bo block options - * @param do_index should we index? - * @param client_info pointer to client context set upon creation (can be modified) - * @return GNUNET_OK to continue (always) + * @param pc the publish context of which a file is being suspended */ -static int -fip_signal_suspend (void *cls, struct GNUNET_FS_FileInformation *fi, - uint64_t length, struct GNUNET_CONTAINER_MetaData *meta, - struct GNUNET_FS_Uri **uri, - struct GNUNET_FS_BlockOptions *bo, int *do_index, - void **client_info) +static void +suspend_operation (struct GNUNET_FS_FileInformation *fi, + struct GNUNET_FS_PublishContext *pc) { - struct GNUNET_FS_PublishContext *pc = cls; struct GNUNET_FS_ProgressInfo pi; uint64_t off; - if (GNUNET_YES == pc->skip_next_fi_callback) - { - pc->skip_next_fi_callback = GNUNET_NO; - return GNUNET_OK; - } - if (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (meta)) - { - /* process entries in directory */ - pc->skip_next_fi_callback = GNUNET_YES; - GNUNET_FS_file_information_inspect (fi, &fip_signal_suspend, pc); - } if (NULL != pc->ksk_pc) { GNUNET_FS_publish_ksk_cancel (pc->ksk_pc); @@ -1006,10 +985,9 @@ fip_signal_suspend (void *cls, struct GNUNET_FS_FileInformation *fi, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suspending publish operation\n"); GNUNET_free_non_null (fi->serialization); fi->serialization = NULL; - off = (fi->chk_uri == NULL) ? 0 : length; + off = (fi->chk_uri == NULL) ? 0 : (fi->is_directory == GNUNET_YES) ? fi->data.dir.dir_size : fi->data.file.file_size; pi.status = GNUNET_FS_STATUS_PUBLISH_SUSPEND; GNUNET_break (NULL == GNUNET_FS_publish_make_status_ (&pi, pc, fi, off)); - *client_info = NULL; if (NULL != pc->qre) { GNUNET_DATASTORE_cancel (pc->qre); @@ -1021,6 +999,45 @@ fip_signal_suspend (void *cls, struct GNUNET_FS_FileInformation *fi, pc->dsh = NULL; } pc->rid = 0; +} + + +/** + * Signal the FS's progress function that we are suspending + * an upload. Performs the recursion. + * + * @param cls closure (of type "struct GNUNET_FS_PublishContext*") + * @param fi the entry in the publish-structure + * @param length length of the file or directory + * @param meta metadata for the file or directory (can be modified) + * @param uri pointer to the keywords that will be used for this entry (can be modified) + * @param bo block options + * @param do_index should we index? + * @param client_info pointer to client context set upon creation (can be modified) + * @return GNUNET_OK to continue (always) + */ +static int +fip_signal_suspend (void *cls, struct GNUNET_FS_FileInformation *fi, + uint64_t length, struct GNUNET_CONTAINER_MetaData *meta, + struct GNUNET_FS_Uri **uri, + struct GNUNET_FS_BlockOptions *bo, int *do_index, + void **client_info) +{ + struct GNUNET_FS_PublishContext *pc = cls; + + if (GNUNET_YES == pc->skip_next_fi_callback) + { + pc->skip_next_fi_callback = GNUNET_NO; + return GNUNET_OK; + } + if (GNUNET_YES == GNUNET_FS_meta_data_test_for_directory (meta)) + { + /* process entries in directory */ + pc->skip_next_fi_callback = GNUNET_YES; + GNUNET_FS_file_information_inspect (fi, &fip_signal_suspend, pc); + } + suspend_operation (fi, pc); + *client_info = NULL; return GNUNET_OK; } @@ -1041,7 +1058,9 @@ GNUNET_FS_publish_signal_suspend_ (void *cls) GNUNET_SCHEDULER_cancel (pc->upload_task); pc->upload_task = GNUNET_SCHEDULER_NO_TASK; } + pc->skip_next_fi_callback = GNUNET_YES; GNUNET_FS_file_information_inspect (pc->fi, &fip_signal_suspend, pc); + suspend_operation (pc->fi, pc); GNUNET_FS_end_top (pc->h, pc->top); pc->top = NULL; publish_cleanup (pc); @@ -1086,7 +1105,7 @@ finish_reserve (void *cls, int success, * * @param h handle to the file sharing subsystem * @param fi information about the file or directory structure to publish - * @param namespace namespace to publish the file in, NULL for no namespace + * @param ns namespace to publish the file in, NULL for no namespace * @param nid identifier to use for the publishd content in the namespace * (can be NULL, must be NULL if namespace is NULL) * @param nuid update-identifier that will be used for future updates @@ -1097,7 +1116,7 @@ finish_reserve (void *cls, int success, struct GNUNET_FS_PublishContext * GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, struct GNUNET_FS_FileInformation *fi, - struct GNUNET_FS_Namespace *namespace, const char *nid, + struct GNUNET_FS_Namespace *ns, const char *nid, const char *nuid, enum GNUNET_FS_PublishOptions options) { @@ -1119,11 +1138,11 @@ GNUNET_FS_publish_start (struct GNUNET_FS_Handle *h, ret->dsh = dsh; ret->h = h; ret->fi = fi; - ret->namespace = namespace; + ret->ns = ns; ret->options = options; - if (namespace != NULL) + if (ns != NULL) { - namespace->rc++; + ns->rc++; GNUNET_assert (NULL != nid); ret->nid = GNUNET_strdup (nid); if (NULL != nuid) diff --git a/src/fs/fs_publish_ksk.c b/src/fs/fs_publish_ksk.c index 0b6d407..5511fb9 100644 --- a/src/fs/fs_publish_ksk.c +++ b/src/fs/fs_publish_ksk.c @@ -172,8 +172,8 @@ publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_FS_PublishKskContext *pkc = cls; const char *keyword; - GNUNET_HashCode key; - GNUNET_HashCode query; + struct GNUNET_HashCode key; + struct GNUNET_HashCode query; struct GNUNET_CRYPTO_AesSessionKey skey; struct GNUNET_CRYPTO_AesInitializationVector iv; struct GNUNET_CRYPTO_RsaPrivateKey *pk; diff --git a/src/fs/fs_search.c b/src/fs/fs_search.c index b280670..3f0a4a3 100644 --- a/src/fs/fs_search.c +++ b/src/fs/fs_search.c @@ -74,7 +74,7 @@ GNUNET_FS_search_make_status_ (struct GNUNET_FS_ProgressInfo *pi, * GNUNET_OK otherwise */ static int -test_result_present (void *cls, const GNUNET_HashCode * key, void *value) +test_result_present (void *cls, const struct GNUNET_HashCode * key, void *value) { const struct GNUNET_FS_Uri *uri = cls; struct GNUNET_FS_SearchResult *sr = value; @@ -129,6 +129,8 @@ notify_client_chk_update (struct GNUNET_FS_SearchContext *sc, pi.value.search.specifics.update.availability_certainty = sr->availability_trials; pi.value.search.specifics.update.applicability_rank = sr->optional_support; + pi.value.search.specifics.update.current_probe_time + = GNUNET_TIME_absolute_get_duration (sr->probe_active_time); sr->client_info = GNUNET_FS_search_make_status_ (&pi, sc); } @@ -162,7 +164,7 @@ struct GetResultContext * @return GNUNET_OK */ static int -get_result_present (void *cls, const GNUNET_HashCode * key, void *value) +get_result_present (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GetResultContext *grc = cls; struct GNUNET_FS_SearchResult *sr = value; @@ -186,10 +188,13 @@ signal_probe_result (struct GNUNET_FS_SearchResult *sr) 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; - pi.value.search.specifics.update.availability_rank = sr->availability_success; - pi.value.search.specifics.update.availability_certainty = - sr->availability_trials; + pi.value.search.specifics.update.availability_rank + = 2 * sr->availability_success - sr->availability_trials; + pi.value.search.specifics.update.availability_certainty + = sr->availability_trials; pi.value.search.specifics.update.applicability_rank = sr->optional_support; + pi.value.search.specifics.update.current_probe_time + = GNUNET_TIME_absolute_get_duration (sr->probe_active_time); sr->client_info = GNUNET_FS_search_make_status_ (&pi, sr->sc); GNUNET_FS_search_start_probe_ (sr); } @@ -210,7 +215,16 @@ probe_failure_handler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) sr->availability_trials++; GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); sr->probe_ctx = NULL; + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_ping_task) + { + GNUNET_SCHEDULER_cancel (sr->probe_ping_task); + sr->probe_ping_task = GNUNET_SCHEDULER_NO_TASK; + } GNUNET_FS_search_result_sync_ (sr); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Probe #%u for search result %p failed\n", + sr->availability_trials, + sr); signal_probe_result (sr); } @@ -231,7 +245,16 @@ probe_success_handler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) sr->availability_success++; GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); sr->probe_ctx = NULL; + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_ping_task) + { + GNUNET_SCHEDULER_cancel (sr->probe_ping_task); + sr->probe_ping_task = GNUNET_SCHEDULER_NO_TASK; + } GNUNET_FS_search_result_sync_ (sr); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Probe #%u for search result %p succeeded\n", + sr->availability_trials, + sr); signal_probe_result (sr); } @@ -302,11 +325,19 @@ GNUNET_FS_search_probe_progress_ (void *cls, sr = NULL; break; case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sr->probe_cancel_task); - sr->probe_active_time = GNUNET_TIME_absolute_get (); - sr->probe_cancel_task = + if (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); + } + else + { + /* should only happen if the cancel task was already + created on 'DOWNLOAD_INACTIVE' as we were out of time */ + GNUNET_break (0 == sr->remaining_probe_time.rel_value); + } break; case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task) @@ -317,6 +348,9 @@ GNUNET_FS_search_probe_progress_ (void *cls, dur = GNUNET_TIME_absolute_get_duration (sr->probe_active_time); sr->remaining_probe_time = GNUNET_TIME_relative_subtract (sr->remaining_probe_time, dur); + if (0 == sr->remaining_probe_time.rel_value) + sr->probe_cancel_task = + GNUNET_SCHEDULER_add_now (&probe_failure_handler, sr); GNUNET_FS_search_result_sync_ (sr); break; default: @@ -328,6 +362,26 @@ GNUNET_FS_search_probe_progress_ (void *cls, /** + * Task run periodically to remind clients that a probe is active. + * + * @param cls the 'struct GNUNET_FS_SearchResult' that we are probing for + * @param tc scheduler context + */ +static void +probe_ping_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_FS_SearchResult *sr = cls; + + signal_probe_result (sr); + sr->probe_ping_task + = GNUNET_SCHEDULER_add_delayed (GNUNET_FS_PROBE_UPDATE_FREQUENCY, + &probe_ping_task, + sr); +} + + +/** * Start download probes for the given search result. * * @param sr the search result @@ -361,6 +415,11 @@ GNUNET_FS_search_start_probe_ (struct GNUNET_FS_SearchResult *sr) len = len - off; else len = DBLOCK_SIZE; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting probe #%u (at offset %llu) for search result %p\n", + sr->availability_trials + 1, + (unsigned long long) off, + sr); sr->remaining_probe_time = GNUNET_TIME_relative_multiply (sr->sc->h->avg_block_latency, 2 * (1 + sr->availability_trials)); @@ -369,6 +428,9 @@ GNUNET_FS_search_start_probe_ (struct GNUNET_FS_SearchResult *sr) len, sr->sc->anonymity, GNUNET_FS_DOWNLOAD_NO_TEMPORARIES | GNUNET_FS_DOWNLOAD_IS_PROBE, sr, NULL); + sr->probe_ping_task + = GNUNET_SCHEDULER_add_now (&probe_ping_task, + sr); } @@ -388,7 +450,7 @@ process_ksk_result (struct GNUNET_FS_SearchContext *sc, const struct GNUNET_FS_Uri *uri, const struct GNUNET_CONTAINER_MetaData *meta) { - GNUNET_HashCode key; + struct GNUNET_HashCode key; struct GNUNET_FS_SearchResult *sr; struct GetResultContext grc; int is_new; @@ -477,7 +539,7 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, const char *id_update, const struct GNUNET_CONTAINER_MetaData *meta) { struct GNUNET_FS_Uri uu; - GNUNET_HashCode key; + struct GNUNET_HashCode key; struct GNUNET_FS_SearchResult *sr; /* check if new */ @@ -505,7 +567,7 @@ process_sks_result (struct GNUNET_FS_SearchContext *sc, const char *id_update, if (0 == strlen (id_update)) return; /* no updates */ uu.type = sks; - uu.data.sks.namespace = sc->uri->data.sks.namespace; + uu.data.sks.ns = sc->uri->data.sks.ns; uu.data.sks.identifier = GNUNET_strdup (id_update); (void) search_start (sc->h, &uu, sc->anonymity, sc->options, NULL, sr); GNUNET_free (uu.data.sks.identifier); @@ -533,7 +595,7 @@ decrypt_block_with_keyword (const struct GNUNET_FS_SearchContext *sc, size_t edata_size, char *data) { - GNUNET_HashCode q; + struct GNUNET_HashCode q; struct GNUNET_CRYPTO_AesSessionKey skey; struct GNUNET_CRYPTO_AesInitializationVector iv; int i; @@ -543,7 +605,7 @@ decrypt_block_with_keyword (const struct GNUNET_FS_SearchContext *sc, &q); /* find key */ for (i = 0; i < sc->uri->data.ksk.keywordCount; i++) - if (0 == memcmp (&q, &sc->requests[i].query, sizeof (GNUNET_HashCode))) + if (0 == memcmp (&q, &sc->requests[i].query, sizeof (struct GNUNET_HashCode))) break; if (i == sc->uri->data.ksk.keywordCount) { @@ -671,13 +733,13 @@ process_nblock (struct GNUNET_FS_SearchContext *sc, const struct NBlock *nb, uri->data.sks.identifier = GNUNET_strdup (pt); GNUNET_CRYPTO_hash (&nb->subspace, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &uri->data.sks.namespace); + &uri->data.sks.ns); uris = GNUNET_FS_uri_to_string (uri); GNUNET_CONTAINER_meta_data_insert (meta, "<gnunet>", EXTRACTOR_METATYPE_URI, EXTRACTOR_METAFORMAT_UTF8, "text/plain", uris, strlen (uris) + 1); GNUNET_free (uris); - GNUNET_PSEUDONYM_add (sc->h->cfg, &uri->data.sks.namespace, meta); + GNUNET_PSEUDONYM_add (sc->h->cfg, &uri->data.sks.ns, meta); /* process */ process_ksk_result (sc, &sc->requests[i], uri, meta); @@ -708,7 +770,7 @@ process_sblock (struct GNUNET_FS_SearchContext *sc, const struct SBlock *sb, const char *uris; size_t off; char *emsg; - GNUNET_HashCode key; + struct GNUNET_HashCode key; char *identifier; /* decrypt */ @@ -762,7 +824,8 @@ process_sblock (struct GNUNET_FS_SearchContext *sc, const struct SBlock *sb, */ static void process_result (struct GNUNET_FS_SearchContext *sc, enum GNUNET_BLOCK_Type type, - struct GNUNET_TIME_Absolute expiration, const void *data, + struct GNUNET_TIME_Absolute expiration, + const void *data, size_t size) { if (GNUNET_TIME_absolute_get_duration (expiration).rel_value > 0) @@ -904,7 +967,7 @@ struct MessageBuilderContext /** * Where to store the keys. */ - GNUNET_HashCode *xoff; + struct GNUNET_HashCode *xoff; /** * Search context we are iterating for. @@ -928,7 +991,7 @@ struct MessageBuilderContext * @return GNUNET_OK to continue iterating */ static int -build_result_set (void *cls, const GNUNET_HashCode * key, void *value) +build_result_set (void *cls, const struct GNUNET_HashCode * key, void *value) { struct MessageBuilderContext *mbc = cls; struct GNUNET_FS_SearchResult *sr = value; @@ -960,7 +1023,7 @@ build_result_set (void *cls, const GNUNET_HashCode * key, void *value) * @return GNUNET_OK to continue iterating */ static int -find_result_set (void *cls, const GNUNET_HashCode * key, void *value) +find_result_set (void *cls, const struct GNUNET_HashCode * key, void *value) { struct MessageBuilderContext *mbc = cls; struct GNUNET_FS_SearchResult *sr = value; @@ -990,8 +1053,8 @@ transmit_search_request (void *cls, size_t size, void *buf) size_t msize; struct SearchMessage *sm; const char *identifier; - GNUNET_HashCode key; - GNUNET_HashCode idh; + struct GNUNET_HashCode key; + struct GNUNET_HashCode idh; unsigned int sqms; uint32_t options; @@ -1004,7 +1067,7 @@ transmit_search_request (void *cls, size_t size, void *buf) mbc.skip_cnt = sc->search_request_map_offset; sm = buf; sm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_START_SEARCH); - mbc.xoff = (GNUNET_HashCode *) & sm[1]; + mbc.xoff = (struct GNUNET_HashCode *) & sm[1]; options = SEARCH_MESSAGE_OPTION_NONE; if (0 != (sc->options & GNUNET_FS_SEARCH_OPTION_LOOPBACK_ONLY)) options |= SEARCH_MESSAGE_OPTION_LOOPBACK_ONLY; @@ -1013,24 +1076,26 @@ transmit_search_request (void *cls, size_t size, void *buf) msize = sizeof (struct SearchMessage); GNUNET_assert (size >= msize); mbc.keyword_offset = sc->keyword_offset; + /* calculate total number of known results (in put_cnt => sqms) */ mbc.put_cnt = 0; GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, &find_result_set, &mbc); sqms = mbc.put_cnt; - mbc.put_cnt = (size - msize) / sizeof (GNUNET_HashCode); + /* calculate how many results we can send in this message */ + mbc.put_cnt = (size - msize) / sizeof (struct GNUNET_HashCode); mbc.put_cnt = GNUNET_MIN (mbc.put_cnt, sqms - mbc.skip_cnt); if (sc->search_request_map_offset < sqms) GNUNET_assert (mbc.put_cnt > 0); + /* now build message */ + msize += sizeof (struct GNUNET_HashCode) * mbc.put_cnt; sm->header.size = htons (msize); sm->type = htonl (GNUNET_BLOCK_TYPE_ANY); sm->anonymity_level = htonl (sc->anonymity); - memset (&sm->target, 0, sizeof (GNUNET_HashCode)); + memset (&sm->target, 0, sizeof (struct GNUNET_HashCode)); sm->query = sc->requests[sc->keyword_offset].query; - msize += sizeof (GNUNET_HashCode) * mbc.put_cnt; GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, &build_result_set, &mbc); - sm->header.size = htons (msize); GNUNET_assert (sqms >= sc->search_request_map_offset); if (sqms != sc->search_request_map_offset) { @@ -1055,18 +1120,18 @@ transmit_search_request (void *cls, size_t size, void *buf) GNUNET_assert (size >= msize); sm->type = htonl (GNUNET_BLOCK_TYPE_FS_SBLOCK); sm->anonymity_level = htonl (sc->anonymity); - sm->target = sc->uri->data.sks.namespace; + sm->target = sc->uri->data.sks.ns; identifier = sc->uri->data.sks.identifier; GNUNET_CRYPTO_hash (identifier, strlen (identifier), &key); - GNUNET_CRYPTO_hash (&key, sizeof (GNUNET_HashCode), &idh); + GNUNET_CRYPTO_hash (&key, sizeof (struct GNUNET_HashCode), &idh); GNUNET_CRYPTO_hash_xor (&idh, &sm->target, &sm->query); - mbc.put_cnt = (size - msize) / sizeof (GNUNET_HashCode); + mbc.put_cnt = (size - msize) / sizeof (struct GNUNET_HashCode); sqms = GNUNET_CONTAINER_multihashmap_size (sc->master_result_map); mbc.put_cnt = GNUNET_MIN (mbc.put_cnt, sqms - mbc.skip_cnt); mbc.keyword_offset = 0; if (sc->search_request_map_offset < sqms) GNUNET_assert (mbc.put_cnt > 0); - msize += sizeof (GNUNET_HashCode) * mbc.put_cnt; + msize += sizeof (struct GNUNET_HashCode) * mbc.put_cnt; GNUNET_CONTAINER_multihashmap_iterate (sc->master_result_map, &build_result_set, &mbc); sm->header.size = htons (msize); @@ -1103,9 +1168,9 @@ schedule_transmit_search_request (struct GNUNET_FS_SearchContext *sc) sqms = GNUNET_CONTAINER_multihashmap_size (sc->master_result_map) - sc->search_request_map_offset; - fit = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - size) / sizeof (GNUNET_HashCode); + fit = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - size) / sizeof (struct GNUNET_HashCode); fit = GNUNET_MIN (fit, sqms); - size += sizeof (GNUNET_HashCode) * fit; + size += sizeof (struct GNUNET_HashCode) * fit; GNUNET_CLIENT_notify_transmit_ready (sc->client, size, GNUNET_CONSTANTS_SERVICE_TIMEOUT, GNUNET_NO, &transmit_search_request, sc); @@ -1155,8 +1220,10 @@ try_reconnect (struct GNUNET_FS_SearchContext *sc) GNUNET_CLIENT_disconnect (sc->client); sc->client = NULL; } + sc->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (sc->reconnect_backoff); sc->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &do_reconnect, + GNUNET_SCHEDULER_add_delayed (sc->reconnect_backoff, + &do_reconnect, sc); } @@ -1192,7 +1259,7 @@ search_start (struct GNUNET_FS_Handle *h, const struct GNUNET_FS_Uri *uri, sc->psearch_result = psearch; psearch->update_search = sc; } - sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16); + sc->master_result_map = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_NO); sc->client_info = cctx; if (GNUNET_OK != GNUNET_FS_search_start_searching_ (sc)) { @@ -1220,7 +1287,7 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc) { unsigned int i; const char *keyword; - GNUNET_HashCode hc; + struct GNUNET_HashCode hc; struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub; struct GNUNET_CRYPTO_RsaPrivateKey *pk; @@ -1246,7 +1313,7 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc) sc->requests[i].mandatory = (sc->uri->data.ksk.keywords[i][0] == '+'); if (sc->requests[i].mandatory) sc->mandatory_count++; - sc->requests[i].results = GNUNET_CONTAINER_multihashmap_create (4); + sc->requests[i].results = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO); GNUNET_CRYPTO_hash (keyword, strlen (keyword), &sc->requests[i].key); } } @@ -1267,7 +1334,7 @@ GNUNET_FS_search_start_searching_ (struct GNUNET_FS_SearchContext *sc) * @return GNUNET_OK */ static int -search_result_freeze_probes (void *cls, const GNUNET_HashCode * key, +search_result_freeze_probes (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GNUNET_FS_SearchResult *sr = value; @@ -1277,6 +1344,11 @@ search_result_freeze_probes (void *cls, const GNUNET_HashCode * key, GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); sr->probe_ctx = NULL; } + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_ping_task) + { + GNUNET_SCHEDULER_cancel (sr->probe_ping_task); + sr->probe_ping_task = GNUNET_SCHEDULER_NO_TASK; + } if (GNUNET_SCHEDULER_NO_TASK != sr->probe_cancel_task) { GNUNET_SCHEDULER_cancel (sr->probe_cancel_task); @@ -1297,7 +1369,7 @@ search_result_freeze_probes (void *cls, const GNUNET_HashCode * key, * @return GNUNET_OK */ static int -search_result_resume_probes (void *cls, const GNUNET_HashCode * key, +search_result_resume_probes (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GNUNET_FS_SearchResult *sr = value; @@ -1318,7 +1390,7 @@ search_result_resume_probes (void *cls, const GNUNET_HashCode * key, * @return GNUNET_OK */ static int -search_result_suspend (void *cls, const GNUNET_HashCode * key, void *value) +search_result_suspend (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GNUNET_FS_SearchContext *sc = cls; struct GNUNET_FS_SearchResult *sr = value; @@ -1334,6 +1406,11 @@ search_result_suspend (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); sr->probe_ctx = NULL; } + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_ping_task) + { + GNUNET_SCHEDULER_cancel (sr->probe_ping_task); + sr->probe_ping_task = GNUNET_SCHEDULER_NO_TASK; + } if (NULL != sr->update_search) { GNUNET_FS_search_signal_suspend_ (sr->update_search); @@ -1477,12 +1554,28 @@ GNUNET_FS_search_continue (struct GNUNET_FS_SearchContext *sc) * @return GNUNET_OK */ static int -search_result_stop (void *cls, const GNUNET_HashCode * key, void *value) +search_result_stop (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GNUNET_FS_SearchContext *sc = cls; struct GNUNET_FS_SearchResult *sr = value; struct GNUNET_FS_ProgressInfo pi; + if (NULL != sr->probe_ctx) + { + GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); + sr->probe_ctx = NULL; + } + if (GNUNET_SCHEDULER_NO_TASK != sr->probe_ping_task) + { + GNUNET_SCHEDULER_cancel (sr->probe_ping_task); + sr->probe_ping_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 (NULL != sr->download) { sr->download->search = NULL; @@ -1519,7 +1612,7 @@ search_result_stop (void *cls, const GNUNET_HashCode * key, void *value) * @return GNUNET_OK */ static int -search_result_free (void *cls, const GNUNET_HashCode * key, void *value) +search_result_free (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GNUNET_FS_SearchResult *sr = value; @@ -1528,14 +1621,13 @@ search_result_free (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_FS_search_stop (sr->update_search); GNUNET_assert (NULL == sr->update_search); } + GNUNET_break (NULL == sr->probe_ctx); + GNUNET_break (GNUNET_SCHEDULER_NO_TASK == sr->probe_cancel_task); + GNUNET_break (GNUNET_SCHEDULER_NO_TASK == sr->probe_ping_task); 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 (NULL != sr->probe_ctx) - GNUNET_FS_download_stop (sr->probe_ctx, GNUNET_YES); - 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); return GNUNET_OK; diff --git a/src/fs/fs_sharetree.c b/src/fs/fs_sharetree.c index c929428..5e96390 100644 --- a/src/fs/fs_sharetree.c +++ b/src/fs/fs_sharetree.c @@ -162,7 +162,7 @@ add_to_keyword_counter (void *cls, const char *keyword, int is_mandatory) { struct GNUNET_CONTAINER_MultiHashMap *mcm = cls; struct KeywordCounter *cnt; - GNUNET_HashCode hc; + struct GNUNET_HashCode hc; size_t klen; klen = strlen (keyword) + 1; @@ -206,7 +206,7 @@ add_to_meta_counter (void *cls, const char *plugin_name, const char *data_mime_type, const char *data, size_t data_len) { struct GNUNET_CONTAINER_MultiHashMap *map = cls; - GNUNET_HashCode key; + struct GNUNET_HashCode key; struct MetaCounter *cnt; GNUNET_CRYPTO_hash (data, data_len, &key); @@ -243,7 +243,7 @@ remove_high_frequency_keywords (void *cls, const char *keyword, int is_mandatory { struct TrimContext *tc = cls; struct KeywordCounter *counter; - GNUNET_HashCode hc; + struct GNUNET_HashCode hc; size_t klen; klen = strlen (keyword) + 1; @@ -268,7 +268,7 @@ remove_high_frequency_keywords (void *cls, const char *keyword, int is_mandatory * @return GNUNET_YES (always) */ static int -migrate_and_drop_keywords (void *cls, const GNUNET_HashCode * key, void *value) +migrate_and_drop_keywords (void *cls, const struct GNUNET_HashCode * key, void *value) { struct TrimContext *tc = cls; struct KeywordCounter *counter = value; @@ -299,7 +299,7 @@ migrate_and_drop_keywords (void *cls, const GNUNET_HashCode * key, void *value) * @return GNUNET_YES (always) */ static int -migrate_and_drop_metadata (void *cls, const GNUNET_HashCode * key, void *value) +migrate_and_drop_metadata (void *cls, const struct GNUNET_HashCode * key, void *value) { struct TrimContext *tc = cls; struct MetaCounter *counter = value; @@ -415,8 +415,8 @@ GNUNET_FS_share_tree_trim (struct GNUNET_FS_ShareTreeItem *toplevel) if (toplevel == NULL) return; - tc.keywordcounter = GNUNET_CONTAINER_multihashmap_create (1024); - tc.metacounter = GNUNET_CONTAINER_multihashmap_create (1024); + tc.keywordcounter = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO); + tc.metacounter = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO); share_tree_trim (&tc, toplevel); GNUNET_CONTAINER_multihashmap_destroy (tc.keywordcounter); GNUNET_CONTAINER_multihashmap_destroy (tc.metacounter); diff --git a/src/fs/fs_test_lib.c b/src/fs/fs_test_lib.c index 06ab01f..758220f 100644 --- a/src/fs/fs_test_lib.c +++ b/src/fs/fs_test_lib.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010, 2011 Christian Grothoff (and other contributing authors) + (C) 2010, 2011, 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 @@ -20,8 +20,8 @@ /** * @file fs/fs_test_lib.c - * @brief library routines for testing FS publishing and downloading - * with multiple peers; this code is limited to flat files + * @brief library routines for testing FS publishing and downloading; + * this code is limited to flat files * and no keywords (those functions can be tested with * single-peer setups; this is for testing routing). * @author Christian Grothoff @@ -29,23 +29,21 @@ #include "platform.h" #include "fs_api.h" #include "fs_test_lib.h" -#include "gnunet_testing_lib.h" -#define CONNECT_ATTEMPTS 4 #define CONTENT_LIFETIME GNUNET_TIME_UNIT_HOURS + /** - * Handle for a daemon started for testing FS. + * Handle for a publishing operation started for testing FS. */ -struct GNUNET_FS_TestDaemon +struct TestPublishOperation { /** - * Global configuration, only stored in first test daemon, - * otherwise NULL. + * Handle for the operation to connect to the peer's 'fs' service. */ - struct GNUNET_CONFIGURATION_Handle *gcfg; + struct GNUNET_TESTBED_Operation *fs_op; /** * Handle to the file sharing context using this daemon. @@ -53,27 +51,6 @@ struct GNUNET_FS_TestDaemon struct GNUNET_FS_Handle *fs; /** - * Handle to the daemon via testing. - */ - struct GNUNET_TESTING_Daemon *daemon; - - /** - * Note that 'group' will be the same value for all of the - * daemons started jointly. - */ - struct GNUNET_TESTING_PeerGroup *group; - - /** - * Configuration for accessing this peer. - */ - struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * ID of this peer. - */ - struct GNUNET_PeerIdentity id; - - /** * Function to call when upload is done. */ GNUNET_FS_TEST_UriContinuation publish_cont; @@ -109,6 +86,49 @@ struct GNUNET_FS_TestDaemon char *publish_tmp_file; /** + * Size of the file. + */ + uint64_t size; + + /** + * Anonymity level used. + */ + uint32_t anonymity; + + /** + * Verbosity level of the current operation. + */ + unsigned int verbose; + + /** + * Are we testing indexing? (YES: index, NO: insert, SYSERR: simulate) + */ + int do_index; +}; + + +/** + * Handle for a download operation started for testing FS. + */ +struct TestDownloadOperation +{ + + /** + * Handle for the operation to connect to the peer's 'fs' service. + */ + struct GNUNET_TESTBED_Operation *fs_op; + + /** + * Handle to the file sharing context using this daemon. + */ + struct GNUNET_FS_Handle *fs; + + /** + * Handle to the daemon via testing. + */ + struct GNUNET_TESTING_Daemon *daemon; + + /** * Function to call when download is done. */ GNUNET_SCHEDULER_Task download_cont; @@ -119,9 +139,9 @@ struct GNUNET_FS_TestDaemon void *download_cont_cls; /** - * Seed for download verification. + * URI to download. */ - uint32_t download_seed; + struct GNUNET_FS_Uri *uri; /** * Task to abort downloading (timeout). @@ -134,107 +154,114 @@ struct GNUNET_FS_TestDaemon struct GNUNET_FS_DownloadContext *download_context; /** - * Verbosity level of the current operation. + * Size of the file. */ - int verbose; + uint64_t size; + /** + * Anonymity level used. + */ + uint32_t anonymity; -}; + /** + * Seed for download verification. + */ + uint32_t download_seed; -/** - * Check whether peers successfully shut down. - */ -static void -shutdown_callback (void *cls, const char *emsg) -{ - struct GNUNET_CONFIGURATION_Handle *gcfg = cls; + /** + * Verbosity level of the current operation. + */ + unsigned int verbose; - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Shutdown of peers failed: %s\n", - emsg); - } - else - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); -#endif - } - if (gcfg != NULL) - GNUNET_CONFIGURATION_destroy (gcfg); -} +}; +/** + * Task scheduled to report on the completion of our publish operation. + * + * @param cls the publish operation context + * @param tc scheduler context (unused) + */ static void -report_uri (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +report_uri (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_FS_TestDaemon *daemon = cls; - GNUNET_FS_TEST_UriContinuation cont; - struct GNUNET_FS_Uri *uri; - - GNUNET_FS_publish_stop (daemon->publish_context); - daemon->publish_context = NULL; - cont = daemon->publish_cont; - daemon->publish_cont = NULL; - uri = daemon->publish_uri; - cont (daemon->publish_cont_cls, uri); - GNUNET_FS_uri_destroy (uri); + struct TestPublishOperation *po = cls; + + GNUNET_FS_publish_stop (po->publish_context); + GNUNET_TESTBED_operation_done (po->fs_op); + po->publish_cont (po->publish_cont_cls, + po->publish_uri, + (GNUNET_YES == po->do_index) + ? po->publish_tmp_file + : NULL); + GNUNET_FS_uri_destroy (po->publish_uri); + if (GNUNET_YES != po->do_index) + (void) GNUNET_DISK_directory_remove (po->publish_tmp_file); + GNUNET_free_non_null (po->publish_tmp_file); + GNUNET_free (po); } +/** + * Task scheduled to run when publish operation times out. + * + * @param cls the publish operation context + * @param tc scheduler context (unused) + */ static void -report_success (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +publish_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_FS_TestDaemon *daemon = cls; + struct TestPublishOperation *po = cls; - GNUNET_FS_download_stop (daemon->download_context, GNUNET_YES); - daemon->download_context = NULL; - GNUNET_SCHEDULER_add_continuation (daemon->download_cont, - daemon->download_cont_cls, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); - daemon->download_cont = NULL; + po->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Timeout while trying to publish data\n"); + if (NULL == po->fs) + GNUNET_TESTBED_operation_done (po->fs_op); + else + GNUNET_TESTBED_operation_done (po->fs_op); + GNUNET_FS_publish_stop (po->publish_context); + po->publish_cont (po->publish_cont_cls, NULL, NULL); + (void) GNUNET_DISK_directory_remove (po->publish_tmp_file); + GNUNET_free_non_null (po->publish_tmp_file); + GNUNET_free (po); } +/** + * Progress callback for file-sharing events while publishing. + * + * @param cls the publish operation context + * @param info information about the event + */ static void * -progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) +publish_progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) { - struct GNUNET_FS_TestDaemon *daemon = cls; + struct TestPublishOperation *po = cls; switch (info->status) { case GNUNET_FS_STATUS_PUBLISH_COMPLETED: - GNUNET_SCHEDULER_cancel (daemon->publish_timeout_task); - daemon->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK; - daemon->publish_uri = + GNUNET_SCHEDULER_cancel (po->publish_timeout_task); + po->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK; + po->publish_uri = GNUNET_FS_uri_dup (info->value.publish.specifics.completed.chk_uri); - GNUNET_SCHEDULER_add_continuation (&report_uri, daemon, + GNUNET_SCHEDULER_add_continuation (&report_uri, po, GNUNET_SCHEDULER_REASON_PREREQ_DONE); break; case GNUNET_FS_STATUS_PUBLISH_PROGRESS: - if (daemon->verbose) + if (po->verbose) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Publishing at %llu/%llu bytes\n", (unsigned long long) info->value.publish.completed, (unsigned long long) info->value.publish.size); break; case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: - if (daemon->verbose) + if (po->verbose) GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Download at %llu/%llu bytes\n", (unsigned long long) info->value.download.completed, (unsigned long long) info->value.download.size); break; - case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: - GNUNET_SCHEDULER_cancel (daemon->download_timeout_task); - daemon->download_timeout_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_SCHEDULER_add_continuation (&report_success, daemon, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); - break; - case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: - case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: - break; - /* FIXME: monitor data correctness during download progress */ - /* FIXME: do performance reports given sufficient verbosity */ - /* FIXME: advance timeout task to "immediate" on error */ default: break; } @@ -242,460 +269,351 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) } -struct StartContext -{ - struct GNUNET_TIME_Relative timeout; - unsigned int total; - unsigned int have; - struct GNUNET_FS_TestDaemon **daemons; - GNUNET_SCHEDULER_Task cont; - void *cont_cls; - struct GNUNET_TESTING_PeerGroup *group; - struct GNUNET_CONFIGURATION_Handle *cfg; - GNUNET_SCHEDULER_TaskIdentifier timeout_task; -}; - - -static void -notify_running (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) +/** + * Generate test data for publishing test. + * + * @param cls pointer to uint32_t with publishing seed + * @param offset offset to generate data for + * @param max maximum number of bytes to generate + * @param buf where to write generated data + * @param emsg where to store error message (unused) + * @return number of bytes written to buf + */ +static size_t +file_generator (void *cls, + uint64_t offset, + size_t max, + void *buf, + char **emsg) { - struct StartContext *sctx = cls; - unsigned int i; + uint32_t *publish_seed = cls; + uint64_t pos; + uint8_t *cbuf = buf; + int mod; if (emsg != NULL) + *emsg = NULL; + if (buf == NULL) + return 0; + for (pos = 0; pos < 8; pos++) + cbuf[pos] = (uint8_t) (offset >> pos * 8); + for (pos = 8; pos < max; pos++) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to start daemon: %s\n"), - emsg); - return; - } - i = 0; - while (i < sctx->total) - { - if (GNUNET_TESTING_daemon_get (sctx->group, i) == d) - break; - i++; - } - GNUNET_assert (i < sctx->total); - GNUNET_assert (sctx->have < sctx->total); - GNUNET_assert (sctx->daemons[i]->cfg == NULL); - sctx->daemons[i]->cfg = GNUNET_CONFIGURATION_dup (cfg); - sctx->daemons[i]->group = sctx->group; - sctx->daemons[i]->daemon = d; - sctx->daemons[i]->id = *id; - sctx->have++; - if (sctx->have == sctx->total) - { - GNUNET_SCHEDULER_add_continuation (sctx->cont, sctx->cont_cls, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); - sctx->daemons[0]->gcfg = sctx->cfg; - GNUNET_SCHEDULER_cancel (sctx->timeout_task); - for (i = 0; i < sctx->total; i++) - { - sctx->daemons[i]->fs = - GNUNET_FS_start (sctx->daemons[i]->cfg, "<tester>", &progress_cb, - sctx->daemons[i], GNUNET_FS_FLAGS_NONE, - GNUNET_FS_OPTIONS_END); - } - GNUNET_free (sctx); + mod = (255 - (offset / 1024 / 32)); + if (mod == 0) + mod = 1; + cbuf[pos] = (uint8_t) ((offset * (*publish_seed)) % mod); } + return max; } -static void -start_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +/** + * Connect adapter for publishing operation. + * + * @param cls the 'struct TestPublishOperation' + * @param cfg configuration of the peer to connect to; will be available until + * GNUNET_TESTBED_operation_done() is called on the operation returned + * from GNUNET_TESTBED_service_connect() + * @return service handle to return in 'op_result', NULL on error + */ +static void * +publish_connect_adapter (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg) { - struct StartContext *sctx = cls; - unsigned int i; - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Timeout while trying to start daemons\n"); - GNUNET_TESTING_daemons_stop (sctx->group, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 30), - &shutdown_callback, NULL); - for (i = 0; i < sctx->total; i++) - { - if (i < sctx->have) - GNUNET_CONFIGURATION_destroy (sctx->daemons[i]->cfg); - GNUNET_free (sctx->daemons[i]); - sctx->daemons[i] = NULL; - } - GNUNET_CONFIGURATION_destroy (sctx->cfg); - GNUNET_SCHEDULER_add_continuation (sctx->cont, sctx->cont_cls, - GNUNET_SCHEDULER_REASON_TIMEOUT); - GNUNET_free (sctx); + struct TestPublishOperation *po = cls; + + return GNUNET_FS_start (cfg, + "fs-test-publish", + &publish_progress_cb, po, + GNUNET_FS_FLAGS_NONE, + GNUNET_FS_OPTIONS_END); } /** - * Start daemons for testing. - * - * @param template_cfg_file configuration template to use - * @param timeout if this operation cannot be completed within the - * given period, call the continuation with an error code - * @param total number of daemons to start - * @param daemons array of 'total' entries to be initialized - * (array must already be allocated, will be filled) - * @param cont function to call when done - * @param cont_cls closure for cont + * Adapter function called to destroy connection to file-sharing service. + * + * @param cls the 'struct GNUNET_FS_Handle' + * @param op_result unused (different for publish/download!) */ -void -GNUNET_FS_TEST_daemons_start (const char *template_cfg_file, - struct GNUNET_TIME_Relative timeout, - unsigned int total, - struct GNUNET_FS_TestDaemon **daemons, - GNUNET_SCHEDULER_Task cont, void *cont_cls) +static void +fs_disconnect_adapter (void *cls, + void *op_result) { - struct StartContext *sctx; - unsigned int i; - - GNUNET_assert (total > 0); - sctx = GNUNET_malloc (sizeof (struct StartContext)); - sctx->daemons = daemons; - sctx->total = total; - sctx->cont = cont; - sctx->cont_cls = cont_cls; - sctx->cfg = GNUNET_CONFIGURATION_create (); - if (GNUNET_OK != GNUNET_CONFIGURATION_load (sctx->cfg, template_cfg_file)) - { - GNUNET_break (0); - GNUNET_CONFIGURATION_destroy (sctx->cfg); - GNUNET_free (sctx); - GNUNET_SCHEDULER_add_continuation (cont, cont_cls, - GNUNET_SCHEDULER_REASON_TIMEOUT); - return; - } - for (i = 0; i < total; i++) - daemons[i] = GNUNET_malloc (sizeof (struct GNUNET_FS_TestDaemon)); - sctx->group = GNUNET_TESTING_daemons_start (sctx->cfg, total, total, /* Outstanding connections */ - total, /* Outstanding ssh connections */ - timeout, NULL, NULL, - ¬ify_running, sctx, NULL, NULL, - NULL); - sctx->timeout_task = - GNUNET_SCHEDULER_add_delayed (timeout, &start_timeout, sctx); -} + struct GNUNET_FS_Handle *fs = op_result; - -struct GNUNET_FS_TEST_ConnectContext -{ - GNUNET_SCHEDULER_Task cont; - void *cont_cls; - struct GNUNET_TESTING_ConnectContext *cc; -}; + GNUNET_FS_stop (fs); +} /** - * Prototype of a function that will be called whenever - * two daemons are connected by the testing library. + * Callback to be called when testbed has connected to the fs service * - * @param cls closure - * @param first peer id for first daemon - * @param second peer id for the second daemon - * @param distance distance between the connected peers - * @param first_cfg config for the first daemon - * @param second_cfg config for the second daemon - * @param first_daemon handle for the first daemon - * @param second_daemon handle for the second daemon - * @param emsg error message (NULL on success) + * @param cls the 'struct TestPublishOperation' + * @param op the operation that has been finished + * @param ca_result the 'struct GNUNET_FS_Handle ' (NULL on error) + * @param emsg error message in case the operation has failed; will be NULL if + * operation has executed successfully. */ static void -notify_connection (void *cls, const struct GNUNET_PeerIdentity *first, - const struct GNUNET_PeerIdentity *second, uint32_t distance, - const struct GNUNET_CONFIGURATION_Handle *first_cfg, - const struct GNUNET_CONFIGURATION_Handle *second_cfg, - struct GNUNET_TESTING_Daemon *first_daemon, - struct GNUNET_TESTING_Daemon *second_daemon, - const char *emsg) +publish_fs_connect_complete_cb (void *cls, + struct GNUNET_TESTBED_Operation *op, + void *ca_result, + const char *emsg) { - struct GNUNET_FS_TEST_ConnectContext *cc = cls; + struct TestPublishOperation *po = cls; + struct GNUNET_FS_FileInformation *fi; + struct GNUNET_DISK_FileHandle *fh; + char *em; + uint64_t off; + char buf[DBLOCK_SIZE]; + size_t bsize; + struct GNUNET_FS_BlockOptions bo; - cc->cc = NULL; - if (emsg != NULL) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to connect peers: %s\n", - emsg); - GNUNET_SCHEDULER_add_continuation (cc->cont, cc->cont_cls, - (emsg != - NULL) ? GNUNET_SCHEDULER_REASON_TIMEOUT : - GNUNET_SCHEDULER_REASON_PREREQ_DONE); - GNUNET_free (cc); + if (NULL == ca_result) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to connect to FS for publishing: %s\n", emsg); + po->publish_cont (po->publish_cont_cls, + NULL, NULL); + GNUNET_TESTBED_operation_done (po->fs_op); + GNUNET_free (po); + return; + } + po->fs = ca_result; + + bo.expiration_time = GNUNET_TIME_relative_to_absolute (CONTENT_LIFETIME); + bo.anonymity_level = po->anonymity; + bo.content_priority = 42; + bo.replication_level = 1; + if (GNUNET_YES == po->do_index) + { + po->publish_tmp_file = GNUNET_DISK_mktemp ("fs-test-publish-index"); + GNUNET_assert (po->publish_tmp_file != NULL); + fh = GNUNET_DISK_file_open (po->publish_tmp_file, + GNUNET_DISK_OPEN_WRITE | + GNUNET_DISK_OPEN_CREATE, + GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); + GNUNET_assert (NULL != fh); + off = 0; + while (off < po->size) + { + bsize = GNUNET_MIN (sizeof (buf), po->size - off); + emsg = NULL; + GNUNET_assert (bsize == file_generator (&po->publish_seed, off, bsize, buf, &em)); + GNUNET_assert (em == NULL); + GNUNET_assert (bsize == GNUNET_DISK_file_write (fh, buf, bsize)); + off += bsize; + } + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); + fi = GNUNET_FS_file_information_create_from_file (po->fs, po, + po->publish_tmp_file, + NULL, NULL, po->do_index, + &bo); + } + else + { + fi = GNUNET_FS_file_information_create_from_reader (po->fs, po, + po->size, + &file_generator, &po->publish_seed, + NULL, NULL, + po->do_index, &bo); + } + po->publish_context = + GNUNET_FS_publish_start (po->fs, fi, NULL, NULL, NULL, + GNUNET_FS_PUBLISH_OPTION_NONE); } /** - * Connect two daemons for testing. + * Publish a file at the given peer. * - * @param daemon1 first daemon to connect - * @param daemon2 second first daemon to connect + * @param peer where to publish * @param timeout if this operation cannot be completed within the * given period, call the continuation with an error code + * @param anonymity option for publication + * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, + * GNUNET_SYSERR for simulation + * @param size size of the file to publish + * @param seed seed to use for file generation + * @param verbose how verbose to be in reporting * @param cont function to call when done * @param cont_cls closure for cont */ -struct GNUNET_FS_TEST_ConnectContext * -GNUNET_FS_TEST_daemons_connect (struct GNUNET_FS_TestDaemon *daemon1, - struct GNUNET_FS_TestDaemon *daemon2, - struct GNUNET_TIME_Relative timeout, - GNUNET_SCHEDULER_Task cont, void *cont_cls) +void +GNUNET_FS_TEST_publish (struct GNUNET_TESTBED_Peer *peer, + struct GNUNET_TIME_Relative timeout, uint32_t anonymity, + int do_index, uint64_t size, uint32_t seed, + unsigned int verbose, + GNUNET_FS_TEST_UriContinuation cont, void *cont_cls) { - struct GNUNET_FS_TEST_ConnectContext *ncc; - - ncc = GNUNET_malloc (sizeof (struct GNUNET_FS_TEST_ConnectContext)); - ncc->cont = cont; - ncc->cont_cls = cont_cls; - ncc->cc = - GNUNET_TESTING_daemons_connect (daemon1->daemon, daemon2->daemon, timeout, - CONNECT_ATTEMPTS, GNUNET_YES, - ¬ify_connection, ncc); - return ncc; + struct TestPublishOperation *po; + + po = GNUNET_malloc (sizeof (struct TestPublishOperation)); + po->publish_cont = cont; + po->publish_cont_cls = cont_cls; + po->publish_seed = seed; + po->anonymity = anonymity; + po->size = size; + po->verbose = verbose; + po->do_index = do_index; + po->fs_op = GNUNET_TESTBED_service_connect (po, + peer, + "fs", + &publish_fs_connect_complete_cb, + po, + &publish_connect_adapter, + &fs_disconnect_adapter, + po); + po->publish_timeout_task = + GNUNET_SCHEDULER_add_delayed (timeout, &publish_timeout, po); } -/** - * Cancel connect operation. - * - * @param cc operation to cancel - */ -void -GNUNET_FS_TEST_daemons_connect_cancel (struct GNUNET_FS_TEST_ConnectContext *cc) -{ - GNUNET_TESTING_daemons_connect_cancel (cc->cc); - GNUNET_free (cc); -} +/* ************************** download ************************ */ /** - * Obtain peer configuration used for testing. + * Task scheduled to run when download operation times out. * - * @param daemons array with the daemons - * @param off which configuration to get - * @return peer configuration + * @param cls the download operation context + * @param tc scheduler context (unused) */ -const struct GNUNET_CONFIGURATION_Handle * -GNUNET_FS_TEST_get_configuration (struct GNUNET_FS_TestDaemon **daemons, - unsigned int off) +static void +download_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - return daemons[off]->cfg; -} + struct TestDownloadOperation *dop = cls; -/** - * Obtain peer group used for testing. - * - * @param daemons array with the daemons (must contain at least one) - * @return peer group - */ -struct GNUNET_TESTING_PeerGroup * -GNUNET_FS_TEST_get_group (struct GNUNET_FS_TestDaemon **daemons) -{ - return daemons[0]->group; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Timeout while trying to download file\n"); + dop->download_timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_FS_download_stop (dop->download_context, GNUNET_YES); + GNUNET_SCHEDULER_add_continuation (dop->download_cont, + dop->download_cont_cls, + GNUNET_SCHEDULER_REASON_TIMEOUT); + if (NULL == dop->fs) + GNUNET_TESTBED_operation_done (dop->fs_op); + else + GNUNET_TESTBED_operation_done (dop->fs_op); + GNUNET_FS_uri_destroy (dop->uri); + GNUNET_free (dop); } /** - * Stop daemons used for testing. + * Task scheduled to report on the completion of our download operation. * - * @param total number of daemons to stop - * @param daemons array with the daemons (values will be clobbered) + * @param cls the download operation context + * @param tc scheduler context (unused) */ -void -GNUNET_FS_TEST_daemons_stop (unsigned int total, - struct GNUNET_FS_TestDaemon **daemons) -{ - unsigned int i; - struct GNUNET_TESTING_PeerGroup *pg; - struct GNUNET_CONFIGURATION_Handle *gcfg; - struct GNUNET_FS_TestDaemon *daemon; - - GNUNET_assert (total > 0); - GNUNET_assert (daemons[0] != NULL); - pg = daemons[0]->group; - gcfg = daemons[0]->gcfg; - for (i = 0; i < total; i++) - { - daemon = daemons[i]; - if (daemon->download_timeout_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (daemon->download_timeout_task); - daemon->download_timeout_task = GNUNET_SCHEDULER_NO_TASK; - } - if (daemon->publish_timeout_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (daemon->publish_timeout_task); - daemon->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK; - } - if (NULL != daemon->download_context) - { - GNUNET_FS_download_stop (daemon->download_context, GNUNET_YES); - daemon->download_context = NULL; - } - if (daemon->fs != NULL) - GNUNET_FS_stop (daemon->fs); - if (daemon->cfg != NULL) - GNUNET_CONFIGURATION_destroy (daemon->cfg); - if (NULL != daemon->publish_tmp_file) - { - GNUNET_break (GNUNET_OK == - GNUNET_DISK_directory_remove (daemon->publish_tmp_file)); - GNUNET_free (daemon->publish_tmp_file); - daemon->publish_tmp_file = NULL; - } - GNUNET_free (daemon); - daemons[i] = NULL; - } - GNUNET_TESTING_daemons_stop (pg, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 30), - &shutdown_callback, gcfg); -} - - static void -publish_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +report_success (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_FS_TestDaemon *daemon = cls; - GNUNET_FS_TEST_UriContinuation cont; + struct TestDownloadOperation *dop = cls; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Timeout while trying to publish data\n"); - cont = daemon->publish_cont; - daemon->publish_timeout_task = GNUNET_SCHEDULER_NO_TASK; - daemon->publish_cont = NULL; - GNUNET_FS_publish_stop (daemon->publish_context); - daemon->publish_context = NULL; - cont (daemon->publish_cont_cls, NULL); + GNUNET_FS_download_stop (dop->download_context, GNUNET_YES); + GNUNET_SCHEDULER_add_continuation (dop->download_cont, + dop->download_cont_cls, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + GNUNET_TESTBED_operation_done (dop->fs_op); + GNUNET_FS_uri_destroy (dop->uri); + GNUNET_free (dop); } -static size_t -file_generator (void *cls, uint64_t offset, size_t max, void *buf, char **emsg) +/** + * Progress callback for file-sharing events while downloading. + * + * @param cls the download operation context + * @param info information about the event + */ +static void * +download_progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) { - struct GNUNET_FS_TestDaemon *daemon = cls; - uint64_t pos; - uint8_t *cbuf = buf; - int mod; + struct TestDownloadOperation *dop = cls; - if (emsg != NULL) - *emsg = NULL; - if (buf == NULL) - return 0; - for (pos = 0; pos < 8; pos++) - cbuf[pos] = (uint8_t) (offset >> pos * 8); - for (pos = 8; pos < max; pos++) + switch (info->status) { - mod = (255 - (offset / 1024 / 32)); - if (mod == 0) - mod = 1; - cbuf[pos] = (uint8_t) ((offset * daemon->publish_seed) % mod); + case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: + if (dop->verbose) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Download at %llu/%llu bytes\n", + (unsigned long long) info->value.download.completed, + (unsigned long long) info->value.download.size); + break; + case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: + GNUNET_SCHEDULER_cancel (dop->download_timeout_task); + dop->download_timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_SCHEDULER_add_continuation (&report_success, dop, + GNUNET_SCHEDULER_REASON_PREREQ_DONE); + break; + case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: + case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: + break; + /* FIXME: monitor data correctness during download progress */ + /* FIXME: do performance reports given sufficient verbosity */ + /* FIXME: advance timeout task to "immediate" on error */ + default: + break; } - return max; + return NULL; } - /** - * Publish a file at the given daemon. - * - * @param daemon where to publish - * @param timeout if this operation cannot be completed within the - * given period, call the continuation with an error code - * @param anonymity option for publication - * @param do_index GNUNET_YES for index, GNUNET_NO for insertion, - * GNUNET_SYSERR for simulation - * @param size size of the file to publish - * @param seed seed to use for file generation - * @param verbose how verbose to be in reporting - * @param cont function to call when done - * @param cont_cls closure for cont + * Connect adapter for download operation. + * + * @param cls the 'struct TestDownloadOperation' + * @param cfg configuration of the peer to connect to; will be available until + * GNUNET_TESTBED_operation_done() is called on the operation returned + * from GNUNET_TESTBED_service_connect() + * @return service handle to return in 'op_result', NULL on error */ -void -GNUNET_FS_TEST_publish (struct GNUNET_FS_TestDaemon *daemon, - struct GNUNET_TIME_Relative timeout, uint32_t anonymity, - int do_index, uint64_t size, uint32_t seed, - unsigned int verbose, - GNUNET_FS_TEST_UriContinuation cont, void *cont_cls) +static void * +download_connect_adapter (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg) { - struct GNUNET_FS_FileInformation *fi; - struct GNUNET_DISK_FileHandle *fh; - char *emsg; - uint64_t off; - char buf[DBLOCK_SIZE]; - size_t bsize; - struct GNUNET_FS_BlockOptions bo; - - GNUNET_assert (daemon->publish_cont == NULL); - daemon->publish_cont = cont; - daemon->publish_cont_cls = cont_cls; - daemon->publish_seed = seed; - daemon->verbose = verbose; - bo.expiration_time = GNUNET_TIME_relative_to_absolute (CONTENT_LIFETIME); - bo.anonymity_level = anonymity; - bo.content_priority = 42; - bo.replication_level = 1; - if (GNUNET_YES == do_index) - { - GNUNET_assert (daemon->publish_tmp_file == NULL); - daemon->publish_tmp_file = GNUNET_DISK_mktemp ("fs-test-publish-index"); - GNUNET_assert (daemon->publish_tmp_file != NULL); - fh = GNUNET_DISK_file_open (daemon->publish_tmp_file, - GNUNET_DISK_OPEN_WRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - GNUNET_assert (NULL != fh); - off = 0; - while (off < size) - { - bsize = GNUNET_MIN (sizeof (buf), size - off); - emsg = NULL; - GNUNET_assert (bsize == file_generator (daemon, off, bsize, buf, &emsg)); - GNUNET_assert (emsg == NULL); - GNUNET_assert (bsize == GNUNET_DISK_file_write (fh, buf, bsize)); - off += bsize; - } - GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh)); - fi = GNUNET_FS_file_information_create_from_file (daemon->fs, daemon, - daemon->publish_tmp_file, - NULL, NULL, do_index, - &bo); - } - else - { - fi = GNUNET_FS_file_information_create_from_reader (daemon->fs, daemon, - size, &file_generator, - daemon, NULL, NULL, - do_index, &bo); - } - daemon->publish_context = - GNUNET_FS_publish_start (daemon->fs, fi, NULL, NULL, NULL, - GNUNET_FS_PUBLISH_OPTION_NONE); - daemon->publish_timeout_task = - GNUNET_SCHEDULER_add_delayed (timeout, &publish_timeout, daemon); + struct TestPublishOperation *po = cls; + + return GNUNET_FS_start (cfg, + "fs-test-download", + &download_progress_cb, po, + GNUNET_FS_FLAGS_NONE, + GNUNET_FS_OPTIONS_END); } +/** + * Callback to be called when testbed has connected to the fs service + * + * @param cls the 'struct TestPublishOperation' + * @param op the operation that has been finished + * @param ca_result the 'struct GNUNET_FS_Handle ' (NULL on error) + * @param emsg error message in case the operation has failed; will be NULL if + * operation has executed successfully. + */ static void -download_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +download_fs_connect_complete_cb (void *cls, + struct GNUNET_TESTBED_Operation *op, + void *ca_result, + const char *emsg) { - struct GNUNET_FS_TestDaemon *daemon = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Timeout while trying to download file\n"); - daemon->download_timeout_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_FS_download_stop (daemon->download_context, GNUNET_YES); - daemon->download_context = NULL; - GNUNET_SCHEDULER_add_continuation (daemon->download_cont, - daemon->download_cont_cls, - GNUNET_SCHEDULER_REASON_TIMEOUT); - daemon->download_cont = NULL; + struct TestDownloadOperation *dop = cls; + + dop->fs = ca_result; + GNUNET_assert (NULL != dop->fs); + dop->download_context = + GNUNET_FS_download_start (dop->fs, dop->uri, NULL, NULL, NULL, 0, dop->size, + dop->anonymity, GNUNET_FS_DOWNLOAD_OPTION_NONE, + NULL, NULL); } /** * Perform test download. * - * @param daemon which peer to download from + * @param peer which peer to download from * @param timeout if this operation cannot be completed within the * given period, call the continuation with an error code * @param anonymity option for download @@ -706,26 +624,34 @@ download_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param cont_cls closure for cont */ void -GNUNET_FS_TEST_download (struct GNUNET_FS_TestDaemon *daemon, +GNUNET_FS_TEST_download (struct GNUNET_TESTBED_Peer *peer, struct GNUNET_TIME_Relative timeout, uint32_t anonymity, uint32_t seed, const struct GNUNET_FS_Uri *uri, unsigned int verbose, GNUNET_SCHEDULER_Task cont, void *cont_cls) { - uint64_t size; - - GNUNET_assert (daemon->download_cont == NULL); - size = GNUNET_FS_uri_chk_get_file_size (uri); - daemon->verbose = verbose; - daemon->download_cont = cont; - daemon->download_cont_cls = cont_cls; - daemon->download_seed = seed; - daemon->download_context = - GNUNET_FS_download_start (daemon->fs, uri, NULL, NULL, NULL, 0, size, - anonymity, GNUNET_FS_DOWNLOAD_OPTION_NONE, NULL, - NULL); - daemon->download_timeout_task = - GNUNET_SCHEDULER_add_delayed (timeout, &download_timeout, daemon); + struct TestDownloadOperation *dop; + + dop = GNUNET_malloc (sizeof (struct TestDownloadOperation)); + dop->uri = GNUNET_FS_uri_dup (uri); + dop->size = GNUNET_FS_uri_chk_get_file_size (uri); + dop->verbose = verbose; + dop->anonymity = anonymity; + dop->download_cont = cont; + dop->download_cont_cls = cont_cls; + dop->download_seed = seed; + + dop->fs_op = GNUNET_TESTBED_service_connect (dop, + peer, + "fs", + &download_fs_connect_complete_cb, + dop, + &download_connect_adapter, + &fs_disconnect_adapter, + dop); + dop->download_timeout_task = + GNUNET_SCHEDULER_add_delayed (timeout, &download_timeout, dop); } -/* end of test_fs_lib.c */ + +/* end of fs_test_lib.c */ diff --git a/src/fs/fs_test_lib.h b/src/fs/fs_test_lib.h index 81125ca..679e074 100644 --- a/src/fs/fs_test_lib.h +++ b/src/fs/fs_test_lib.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010 Christian Grothoff (and other contributing authors) + (C) 2010, 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 @@ -20,8 +20,8 @@ /** * @file fs/fs_test_lib.h - * @brief library routines for testing FS publishing and downloading - * with multiple peers; this code is limited to flat files + * @brief library routines for testing FS publishing and downloading; + * this code is limited to flat files * and no keywords (those functions can be tested with * single-peer setups; this is for testing routing). * @author Christian Grothoff @@ -31,97 +31,7 @@ #include "gnunet_util_lib.h" #include "gnunet_fs_service.h" - -/** - * Handle for a daemon started for testing FS. - */ -struct GNUNET_FS_TestDaemon; - - -/** - * Start daemons for testing. - * - * @param template_cfg_file configuration template to use - * @param timeout if this operation cannot be completed within the - * given period, call the continuation with an error code - * @param total number of daemons to start - * @param daemons array of 'total' entries to be initialized - * (array must already be allocated, will be filled) - * @param cont function to call when done; note that if 'cont' - * is called with reason "TIMEOUT", then starting the - * daemons has failed and the client MUST NOT call - * 'GNUNET_FS_TEST_daemons_stop'! - * @param cont_cls closure for cont - */ -void -GNUNET_FS_TEST_daemons_start (const char *template_cfg_file, - struct GNUNET_TIME_Relative timeout, - unsigned int total, - struct GNUNET_FS_TestDaemon **daemons, - GNUNET_SCHEDULER_Task cont, void *cont_cls); - - -struct GNUNET_FS_TEST_ConnectContext; - - -/** - * Connect two daemons for testing. - * - * @param daemon1 first daemon to connect - * @param daemon2 second first daemon to connect - * @param timeout if this operation cannot be completed within the - * given period, call the continuation with an error code - * @param cont function to call when done - * @param cont_cls closure for cont - */ -struct GNUNET_FS_TEST_ConnectContext * -GNUNET_FS_TEST_daemons_connect (struct GNUNET_FS_TestDaemon *daemon1, - struct GNUNET_FS_TestDaemon *daemon2, - struct GNUNET_TIME_Relative timeout, - GNUNET_SCHEDULER_Task cont, void *cont_cls); - - -/** - * Cancel connect operation. - * - * @param cc operation to cancel - */ -void -GNUNET_FS_TEST_daemons_connect_cancel (struct GNUNET_FS_TEST_ConnectContext - *cc); - - -/** - * Obtain peer group used for testing. - * - * @param daemons array with the daemons (must contain at least one) - * @return peer group - */ -struct GNUNET_TESTING_PeerGroup * -GNUNET_FS_TEST_get_group (struct GNUNET_FS_TestDaemon **daemons); - - - -/** - * Obtain peer configuration used for testing. - * - * @param daemons array with the daemons - * @param off which configuration to get - * @return peer configuration - */ -const struct GNUNET_CONFIGURATION_Handle * -GNUNET_FS_TEST_get_configuration (struct GNUNET_FS_TestDaemon **daemons, - unsigned int off); - -/** - * Stop daemons used for testing. - * - * @param total number of daemons to stop - * @param daemons array with the daemons (values will be clobbered) - */ -void -GNUNET_FS_TEST_daemons_stop (unsigned int total, - struct GNUNET_FS_TestDaemon **daemons); +#include "gnunet_testbed_service.h" /** @@ -129,16 +39,19 @@ GNUNET_FS_TEST_daemons_stop (unsigned int total, * * @param cls closure (user defined) * @param uri a URI, NULL for errors + * @param fn name of the file on disk to be removed upon + * completion, or NULL for inserted files (also NULL on error) */ typedef void (*GNUNET_FS_TEST_UriContinuation) (void *cls, const struct GNUNET_FS_Uri * - uri); + uri, + const char *fn); /** * Publish a file at the given daemon. * - * @param daemon where to publish + * @param peer where to publish * @param timeout if this operation cannot be completed within the * given period, call the continuation with an error code * @param anonymity option for publication @@ -151,7 +64,7 @@ typedef void (*GNUNET_FS_TEST_UriContinuation) (void *cls, * @param cont_cls closure for cont */ void -GNUNET_FS_TEST_publish (struct GNUNET_FS_TestDaemon *daemon, +GNUNET_FS_TEST_publish (struct GNUNET_TESTBED_Peer *peer, struct GNUNET_TIME_Relative timeout, uint32_t anonymity, int do_index, uint64_t size, uint32_t seed, unsigned int verbose, @@ -161,7 +74,7 @@ GNUNET_FS_TEST_publish (struct GNUNET_FS_TestDaemon *daemon, /** * Perform test download. * - * @param daemon which peer to download from + * @param peer which peer to download from * @param timeout if this operation cannot be completed within the * given period, call the continuation with an error code * @param anonymity option for download @@ -172,7 +85,7 @@ GNUNET_FS_TEST_publish (struct GNUNET_FS_TestDaemon *daemon, * @param cont_cls closure for cont */ void -GNUNET_FS_TEST_download (struct GNUNET_FS_TestDaemon *daemon, +GNUNET_FS_TEST_download (struct GNUNET_TESTBED_Peer *peer, struct GNUNET_TIME_Relative timeout, uint32_t anonymity, uint32_t seed, const struct GNUNET_FS_Uri *uri, unsigned int verbose, diff --git a/src/fs/fs_test_lib_data.conf b/src/fs/fs_test_lib_data.conf index e6c2abd..89b89aa 100644 --- a/src/fs/fs_test_lib_data.conf +++ b/src/fs/fs_test_lib_data.conf @@ -8,4 +8,10 @@ WAN_QUOTA_OUT = 3932160 [datastore] QUOTA = 2 GB +#PLUGIN = heap +# +#[fs] +#DELAY = YES +[testbed] +OVERLAY_TOPOLOGY = CLIQUE diff --git a/src/fs/fs_unindex.c b/src/fs/fs_unindex.c index 6910321..2217603 100644 --- a/src/fs/fs_unindex.c +++ b/src/fs/fs_unindex.c @@ -341,12 +341,13 @@ unindex_directory_scan_cb (void *cls, { 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 { + uc->emsg = GNUNET_strdup (_("Failed to get KSKs from directory scan.")); + GNUNET_FS_unindex_sync_ (uc); unindex_finish (uc); } GNUNET_FS_share_tree_free (directory_scan_result); @@ -355,11 +356,15 @@ unindex_directory_scan_cb (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Internal error scanning `%s'.\n"), uc->filename); + GNUNET_FS_directory_scan_abort (uc->dscan); + uc->dscan = NULL; + uc->emsg = GNUNET_strdup (_("Failed to get KSKs from directory scan.")); + GNUNET_FS_unindex_sync_ (uc); + unindex_finish (uc); break; default: break; } - } @@ -437,7 +442,7 @@ continue_after_remove (void *cls, */ static void process_kblock_for_unindex (void *cls, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, size_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, @@ -649,7 +654,7 @@ GNUNET_FS_unindex_do_remove_ (struct GNUNET_FS_UnindexContext *uc) * @param file_id computed hash, NULL on error */ void -GNUNET_FS_unindex_process_hash_ (void *cls, const GNUNET_HashCode * file_id) +GNUNET_FS_unindex_process_hash_ (void *cls, const struct GNUNET_HashCode * file_id) { struct GNUNET_FS_UnindexContext *uc = cls; diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c index 0c2d64c..fa6d411 100644 --- a/src/fs/fs_uri.c +++ b/src/fs/fs_uri.c @@ -98,7 +98,7 @@ * @param key wherer to store the unique key */ void -GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, GNUNET_HashCode * key) +GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, struct GNUNET_HashCode * key) { switch (uri->type) { @@ -121,7 +121,7 @@ GNUNET_FS_uri_to_key (const struct GNUNET_FS_Uri *uri, GNUNET_HashCode * key) key); break; default: - memset (key, 0, sizeof (GNUNET_HashCode)); + memset (key, 0, sizeof (struct GNUNET_HashCode)); break; } } @@ -217,7 +217,8 @@ percent_decode_keyword (const char *in, char **emsg) if (1 != SSCANF (&out[rpos + 1], "%2X", &hx)) { GNUNET_free (out); - *emsg = GNUNET_strdup (_("`%' must be followed by HEX number")); + *emsg = GNUNET_strdup (_(/* xgettext:no-c-format */ + "`%' must be followed by HEX number")); return NULL; } rpos += 3; @@ -355,7 +356,7 @@ static struct GNUNET_FS_Uri * uri_sks_parse (const char *s, char **emsg) { struct GNUNET_FS_Uri *ret; - GNUNET_HashCode namespace; + struct GNUNET_HashCode ns; char *identifier; unsigned int pos; size_t slen; @@ -374,7 +375,7 @@ uri_sks_parse (const char *s, char **emsg) } memcpy (enc, &s[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); enc[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0'; - if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (enc, &namespace)) + if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (enc, &ns)) { *emsg = GNUNET_strdup (_("Malformed SKS URI")); return NULL; @@ -383,7 +384,7 @@ uri_sks_parse (const char *s, char **emsg) GNUNET_strdup (&s[pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)]); ret = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); ret->type = sks; - ret->data.sks.namespace = namespace; + ret->data.sks.ns = ns; ret->data.sks.identifier = identifier; return ret; } @@ -903,8 +904,7 @@ GNUNET_FS_uri_loc_create (const struct GNUNET_FS_Uri *baseUri, _("Lacking key configuration settings.\n")); return NULL; } - my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); - if (my_private_key == NULL) + if (NULL == (my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not access hostkey file `%s'.\n"), keyfile); @@ -949,7 +949,7 @@ GNUNET_FS_uri_sks_create (struct GNUNET_FS_Namespace *ns, const char *id, ns_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); ns_uri->type = sks; GNUNET_CRYPTO_rsa_key_get_public (ns->key, &pk); - GNUNET_CRYPTO_hash (&pk, sizeof (pk), &ns_uri->data.sks.namespace); + GNUNET_CRYPTO_hash (&pk, sizeof (pk), &ns_uri->data.sks.ns); ns_uri->data.sks.identifier = GNUNET_strdup (id); return ns_uri; } @@ -963,13 +963,13 @@ GNUNET_FS_uri_sks_create (struct GNUNET_FS_Namespace *ns, const char *id, * @return an FS URI for the given namespace and identifier */ struct GNUNET_FS_Uri * -GNUNET_FS_uri_sks_create_from_nsid (GNUNET_HashCode * nsid, const char *id) +GNUNET_FS_uri_sks_create_from_nsid (struct GNUNET_HashCode * nsid, const char *id) { struct GNUNET_FS_Uri *ns_uri; ns_uri = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri)); ns_uri->type = sks; - ns_uri->data.sks.namespace = *nsid; + ns_uri->data.sks.ns = *nsid; ns_uri->data.sks.identifier = GNUNET_strdup (id); return ns_uri; } @@ -1272,8 +1272,8 @@ GNUNET_FS_uri_test_equal (const struct GNUNET_FS_Uri *u1, return GNUNET_NO; case sks: if ((0 == - memcmp (&u1->data.sks.namespace, &u2->data.sks.namespace, - sizeof (GNUNET_HashCode))) && + memcmp (&u1->data.sks.ns, &u2->data.sks.ns, + sizeof (struct GNUNET_HashCode))) && (0 == strcmp (u1->data.sks.identifier, u2->data.sks.identifier))) return GNUNET_YES; @@ -1334,14 +1334,14 @@ GNUNET_FS_uri_test_sks (const struct GNUNET_FS_Uri *uri) */ int GNUNET_FS_uri_sks_get_namespace (const struct GNUNET_FS_Uri *uri, - GNUNET_HashCode * nsid) + struct GNUNET_HashCode * nsid) { if (!GNUNET_FS_uri_test_sks (uri)) { GNUNET_break (0); return GNUNET_SYSERR; } - *nsid = uri->data.sks.namespace; + *nsid = uri->data.sks.ns; return GNUNET_OK; } @@ -1382,9 +1382,9 @@ GNUNET_FS_uri_sks_to_string_fancy (struct GNUNET_CONFIGURATION_Handle *cfg, if (uri->type != sks) return NULL; - (void) GNUNET_PSEUDONYM_get_info (cfg, &uri->data.sks.namespace, + (void) GNUNET_PSEUDONYM_get_info (cfg, &uri->data.sks.ns, NULL, NULL, &name, NULL); - unique_name = GNUNET_PSEUDONYM_name_uniquify (cfg, &uri->data.sks.namespace, name, NULL); + unique_name = GNUNET_PSEUDONYM_name_uniquify (cfg, &uri->data.sks.ns, name, NULL); GNUNET_free (name); GNUNET_asprintf (&ret, "%s: %s", unique_name, uri->data.sks.identifier); GNUNET_free (unique_name); @@ -1665,7 +1665,7 @@ get_keywords_from_parens (const char *s, char **array, int index) /** * Where to break up keywords */ -#define TOKENS "_. /-!?#&+@\"\'\\;:," +#define TOKENS "_. /-!?#&+@\"\'\\;:,()[]{}$<>|" /** * Break the filename up by TOKENS to make @@ -1907,7 +1907,7 @@ uri_ksk_to_string (const struct GNUNET_FS_Uri *uri) continue; /* skip leading space */ if (needs_percent (keyword[j])) { - sprintf (&ret[wpos], "%%%02X", keyword[j]); + sprintf (&ret[wpos], "%%%02X", (unsigned char) keyword[j]); wpos += 3; } else @@ -1931,18 +1931,18 @@ uri_ksk_to_string (const struct GNUNET_FS_Uri *uri) static char * uri_sks_to_string (const struct GNUNET_FS_Uri *uri) { - const GNUNET_HashCode *namespace; + const struct GNUNET_HashCode *ns; const char *identifier; char *ret; - struct GNUNET_CRYPTO_HashAsciiEncoded ns; + struct GNUNET_CRYPTO_HashAsciiEncoded nsasc; if (uri->type != sks) return NULL; - namespace = &uri->data.sks.namespace; + ns = &uri->data.sks.ns; identifier = uri->data.sks.identifier; - GNUNET_CRYPTO_hash_to_enc (namespace, &ns); + GNUNET_CRYPTO_hash_to_enc (ns, &nsasc); GNUNET_asprintf (&ret, "%s%s%s/%s", GNUNET_FS_URI_PREFIX, - GNUNET_FS_URI_SKS_INFIX, (const char *) &ns, identifier); + GNUNET_FS_URI_SKS_INFIX, (const char *) &nsasc, identifier); return ret; } diff --git a/src/fs/gnunet-auto-share.c b/src/fs/gnunet-auto-share.c new file mode 100644 index 0000000..86cab55 --- /dev/null +++ b/src/fs/gnunet-auto-share.c @@ -0,0 +1,795 @@ +/* + This file is part of GNUnet. + (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 + 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/gnunet-auto-share.c + * @brief automatically publish files on GNUnet + * @author Christian Grothoff + * + * TODO: + * - support loading meta data / keywords from resource file + * - add stability timer (a la buildbot) + */ +#include "platform.h" +#include "gnunet_util_lib.h" + +#define MIN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) + +#define MAX_FREQUENCY GNUNET_TIME_UNIT_MINUTES + + +/** + * Item in our work queue (or in the set of files/directories + * we have successfully published). + */ +struct WorkItem +{ + + /** + * PENDING Work is kept in a linked list. + */ + struct WorkItem *prev; + + /** + * PENDING Work is kept in a linked list. + */ + struct WorkItem *next; + + /** + * Filename of the work item. + */ + char *filename; + + /** + * Unique identity for this work item (used to detect + * if we need to do the work again). + */ + struct GNUNET_HashCode id; +}; + + +/** + * Global return value from 'main'. + */ +static int ret; + +/** + * Are we running 'verbosely'? + */ +static int verbose; + +/** + * Configuration to use. + */ +static const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Name of the configuration file. + */ +static char *cfg_filename; + +/** + * Disable extractor option to use for publishing. + */ +static int disable_extractor; + +/** + * Disable creation time option to use for publishing. + */ +static int do_disable_creation_time; + +/** + * Handle for the 'shutdown' task. + */ +static GNUNET_SCHEDULER_TaskIdentifier kill_task; + +/** + * Handle for the main task that does scanning and working. + */ +static GNUNET_SCHEDULER_TaskIdentifier run_task; + +/** + * Anonymity level option to use for publishing. + */ +static unsigned int anonymity_level = 1; + +/** + * Content priority option to use for publishing. + */ +static unsigned int content_priority = 365; + +/** + * Replication level option to use for publishing. + */ +static unsigned int replication_level = 1; + +/** + * Top-level directory we monitor to auto-publish. + */ +static const char *dir_name; + +/** + * Head of linked list of files still to publish. + */ +static struct WorkItem *work_head; + +/** + * Tail of linked list of files still to publish. + */ +static struct WorkItem *work_tail; + +/** + * Map from the hash of the filename (!) to a 'struct WorkItem' + * that was finished. + */ +static struct GNUNET_CONTAINER_MultiHashMap *work_finished; + +/** + * Set to GNUNET_YES if we are shutting down. + */ +static int do_shutdown; + +/** + * Start time of the current round; used to determine how long + * one iteration takes (which influences how fast we schedule + * the next one). + */ +static struct GNUNET_TIME_Absolute start_time; + +/** + * Pipe used to communicate 'gnunet-publish' completion (SIGCHLD) via signal. + */ +static struct GNUNET_DISK_PipeHandle *sigpipe; + +/** + * Handle to the 'gnunet-publish' process that we executed. + */ +static struct GNUNET_OS_Process *publish_proc; + + +/** + * Compute the name of the state database file we will use. + */ +static char * +get_state_file () +{ + char *ret; + + GNUNET_asprintf (&ret, + "%s%s.auto-share", + dir_name, + (DIR_SEPARATOR == dir_name[strlen(dir_name)-1]) ? "" : DIR_SEPARATOR_STR); + return ret; +} + + +/** + * Load the set of 'work_finished' items from disk. + */ +static void +load_state () +{ + char *fn; + struct GNUNET_BIO_ReadHandle *rh; + uint32_t n; + struct GNUNET_HashCode id; + struct WorkItem *wi; + char *emsg; + + emsg = NULL; + fn = get_state_file (); + rh = GNUNET_BIO_read_open (fn); + GNUNET_free (fn); + if (NULL == rh) + return; + fn = NULL; + if (GNUNET_OK != GNUNET_BIO_read_int32 (rh, &n)) + goto error; + while (n-- > 0) + { + if ( (GNUNET_OK != + GNUNET_BIO_read_string (rh, "filename", &fn, 1024)) || + (GNUNET_OK != + GNUNET_BIO_read (rh, "id", &id, sizeof (struct GNUNET_HashCode))) ) + goto error; + wi = GNUNET_malloc (sizeof (struct WorkItem)); + wi->id = id; + wi->filename = fn; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Loaded serialization ID for `%s' is `%s'\n", + wi->filename, + GNUNET_h2s (&id)); + fn = NULL; + GNUNET_CRYPTO_hash (wi->filename, + strlen (wi->filename), + &id); + GNUNET_CONTAINER_multihashmap_put (work_finished, + &id, + wi, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); + } + if (GNUNET_OK == + GNUNET_BIO_read_close (rh, &emsg)) + return; + rh = NULL; + error: + GNUNET_free_non_null (fn); + if (NULL != rh) + (void) GNUNET_BIO_read_close (rh, &emsg); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to load state: %s\n"), + emsg); + GNUNET_free_non_null (emsg); +} + + +/** + * Write work item from the work_finished map to the given write handle. + * + * @param cls the 'struct GNUNET_BIO_WriteHandle*' + * @param key key of the item in the map (unused) + * @param value the 'struct WorkItem' to write + * @return GNUNET_OK to continue to iterate (if write worked) + */ +static int +write_item (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct GNUNET_BIO_WriteHandle *wh = cls; + struct WorkItem *wi = value; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Saving serialization ID of file `%s' with value `%s'\n", + wi->filename, + GNUNET_h2s (&wi->id)); + if ( (GNUNET_OK != + GNUNET_BIO_write_string (wh, wi->filename)) || + (GNUNET_OK != + GNUNET_BIO_write (wh, + &wi->id, + sizeof (struct GNUNET_HashCode))) ) + return GNUNET_SYSERR; /* write error, abort iteration */ + return GNUNET_OK; +} + + +/** + * Save the set of 'work_finished' items on disk. + */ +static void +save_state () +{ + uint32_t n; + struct GNUNET_BIO_WriteHandle *wh; + char *fn; + + n = GNUNET_CONTAINER_multihashmap_size (work_finished); + fn = get_state_file (); + wh = GNUNET_BIO_write_open (fn); + if (NULL == wh) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to save state to file %s\n"), + fn); + GNUNET_free (fn); + return; + } + if (GNUNET_OK != + GNUNET_BIO_write_int32 (wh, n)) + { + (void) GNUNET_BIO_write_close (wh); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to save state to file %s\n"), + fn); + GNUNET_free (fn); + return; + } + (void) GNUNET_CONTAINER_multihashmap_iterate (work_finished, + &write_item, + wh); + if (GNUNET_OK != GNUNET_BIO_write_close (wh)) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to save state to file %s\n"), + fn); + GNUNET_free (fn); +} + + +/** + * Task run on shutdown. Serializes our current state to disk. + * + * @param cls closure, unused + * @param tc scheduler context, unused + */ +static void +do_stop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + kill_task = GNUNET_SCHEDULER_NO_TASK; + do_shutdown = GNUNET_YES; + if (NULL != publish_proc) + { + GNUNET_OS_process_kill (publish_proc, SIGKILL); + return; + } + if (GNUNET_SCHEDULER_NO_TASK != run_task) + { + GNUNET_SCHEDULER_cancel (run_task); + run_task = GNUNET_SCHEDULER_NO_TASK; + } +} + + +/** + * Decide what the next task is (working or scanning) and schedule it. + */ +static void +schedule_next_task (void); + + +/** + * Task triggered whenever we receive a SIGCHLD (child + * process died). + * + * @param cls the 'struct WorkItem' we were working on + * @param tc context + */ +static void +maint_child_death (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct WorkItem *wi = cls; + struct GNUNET_HashCode key; + enum GNUNET_OS_ProcessStatusType type; + unsigned long code; + int ret; + char c; + const struct GNUNET_DISK_FileHandle *pr; + + + run_task = GNUNET_SCHEDULER_NO_TASK; + pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); + if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) + { + /* shutdown scheduled us, ignore! */ + run_task = + GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, + pr, &maint_child_death, wi); + return; + } + + ret = GNUNET_OS_process_status (publish_proc, + &type, + &code); + GNUNET_assert (GNUNET_SYSERR != ret); + if (GNUNET_NO == ret) + { + GNUNET_break (0); + GNUNET_OS_process_kill (publish_proc, SIGKILL); + type = GNUNET_OS_PROCESS_SIGNALED; + } + GNUNET_OS_process_destroy (publish_proc); + publish_proc = NULL; + /* consume the signal */ + GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c))); + + if (GNUNET_YES == do_shutdown) + { + GNUNET_free (wi->filename); + GNUNET_free (wi); + return; + } + if ( (GNUNET_OS_PROCESS_EXITED == type) && + (0 == code) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Publication of `%s' done\n"), + wi->filename); + GNUNET_CRYPTO_hash (wi->filename, + strlen (wi->filename), + &key); + GNUNET_CONTAINER_multihashmap_put (work_finished, + &key, + wi, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); + } + else + { + GNUNET_CONTAINER_DLL_insert_tail (work_head, + work_tail, + wi); + } + save_state (); + schedule_next_task (); +} + + +/** + * Signal handler called for SIGCHLD. Triggers the + * respective handler by writing to the trigger pipe. + */ +static void +sighandler_child_death () +{ + static char c; + int old_errno = errno; /* back-up errno */ + + GNUNET_break (1 == + GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle + (sigpipe, GNUNET_DISK_PIPE_END_WRITE), + &c, sizeof (c))); + errno = old_errno; /* restore errno */ +} + + +/** + * Function called to process work items. + * + * @param cls closure, NULL + * @param tc scheduler context (unused) + */ +static void +work (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + static char *argv[14]; + static char anon_level[20]; + static char content_prio[20]; + static char repl_level[20]; + struct WorkItem *wi; + const struct GNUNET_DISK_FileHandle *pr; + int argc; + + run_task = GNUNET_SCHEDULER_NO_TASK; + wi = work_head; + GNUNET_CONTAINER_DLL_remove (work_head, + work_tail, + wi); + argc = 0; + argv[argc++] = "gnunet-publish"; + if (verbose) + argv[argc++] = "-V"; + if (disable_extractor) + argv[argc++] = "-D"; + if (do_disable_creation_time) + argv[argc++] = "-d"; + argv[argc++] = "-c"; + argv[argc++] = cfg_filename; + GNUNET_snprintf (anon_level, sizeof (anon_level), + "%u", anonymity_level); + argv[argc++] = "-a"; + argv[argc++] = anon_level; + GNUNET_snprintf (content_prio, sizeof (content_prio), + "%u", content_priority); + argv[argc++] = "-p"; + argv[argc++] = content_prio; + GNUNET_snprintf (repl_level, sizeof (repl_level), + "%u", replication_level); + argv[argc++] = "-r"; + argv[argc++] = repl_level; + argv[argc++] = wi->filename; + argv[argc] = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Publishing `%s'\n"), + wi->filename); + publish_proc = GNUNET_OS_start_process_vap (GNUNET_YES, + 0, NULL, NULL, + "gnunet-publish", + argv); + if (NULL == publish_proc) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to run `%s'\n"), + "gnunet-publish"); + GNUNET_CONTAINER_DLL_insert (work_head, + work_tail, + wi); + run_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, + &work, + NULL); + return; + } + pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ); + run_task = + GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, + pr, &maint_child_death, wi); +} + + +/** + * Recursively scan the given file/directory structure to determine + * a unique ID that represents the current state of the hierarchy. + * + * @param cls where to store the unique ID we are computing + * @param filename file to scan + * @return GNUNET_OK (always) + */ +static int +determine_id (void *cls, + const char *filename) +{ + struct GNUNET_HashCode *id = cls; + struct stat sbuf; + struct GNUNET_HashCode fx[2]; + struct GNUNET_HashCode ft; + + if (0 != STAT (filename, &sbuf)) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "stat", filename); + return GNUNET_OK; + } + GNUNET_CRYPTO_hash (filename, strlen (filename), &fx[0]); + if (!S_ISDIR (sbuf.st_mode)) + { + uint64_t fattr[2]; + + fattr[0] = GNUNET_htonll (sbuf.st_size); + fattr[0] = GNUNET_htonll (sbuf.st_mtime); + + GNUNET_CRYPTO_hash (fattr, sizeof (fattr), &fx[1]); + } + else + { + memset (&fx[1], 1, sizeof (struct GNUNET_HashCode)); + GNUNET_DISK_directory_scan (filename, + &determine_id, + &fx[1]); + } + /* use hash here to make hierarchical structure distinct from + all files on the same level */ + GNUNET_CRYPTO_hash (fx, sizeof (fx), &ft); + /* use XOR here so that order of the files in the directory + does not matter! */ + GNUNET_CRYPTO_hash_xor (&ft, id, id); + return GNUNET_OK; +} + + +/** + * Function called with a filename (or directory name) to publish + * (if it has changed since the last time we published it). This function + * is called for the top-level files only. + * + * @param cls closure, NULL + * @param filename complete filename (absolute path) + * @return GNUNET_OK to continue to iterate, GNUNET_SYSERR during shutdown + */ +static int +add_file (void *cls, + const char *filename) +{ + struct WorkItem *wi; + struct GNUNET_HashCode key; + struct GNUNET_HashCode id; + + if (GNUNET_YES == do_shutdown) + return GNUNET_SYSERR; + if ( (NULL != strstr (filename, + "/.auto-share")) || + (NULL != strstr (filename, + "\\.auto-share")) ) + return GNUNET_OK; /* skip internal file */ + GNUNET_CRYPTO_hash (filename, + strlen (filename), + &key); + wi = GNUNET_CONTAINER_multihashmap_get (work_finished, + &key); + memset (&id, 0, sizeof (struct GNUNET_HashCode)); + determine_id (&id, filename); + if (NULL != wi) + { + if (0 == memcmp (&id, + &wi->id, + sizeof (struct GNUNET_HashCode))) + return GNUNET_OK; /* skip: we did this one already */ + /* contents changed, need to re-do the directory... */ + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (work_finished, + &key, + wi)); + } + else + { + wi = GNUNET_malloc (sizeof (struct WorkItem)); + wi->filename = GNUNET_strdup (filename); + } + wi->id = id; + GNUNET_CONTAINER_DLL_insert (work_head, + work_tail, + wi); + if (GNUNET_YES == do_shutdown) + return GNUNET_SYSERR; + return GNUNET_OK; +} + + +/** + * Periodically run task to update our view of the directory to share. + * + * @param cls NULL + * @param tc scheduler context, unused + */ +static void +scan (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + run_task = GNUNET_SCHEDULER_NO_TASK; + start_time = GNUNET_TIME_absolute_get (); + (void) GNUNET_DISK_directory_scan (dir_name, + &add_file, + NULL); + schedule_next_task (); +} + + +/** + * Decide what the next task is (working or scanning) and schedule it. + */ +static void +schedule_next_task () +{ + struct GNUNET_TIME_Relative delay; + + if (GNUNET_YES == do_shutdown) + return; + if (NULL == work_head) + { + /* delay by at most 4h, at least 1s, and otherwise in between depending + on how long it took to scan */ + delay = GNUNET_TIME_absolute_get_duration (start_time); + delay = GNUNET_TIME_relative_min (MIN_FREQUENCY, + GNUNET_TIME_relative_multiply (delay, + 100)); + delay = GNUNET_TIME_relative_max (delay, + MAX_FREQUENCY); + run_task = GNUNET_SCHEDULER_add_delayed (delay, + &scan, + NULL); + } + else + { + run_task = GNUNET_SCHEDULER_add_now (&work, NULL); + } +} + + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param c configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + /* check arguments */ + if ((args[0] == NULL) || (args[1] != NULL) || + (GNUNET_YES != GNUNET_DISK_directory_test (args[0], GNUNET_YES))) + { + printf (_("You must specify one and only one directory name for automatic publication.\n")); + ret = -1; + return; + } + cfg_filename = GNUNET_strdup (cfgfile); + cfg = c; + dir_name = args[0]; + work_finished = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO); + load_state (); + run_task = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, + &scan, NULL); + + kill_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &do_stop_task, + NULL); +} + + +/** + * Free memory associated with the work item from the work_finished map. + * + * @param cls NULL (unused) + * @param key key of the item in the map (unused) + * @param value the 'struct WorkItem' to free + * @return GNUNET_OK to continue to iterate + */ +static int +free_item (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct WorkItem *wi = value; + + GNUNET_free (wi->filename); + GNUNET_free (wi); + return GNUNET_OK; +} + + +/** + * The main function to automatically publish content to GNUnet. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'a', "anonymity", "LEVEL", + gettext_noop ("set the desired LEVEL of sender-anonymity"), + 1, &GNUNET_GETOPT_set_uint, &anonymity_level}, + {'d', "disable-creation-time", NULL, + gettext_noop + ("disable adding the creation time to the metadata of the uploaded file"), + 0, &GNUNET_GETOPT_set_one, &do_disable_creation_time}, + {'D', "disable-extractor", NULL, + gettext_noop ("do not use libextractor to add keywords or metadata"), + 0, &GNUNET_GETOPT_set_one, &disable_extractor}, + {'p', "priority", "PRIORITY", + gettext_noop ("specify the priority of the content"), + 1, &GNUNET_GETOPT_set_uint, &content_priority}, + {'r', "replication", "LEVEL", + gettext_noop ("set the desired replication LEVEL"), + 1, &GNUNET_GETOPT_set_uint, &replication_level}, + {'V', "verbose", NULL, + gettext_noop ("be verbose (print progress information)"), + 0, &GNUNET_GETOPT_set_one, &verbose}, + GNUNET_GETOPT_OPTION_END + }; + struct WorkItem *wi; + int ok; + struct GNUNET_SIGNAL_Context *shc_chld; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO); + GNUNET_assert (sigpipe != NULL); + shc_chld = + GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD, &sighandler_child_death); + ok = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-auto-share [OPTIONS] FILENAME", + gettext_noop + ("Automatically publish files from a directory on GNUnet"), + options, &run, NULL)) ? ret : 1; + if (NULL != work_finished) + { + (void) GNUNET_CONTAINER_multihashmap_iterate (work_finished, + &free_item, + NULL); + GNUNET_CONTAINER_multihashmap_destroy (work_finished); + } + while (NULL != (wi = work_head)) + { + GNUNET_CONTAINER_DLL_remove (work_head, work_tail, wi); + GNUNET_free (wi->filename); + GNUNET_free (wi); + } + GNUNET_SIGNAL_handler_uninstall (shc_chld); + shc_chld = NULL; + GNUNET_DISK_pipe_close (sigpipe); + sigpipe = NULL; + GNUNET_free (cfg_filename); + cfg_filename = NULL; + GNUNET_free ((void*) argv); + return ok; +} + +/* end of gnunet-auto-share.c */ diff --git a/src/fs/gnunet-daemon-fsprofiler.c b/src/fs/gnunet-daemon-fsprofiler.c new file mode 100644 index 0000000..16a74b8 --- /dev/null +++ b/src/fs/gnunet-daemon-fsprofiler.c @@ -0,0 +1,660 @@ +/* + This file is part of GNUnet. + (C) 2012 Christian Grothoff + + 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/gnunet-daemon-fsprofiler.c + * @brief daemon that publishes and downloads (random) files + * @author Christian Grothoff + * + * TODO: + * - how to signal driver that we're done? + */ +#include "platform.h" +#include "gnunet_fs_service.h" +#include "gnunet_statistics_service.h" + +/** + * We use 'patterns' of the form (x,y,t) to specify desired download/publish + * activities of a peer. They are stored in a DLL. + */ +struct Pattern +{ + /** + * Kept in a DLL. + */ + struct Pattern *next; + + /** + * Kept in a DLL. + */ + struct Pattern *prev; + + /** + * Execution context for the pattern (FS-handle to the operation). + */ + void *ctx; + + /** + * Secondary execution context for the pattern (FS-handle to the operation). + */ + void *sctx; + + /** + * When did the operation start? + */ + struct GNUNET_TIME_Absolute start_time; + + /** + * With how much delay should this operation be started? + */ + struct GNUNET_TIME_Relative delay; + + /** + * Task to run the operation. + */ + GNUNET_SCHEDULER_TaskIdentifier task; + + /** + * Secondary task to run the operation. + */ + GNUNET_SCHEDULER_TaskIdentifier stask; + + /** + * X-value. + */ + unsigned long long x; + + /** + * Y-value. + */ + unsigned long long y; +}; + + +/** + * Return value from 'main'. + */ +static int global_ret; + +/** + * Configuration we use. + */ +static const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Handle to the statistics service. + */ +static struct GNUNET_STATISTICS_Handle *stats_handle; + +/** + * Peer's FS handle. + */ +static struct GNUNET_FS_Handle *fs_handle; + +/** + * Unique number for this peer in the testbed. + */ +static unsigned long long my_peerid; + +/** + * Desired anonymity level. + */ +static unsigned long long anonymity_level; + +/** + * Desired replication level. + */ +static unsigned long long replication_level; + +/** + * String describing which publishing operations this peer should + * perform. The format is "(SIZE,SEED,TIME)*", for example: + * "(1,5,0)(7,3,13)" means to publish a file with 1 byte and + * seed/keyword 5 immediately and another file with 7 bytes and + * seed/keyword 3 after 13 ms. + */ +static char *publish_pattern; + +/** + * Head of the DLL of publish patterns. + */ +static struct Pattern *publish_head; + +/** + * Tail of the DLL of publish patterns. + */ +static struct Pattern *publish_tail; + +/** + * String describing which download operations this peer should + * perform. The format is "(KEYWORD,SIZE,DELAY)*"; for example, + * "(1,7,3)(3,8,8)" means to download one file of 7 bytes under + * keyword "1" starting the search after 3 ms; and another one of 8 + * bytes under keyword '3' starting after 8 ms. The file size is + * used to determine which search result(s) should be used or ignored. + */ +static char *download_pattern; + +/** + * Head of the DLL of publish patterns. + */ +static struct Pattern *download_head; + +/** + * Tail of the DLL of publish patterns. + */ +static struct Pattern *download_tail; + + +/** + * Parse a pattern string and store the corresponding + * 'struct Pattern' in the given head/tail. + * + * @param head where to store the head + * @param tail where to store the tail + * @param pattern pattern to parse + * @return GNUNET_OK on success + */ +static int +parse_pattern (struct Pattern **head, + struct Pattern **tail, + const char *pattern) +{ + struct Pattern *p; + unsigned long long x; + unsigned long long y; + unsigned long long t; + + while (3 == sscanf (pattern, + "(%llu,%llu,%llu)", + &x, &y, &t)) + { + p = GNUNET_malloc (sizeof (struct Pattern)); + p->x = x; + p->y = y; + p->delay.rel_value = (uint64_t) t; + GNUNET_CONTAINER_DLL_insert (*head, *tail, p); + pattern = strstr (pattern, ")"); + GNUNET_assert (NULL != pattern); + pattern++; + } + return (0 == strlen (pattern)) ? GNUNET_OK : GNUNET_SYSERR; +} + + +/** + * Create a KSK URI from a number. + * + * @param kval the number + * @return corresponding KSK URI + */ +static struct GNUNET_FS_Uri * +make_keywords (uint64_t kval) +{ + char kw[128]; + + GNUNET_snprintf (kw, sizeof (kw), + "%llu", (unsigned long long) kval); + return GNUNET_FS_uri_ksk_create (kw, NULL); +} + + +/** + * Create a file of the given length with a deterministic amount + * of data to be published under keyword 'kval'. + * + * @param length number of bytes in the file + * @param kval keyword value and seed for the data of the file + * @param ctx context to pass to 'fi' + * @return file information handle for the file + */ +static struct GNUNET_FS_FileInformation * +make_file (uint64_t length, + uint64_t kval, + void *ctx) +{ + struct GNUNET_FS_FileInformation *fi; + struct GNUNET_FS_BlockOptions bo; + char *data; + struct GNUNET_FS_Uri *keywords; + unsigned long long i; + uint64_t xor; + + data = NULL; /* to make compilers happy */ + if ( (0 != length) && + (NULL == (data = GNUNET_malloc_large ((size_t) length))) ) + return NULL; + /* initialize data with 'unique' data only depending on 'kval' and 'size', + making sure that blocks do not repeat */ + for (i=0;i<length; i+=8) + { + xor = length ^ kval ^ (uint64_t) (i / 32 / 1024); + memcpy (&data[i], &xor, GNUNET_MIN (length - i, sizeof (uint64_t))); + } + bo.expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_DAYS); + bo.anonymity_level = (uint32_t) anonymity_level; + bo.content_priority = 128; + bo.replication_level = (uint32_t) replication_level; + keywords = make_keywords (kval); + fi = GNUNET_FS_file_information_create_from_data (fs_handle, + ctx, + length, + data, keywords, + NULL, GNUNET_NO, &bo); + GNUNET_FS_uri_destroy (keywords); + return fi; +} + + +/** + * Task run during shutdown. + * + * @param cls unused + * @param tc unused + */ +static void +shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Pattern *p; + + while (NULL != (p = publish_head)) + { + if (GNUNET_SCHEDULER_NO_TASK != p->task) + GNUNET_SCHEDULER_cancel (p->task); + if (NULL != p->ctx) + GNUNET_FS_publish_stop (p->ctx); + GNUNET_CONTAINER_DLL_remove (publish_head, publish_tail, p); + GNUNET_free (p); + } + while (NULL != (p = download_head)) + { + if (GNUNET_SCHEDULER_NO_TASK != p->task) + GNUNET_SCHEDULER_cancel (p->task); + if (GNUNET_SCHEDULER_NO_TASK != p->stask) + GNUNET_SCHEDULER_cancel (p->stask); + if (NULL != p->ctx) + GNUNET_FS_download_stop (p->ctx, GNUNET_YES); + if (NULL != p->sctx) + GNUNET_FS_search_stop (p->sctx); + GNUNET_CONTAINER_DLL_remove (download_head, download_tail, p); + GNUNET_free (p); + } + if (NULL != fs_handle) + { + GNUNET_FS_stop (fs_handle); + fs_handle = NULL; + } + if (NULL != stats_handle) + { + GNUNET_STATISTICS_destroy (stats_handle, GNUNET_YES); + stats_handle = NULL; + } +} + + +/** + * Task run when a publish operation should be stopped. + * + * @param cls the 'struct Pattern' of the publish operation to stop + * @param tc unused + */ +static void +publish_stop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Pattern *p = cls; + + p->task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_FS_publish_stop (p->ctx); +} + + +/** + * Task run when a download operation should be stopped. + * + * @param cls the 'struct Pattern' of the download operation to stop + * @param tc unused + */ +static void +download_stop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Pattern *p = cls; + + p->task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_FS_download_stop (p->ctx, GNUNET_YES); +} + + +/** + * Task run when a download operation should be stopped. + * + * @param cls the 'struct Pattern' of the download operation to stop + * @param tc unused + */ +static void +search_stop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Pattern *p = cls; + + p->stask = GNUNET_SCHEDULER_NO_TASK; + GNUNET_FS_search_stop (p->sctx); +} + + +/** + * Notification of FS to a client about the progress of an + * operation. Callbacks of this type will be used for uploads, + * downloads and searches. Some of the arguments depend a bit + * in their meaning on the context in which the callback is used. + * + * @param cls closure + * @param info details about the event, specifying the event type + * and various bits about the event + * @return client-context (for the next progress call + * for this operation; should be set to NULL for + * SUSPEND and STOPPED events). The value returned + * will be passed to future callbacks in the respective + * field in the GNUNET_FS_ProgressInfo struct. + */ +static void * +progress_cb (void *cls, + const struct GNUNET_FS_ProgressInfo *info) +{ + struct Pattern *p; + const struct GNUNET_FS_Uri *uri; + + switch (info->status) + { + case GNUNET_FS_STATUS_PUBLISH_START: + case GNUNET_FS_STATUS_PUBLISH_PROGRESS: + p = info->value.publish.cctx; + return p; + case GNUNET_FS_STATUS_PUBLISH_ERROR: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Publishing failed\n"); + GNUNET_STATISTICS_update (stats_handle, + "# failed publish operations", 1, GNUNET_NO); + p = info->value.publish.cctx; + p->task = GNUNET_SCHEDULER_add_now (&publish_stop_task, p); + return p; + case GNUNET_FS_STATUS_PUBLISH_COMPLETED: + p = info->value.publish.cctx; + GNUNET_STATISTICS_update (stats_handle, + "# publishing time (ms)", + (long long) GNUNET_TIME_absolute_get_duration (p->start_time).rel_value, + GNUNET_NO); + p->task = GNUNET_SCHEDULER_add_now (&publish_stop_task, p); + return p; + case GNUNET_FS_STATUS_PUBLISH_STOPPED: + p = info->value.publish.cctx; + p->ctx = NULL; + GNUNET_CONTAINER_DLL_remove (publish_head, publish_tail, p); + GNUNET_free (p); + return NULL; + case GNUNET_FS_STATUS_DOWNLOAD_START: + case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: + case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: + case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: + p = info->value.download.cctx; + return p; + case GNUNET_FS_STATUS_DOWNLOAD_ERROR: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Download failed\n"); + GNUNET_STATISTICS_update (stats_handle, + "# failed downloads", 1, GNUNET_NO); + p = info->value.download.cctx; + p->task = GNUNET_SCHEDULER_add_now (&download_stop_task, p); + return p; + case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: + p = info->value.download.cctx; + GNUNET_STATISTICS_update (stats_handle, + "# download time (ms)", + (long long) GNUNET_TIME_absolute_get_duration (p->start_time).rel_value, + GNUNET_NO); p->task = GNUNET_SCHEDULER_add_now (&download_stop_task, p); + return p; + case GNUNET_FS_STATUS_DOWNLOAD_STOPPED: + p = info->value.download.cctx; + p->ctx = NULL; + if (NULL == p->sctx) + { + GNUNET_CONTAINER_DLL_remove (download_head, download_tail, p); + GNUNET_free (p); + } + return NULL; + case GNUNET_FS_STATUS_SEARCH_START: + case GNUNET_FS_STATUS_SEARCH_RESULT_NAMESPACE: + p = info->value.search.cctx; + return p; + case GNUNET_FS_STATUS_SEARCH_RESULT: + p = info->value.search.cctx; + uri = info->value.search.specifics.result.uri; + if (GNUNET_YES != GNUNET_FS_uri_test_chk (uri)) + return NULL; /* not what we want */ + if (p->y != GNUNET_FS_uri_chk_get_file_size (uri)) + return NULL; /* not what we want */ + GNUNET_STATISTICS_update (stats_handle, + "# search time (ms)", + (long long) GNUNET_TIME_absolute_get_duration (p->start_time).rel_value, + GNUNET_NO); + p->start_time = GNUNET_TIME_absolute_get (); + p->ctx = GNUNET_FS_download_start (fs_handle, uri, + NULL, NULL, NULL, + 0, GNUNET_FS_uri_chk_get_file_size (uri), + anonymity_level, + GNUNET_FS_DOWNLOAD_NO_TEMPORARIES, + p, + NULL); + p->stask = GNUNET_SCHEDULER_add_now (&search_stop_task, p); + return NULL; + case GNUNET_FS_STATUS_SEARCH_UPDATE: + case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED: + return NULL; /* don't care */ + case GNUNET_FS_STATUS_SEARCH_ERROR: + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Search failed\n"); + GNUNET_STATISTICS_update (stats_handle, + "# failed searches", 1, GNUNET_NO); + p = info->value.search.cctx; + p->stask = GNUNET_SCHEDULER_add_now (&search_stop_task, p); + return p; + case GNUNET_FS_STATUS_SEARCH_STOPPED: + p = info->value.search.cctx; + p->sctx = NULL; + if (NULL == p->ctx) + { + GNUNET_CONTAINER_DLL_remove (download_head, download_tail, p); + GNUNET_free (p); + } + return NULL; + default: + /* unexpected event during profiling */ + GNUNET_break (0); + return NULL; + } +} + + +/** + * Start publish operation. + * + * @param cls the 'struct Pattern' specifying the operation to perform + * @param tc scheduler context + */ +static void +start_publish (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Pattern *p = cls; + struct GNUNET_FS_FileInformation *fi; + + p->task = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + fi = make_file (p->x, p->y, p); + p->start_time = GNUNET_TIME_absolute_get (); + p->ctx = GNUNET_FS_publish_start (fs_handle, + fi, + NULL, NULL, NULL, + GNUNET_FS_PUBLISH_OPTION_NONE); +} + + +/** + * Start download operation. + * + * @param cls the 'struct Pattern' specifying the operation to perform + * @param tc scheduler context + */ +static void +start_download (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Pattern *p = cls; + struct GNUNET_FS_Uri *keywords; + + p->task = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + keywords = make_keywords (p->x); + p->start_time = GNUNET_TIME_absolute_get (); + p->sctx = GNUNET_FS_search_start (fs_handle, keywords, + anonymity_level, + GNUNET_FS_SEARCH_OPTION_NONE, + p); +} + + +/** + * @brief Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg_ configuration + */ +static void +run (void *cls, char *const *args GNUNET_UNUSED, + const char *cfgfile GNUNET_UNUSED, + const struct GNUNET_CONFIGURATION_Handle *cfg_) +{ + char myoptname[128]; + struct Pattern *p; + + cfg = cfg_; + /* Scheduled the task to clean up when shutdown is called */ + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, + NULL); + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (cfg, + "TESTBED", "PEERID", + &my_peerid)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "TESTBED", "PEERID"); + global_ret = GNUNET_SYSERR; + GNUNET_SCHEDULER_shutdown (); + return; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (cfg, + "FSPROFILER", "ANONYMITY_LEVEL", + &anonymity_level)) + anonymity_level = 1; + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (cfg, + "FSPROFILER", "REPLICATION_LEVEL", + &replication_level)) + replication_level = 1; + GNUNET_snprintf (myoptname, sizeof (myoptname), + "DOWNLOAD-PATTERN-%u", my_peerid); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "FSPROFILER", myoptname, + &download_pattern)) + download_pattern = GNUNET_strdup (""); + GNUNET_snprintf (myoptname, sizeof (myoptname), + "PUBLISH-PATTERN-%u", my_peerid); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "FSPROFILER", myoptname, + &publish_pattern)) + publish_pattern = GNUNET_strdup (""); + if ( (GNUNET_OK != + parse_pattern (&download_head, + &download_tail, + download_pattern)) || + (GNUNET_OK != + parse_pattern (&publish_head, + &publish_tail, + publish_pattern)) ) + { + GNUNET_SCHEDULER_shutdown (); + return; + } + + stats_handle = GNUNET_STATISTICS_create ("fsprofiler", cfg); + fs_handle = + GNUNET_FS_start (cfg, + "fsprofiler", + &progress_cb, NULL, + GNUNET_FS_FLAGS_NONE, + GNUNET_FS_OPTIONS_DOWNLOAD_PARALLELISM, 1, + GNUNET_FS_OPTIONS_REQUEST_PARALLELISM, 1, + GNUNET_FS_OPTIONS_END); + if (NULL == fs_handle) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not acquire FS handle. Exiting.\n"); + global_ret = GNUNET_SYSERR; + GNUNET_SCHEDULER_shutdown (); + return; + } + for (p = publish_head; NULL != p; p = p->next) + p->task = GNUNET_SCHEDULER_add_delayed (p->delay, + &start_publish, p); + for (p = download_head; NULL != p; p = p->next) + p->task = GNUNET_SCHEDULER_add_delayed (p->delay, + &start_download, p); +} + + +/** + * Program that performs various "random" FS activities. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + return (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-fsprofiler", + gettext_noop + ("Daemon to use file-sharing to measure its performance."), + options, &run, NULL)) ? global_ret : 1; +} + +/* end of gnunet-daemon-fsprofiler.c */ diff --git a/src/fs/gnunet-directory.c b/src/fs/gnunet-directory.c index c722f57..2f25e28 100644 --- a/src/fs/gnunet-directory.c +++ b/src/fs/gnunet-directory.c @@ -173,11 +173,17 @@ main (int argc, char *const *argv) static struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-directory [OPTIONS] FILENAME", - gettext_noop - ("Display contents of a GNUnet directory"), - options, &run, NULL)) ? ret : 1; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-directory [OPTIONS] FILENAME", + gettext_noop + ("Display contents of a GNUnet directory"), + options, &run, NULL)) ? ret : 1; + GNUNET_free ((void*) argv); + return ret; } /* end of gnunet-directory.c */ diff --git a/src/fs/gnunet-download.c b/src/fs/gnunet-download.c index 5a66aea..04edc66 100644 --- a/src/fs/gnunet-download.c +++ b/src/fs/gnunet-download.c @@ -52,6 +52,7 @@ static char *filename; static int local_only; + static void cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -63,18 +64,53 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_FS_DownloadContext *d; - - if (dc != NULL) + if (NULL != dc) { - d = dc; + GNUNET_FS_download_stop (dc, delete_incomplete); dc = NULL; - GNUNET_FS_download_stop (d, delete_incomplete); } } /** + * Display progress bar (if tty). + * + * @param x current position in the download + * @param n total size of the download + * @param w desired number of steps in the progress bar + */ +static void +display_bar (unsigned long long x, + unsigned long long n, + unsigned int w) +{ + char buf[w + 20]; + unsigned int p; + unsigned int endeq; + float ratio_complete; + +#if !WINDOWS + if (0 == isatty (1)) + return; +#else + if (FILE_TYPE_CHAR != GetFileType (GetStdHandle (STD_OUTPUT_HANDLE))) + return; +#endif + ratio_complete = x/(float)n; + endeq = ratio_complete * w; + GNUNET_snprintf (buf, sizeof (buf), + "%3d%% [", (int)(ratio_complete*100) ); + for (p=0; p<endeq; p++) + strcat (buf, "="); + for (p=endeq; p<w; p++) + strcat (buf, " "); + strcat (buf, "]\r"); + printf ("%s", buf); + fflush(stdout); +} + + +/** * Called by FS client to give information about the progress of an * operation. * @@ -91,7 +127,7 @@ static void * progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) { char *s; - char *s2; + const char *s2; char *t; switch (info->status) @@ -104,13 +140,15 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: if (verbose) { - s = GNUNET_STRINGS_relative_time_to_string (info->value.download.eta); + s = GNUNET_strdup (GNUNET_STRINGS_relative_time_to_string (info->value.download.eta, + GNUNET_YES)); if (info->value.download.specifics.progress.block_download_duration.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value) - s2 = GNUNET_strdup (_("<unknown time>")); + s2 = _("<unknown time>"); else s2 = GNUNET_STRINGS_relative_time_to_string ( - info->value.download.specifics.progress.block_download_duration); + info->value.download.specifics.progress.block_download_duration, + GNUNET_YES); t = GNUNET_STRINGS_byte_size_fancy (info->value.download.completed * 1000LL / (info->value.download. @@ -121,11 +159,23 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) (unsigned long long) info->value.download.completed, (unsigned long long) info->value.download.size, s, t, s2); GNUNET_free (s); - GNUNET_free (s2); GNUNET_free (t); } + else + { + display_bar (info->value.download.completed, + info->value.download.size, + 60); + } break; case GNUNET_FS_STATUS_DOWNLOAD_ERROR: +#if !WINDOWS + if (0 != isatty (1)) + fprintf (stdout, "\n"); +#else + if (FILE_TYPE_CHAR == GetFileType (GetStdHandle (STD_OUTPUT_HANDLE))) + fprintf (stdout, "\n"); +#endif FPRINTF (stderr, _("Error downloading: %s.\n"), info->value.download.specifics.error.message); GNUNET_SCHEDULER_shutdown (); @@ -134,6 +184,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) s = GNUNET_STRINGS_byte_size_fancy (info->value.download.completed * 1000 / (info->value.download. duration.rel_value + 1)); +#if !WINDOWS + if (0 != isatty (1)) + fprintf (stdout, "\n"); +#else + if (FILE_TYPE_CHAR == GetFileType (GetStdHandle (STD_OUTPUT_HANDLE))) + fprintf (stdout, "\n"); +#endif FPRINTF (stdout, _("Downloading `%s' done (%s/s).\n"), info->value.download.filename, s); GNUNET_free (s); @@ -272,11 +329,17 @@ main (int argc, char *const *argv) 0, &GNUNET_GETOPT_increment_value, &verbose}, GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-download [OPTIONS] URI", - gettext_noop - ("Download files from GNUnet using a GNUnet CHK or LOC URI (gnunet://fs/chk/...)"), - options, &run, NULL)) ? ret : 1; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-download [OPTIONS] URI", + gettext_noop + ("Download files from GNUnet using a GNUnet CHK or LOC URI (gnunet://fs/chk/...)"), + options, &run, NULL)) ? ret : 1; + GNUNET_free ((void*) argv); + return ret; } /* end of gnunet-download.c */ diff --git a/src/fs/gnunet-fs-profiler.c b/src/fs/gnunet-fs-profiler.c new file mode 100644 index 0000000..7a0b7e8 --- /dev/null +++ b/src/fs/gnunet-fs-profiler.c @@ -0,0 +1,203 @@ +/* + 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/gnunet-fs-profiler.c + * @brief tool to benchmark/profile file-sharing + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testbed_service.h" + +/** + * Final status code. + */ +static int ret; + +/** + * Data file with the hosts for the testbed. + */ +static char *host_filename; + +/** + * Number of peers to run in the experiment. + */ +static unsigned int num_peers; + +/** + * After how long do we abort the test? + */ +static struct GNUNET_TIME_Relative timeout; + +/** + * Handle to the task run during termination. + */ +static GNUNET_SCHEDULER_TaskIdentifier terminate_taskid; + + +/** + * Function called after we've collected the statistics. + * + * @param cls NULL + * @param op the operation that has been finished + * @param emsg error message in case the operation has failed; will be NULL if + * operation has executed successfully. + */ +static void +shutdown_task (void *cls, + struct GNUNET_TESTBED_Operation *op, + const char *emsg) +{ + if (NULL != emsg) + fprintf (stderr, + "Error collecting statistics: %s\n", + emsg); + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Callback function to process statistic values from all peers. + * Prints them out. + * + * @param cls closure + * @param peer the peer the statistic belong to + * @param subsystem name of subsystem that created the statistic + * @param name the name of the datum + * @param value the current value + * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not + * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration + */ +static int +process_stats (void *cls, + const struct GNUNET_TESTBED_Peer *peer, + const char *subsystem, + const char *name, + uint64_t value, + int is_persistent) +{ + fprintf (stdout, + "%p-%s: %s = %llu\n", + peer, + subsystem, + name, + (unsigned long long) value); + return GNUNET_OK; +} + + +/** + * Task run on timeout to terminate. Triggers printing out + * all statistics. + * + * @param cls NULL + * @param tc unused + */ +static void +terminate_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + terminate_taskid = GNUNET_SCHEDULER_NO_TASK; + GNUNET_TESTBED_get_statistics (0, NULL, + &process_stats, + &shutdown_task, + NULL); +} + + +/** + * Signature of a main function for a testcase. + * + * @param cls closure + * @param num_peers number of peers in 'peers' + * @param peers handle to peers run in the testbed + */ +static void +test_master (void *cls, unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers) +{ + // const struct GNUNET_CONFIGURATION_Handle *cfg = cls; + // FIXME: enable clients to signal 'completion' before timeout; + // in that case, run the 'terminate_task' "immediately" + + if (0 != timeout.rel_value) + terminate_taskid = GNUNET_SCHEDULER_add_delayed (timeout, + &terminate_task, NULL); + else + terminate_taskid = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &terminate_task, + NULL); +} + + +/** + * Main function that will be run by the scheduler. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + GNUNET_TESTBED_run (host_filename, + cfg, + num_peers, + 0, NULL, NULL, + &test_master, (void *) cfg); +} + + +/** + * Program to run a file-sharing testbed. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'n', "num-peers", "COUNT", + gettext_noop ("run the experiment with COUNT peers"), + 1, &GNUNET_GETOPT_set_uint, &num_peers}, + {'H', "hosts", "HOSTFILE", + gettext_noop ("specifies name of a file with the HOSTS the testbed should use"), + 1, &GNUNET_GETOPT_set_string, &host_filename}, + {'t', "timeout", "DELAY", + gettext_noop ("automatically terminate experiment after DELAY"), + 1, &GNUNET_GETOPT_set_relative_time, &timeout}, + GNUNET_GETOPT_OPTION_END + }; + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-fs-profiler", + gettext_noop ("run a testbed to measure file-sharing performance"), options, &run, + NULL)) ? ret : 1; + GNUNET_free ((void*) argv); + return ret; +} + +/* end of gnunet-fs-profiler.c */ diff --git a/src/fs/gnunet-fs.c b/src/fs/gnunet-fs.c index 0b28923..1d79137 100644 --- a/src/fs/gnunet-fs.c +++ b/src/fs/gnunet-fs.c @@ -55,7 +55,7 @@ static int verbose; * @return GNUNET_OK to continue iteration */ static int -print_indexed (void *cls, const char *filename, const GNUNET_HashCode * file_id) +print_indexed (void *cls, const char *filename, const struct GNUNET_HashCode * file_id) { if (NULL == filename) { @@ -119,10 +119,15 @@ main (int argc, char *const *argv) GNUNET_GETOPT_OPTION_VERBOSE (&verbose), GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-fs [OPTIONS]", - gettext_noop ("Special file-sharing operations"), - options, &run, NULL)) ? ret : 1; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-fs [OPTIONS]", + gettext_noop ("Special file-sharing operations"), + options, &run, NULL)) ? ret : 1; + GNUNET_free ((void*) argv); + return ret; } /* end of gnunet-fs.c */ diff --git a/src/fs/gnunet-helper-fs-publish.c b/src/fs/gnunet-helper-fs-publish.c index 86b0249..7ea9499 100644 --- a/src/fs/gnunet-helper-fs-publish.c +++ b/src/fs/gnunet-helper-fs-publish.c @@ -364,8 +364,7 @@ extract_files (struct ScanTreeNode *item) /* this is the expensive operation, *afterwards* we'll check for aborts */ meta = GNUNET_CONTAINER_meta_data_create (); - if (NULL != plugins) - EXTRACTOR_extract (plugins, item->filename, NULL, 0, &add_to_md, meta); + EXTRACTOR_extract (plugins, item->filename, NULL, 0, &add_to_md, meta); slen = strlen (item->filename) + 1; size = GNUNET_CONTAINER_meta_data_get_serialized_size (meta); if (-1 == size) @@ -378,6 +377,11 @@ extract_files (struct ScanTreeNode *item) return GNUNET_SYSERR; return GNUNET_OK; } + else if (size > (UINT16_MAX - sizeof (struct GNUNET_MessageHeader) - slen)) + { + /* We can't transfer more than 64k bytes in one message. */ + size = UINT16_MAX - sizeof (struct GNUNET_MessageHeader) - slen; + } { char buf[size + slen]; char *dst = &buf[slen]; @@ -402,6 +406,31 @@ extract_files (struct ScanTreeNode *item) } +#ifndef WINDOWS +/** + * Install a signal handler to ignore SIGPIPE. + */ +static void +ignore_sigpipe () +{ + struct sigaction oldsig; + struct sigaction sig; + + memset (&sig, 0, sizeof (struct sigaction)); + sig.sa_handler = SIG_IGN; + sigemptyset (&sig.sa_mask); +#ifdef SA_INTERRUPT + sig.sa_flags = SA_INTERRUPT; /* SunOS */ +#else + sig.sa_flags = SA_RESTART; +#endif + if (0 != sigaction (SIGPIPE, &sig, &oldsig)) + fprintf (stderr, + "Failed to install SIGPIPE handler: %s\n", strerror (errno)); +} +#endif + + /** * Main function of the helper process to extract meta data. * @@ -413,7 +442,7 @@ extract_files (struct ScanTreeNode *item) * @return 0 on success */ int main(int argc, - char **argv) + char *const *argv) { const char *filename_expanded; const char *ex; @@ -424,6 +453,11 @@ int main(int argc, * binary mode. */ _setmode (1, _O_BINARY); + /* Get utf-8-encoded arguments */ + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 5; +#else + ignore_sigpipe (); #endif /* parse command line */ @@ -432,6 +466,9 @@ int main(int argc, FPRINTF (stderr, "%s", "gnunet-helper-fs-publish needs exactly one or two arguments\n"); +#if WINDOWS + GNUNET_free ((void*) argv); +#endif return 1; } filename_expanded = argv[1]; @@ -450,13 +487,23 @@ int main(int argc, &root)) { (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR, NULL, 0); + EXTRACTOR_plugin_remove_all (plugins); +#if WINDOWS + GNUNET_free ((void*) argv); +#endif return 2; } /* signal that we're done counting files, so that a percentage of progress can now be calculated */ if (GNUNET_OK != write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_COUNTING_DONE, NULL, 0)) + { + EXTRACTOR_plugin_remove_all (plugins); +#if WINDOWS + GNUNET_free ((void*) argv); +#endif return 3; + } if (NULL != root) { if (GNUNET_OK != @@ -464,15 +511,20 @@ int main(int argc, { (void) write_message (GNUNET_MESSAGE_TYPE_FS_PUBLISH_HELPER_ERROR, NULL, 0); free_tree (root); + EXTRACTOR_plugin_remove_all (plugins); +#if WINDOWS + GNUNET_free ((void*) argv); +#endif 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) - EXTRACTOR_plugin_remove_all (plugins); - + EXTRACTOR_plugin_remove_all (plugins); +#if WINDOWS + GNUNET_free ((void*) argv); +#endif return 0; } diff --git a/src/fs/gnunet-pseudonym.c b/src/fs/gnunet-pseudonym.c index 38826d1..a692917 100644 --- a/src/fs/gnunet-pseudonym.c +++ b/src/fs/gnunet-pseudonym.c @@ -95,7 +95,7 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) static void -ns_printer (void *cls, const char *name, const GNUNET_HashCode * id) +ns_printer (void *cls, const char *name, const struct GNUNET_HashCode * id) { struct GNUNET_CRYPTO_HashAsciiEncoded enc; @@ -105,7 +105,7 @@ ns_printer (void *cls, const char *name, const GNUNET_HashCode * id) static int -pseudo_printer (void *cls, const GNUNET_HashCode * pseudonym, +pseudo_printer (void *cls, const struct GNUNET_HashCode * pseudonym, const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { @@ -136,7 +136,7 @@ pseudo_printer (void *cls, const GNUNET_HashCode * pseudonym, static void post_advertising (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) { - GNUNET_HashCode nsid; + struct GNUNET_HashCode nsid; char *set; int delta; @@ -313,10 +313,16 @@ main (int argc, char *const *argv) }; bo.expiration_time = GNUNET_FS_year_to_time (GNUNET_FS_get_current_year () + 2); - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-pseudonym [OPTIONS]", - gettext_noop ("Manage GNUnet pseudonyms."), - options, &run, NULL)) ? ret : 1; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-pseudonym [OPTIONS]", + gettext_noop ("Manage GNUnet pseudonyms."), + options, &run, NULL)) ? ret : 1; + GNUNET_free ((void*) argv); + return ret; } /* end of gnunet-pseudonym.c */ diff --git a/src/fs/gnunet-publish.c b/src/fs/gnunet-publish.c index a1b26db..08b34c6 100644 --- a/src/fs/gnunet-publish.c +++ b/src/fs/gnunet-publish.c @@ -28,7 +28,7 @@ #include "platform.h" #include "gnunet_fs_service.h" -static int ret; +static int ret = 1; static int verbose; @@ -105,8 +105,11 @@ static void stop_scanner_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { kill_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_FS_directory_scan_abort (ds); - ds = NULL; + if (NULL != ds) + { + GNUNET_FS_directory_scan_abort (ds); + ds = NULL; + } if (namespace != NULL) { GNUNET_FS_namespace_delete (namespace, GNUNET_NO); @@ -134,7 +137,8 @@ stop_scanner_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void * progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) { - char *s; + const char *s; + char *suri; switch (info->status) { @@ -143,12 +147,12 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) case GNUNET_FS_STATUS_PUBLISH_PROGRESS: if (verbose) { - s = GNUNET_STRINGS_relative_time_to_string (info->value.publish.eta); + s = GNUNET_STRINGS_relative_time_to_string (info->value.publish.eta, + GNUNET_YES); FPRINTF (stdout, _("Publishing `%s' at %llu/%llu (%s remaining)\n"), info->value.publish.filename, (unsigned long long) info->value.publish.completed, (unsigned long long) info->value.publish.size, s); - GNUNET_free (s); } break; case GNUNET_FS_STATUS_PUBLISH_ERROR: @@ -164,10 +168,10 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) case GNUNET_FS_STATUS_PUBLISH_COMPLETED: FPRINTF (stdout, _("Publishing `%s' done.\n"), info->value.publish.filename); - s = GNUNET_FS_uri_to_string (info->value.publish.specifics. + suri = GNUNET_FS_uri_to_string (info->value.publish.specifics. completed.chk_uri); - FPRINTF (stdout, _("URI is `%s'.\n"), s); - GNUNET_free (s); + FPRINTF (stdout, _("URI is `%s'.\n"), suri); + GNUNET_free (suri); if (info->value.publish.pctx == NULL) { if (kill_task != GNUNET_SCHEDULER_NO_TASK) @@ -177,6 +181,7 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) } kill_task = GNUNET_SCHEDULER_add_now (&do_stop_task, NULL); } + ret = 0; break; case GNUNET_FS_STATUS_PUBLISH_STOPPED: GNUNET_break (NULL == pc); @@ -268,6 +273,12 @@ publish_inspector (void *cls, struct GNUNET_FS_FileInformation *fi, if (cls == fi) return GNUNET_OK; + if ( (disable_extractor) && + (NULL != *uri) ) + { + GNUNET_FS_uri_destroy (*uri); + *uri = NULL; + } if (NULL != topKeywords) { if (*uri != NULL) @@ -291,12 +302,6 @@ 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, @@ -355,7 +360,7 @@ uri_ksk_continuation (void *cls, const struct GNUNET_FS_Uri *ksk_uri, ns = GNUNET_FS_namespace_create (ctx, pseudonym); if (ns == NULL) { - FPRINTF (stderr, _("Failed to create namespace `%s'\n"), pseudonym); + FPRINTF (stderr, _("Failed to create namespace `%s' (illegal filename?)\n"), pseudonym); ret = 1; } else @@ -609,7 +614,7 @@ run (void *cls, char *const *args, const char *cfgfile, namespace = GNUNET_FS_namespace_create (ctx, pseudonym); if (NULL == namespace) { - FPRINTF (stderr, _("Could not create namespace `%s'\n"), pseudonym); + FPRINTF (stderr, _("Failed to create namespace `%s' (illegal filename?)\n"), pseudonym); GNUNET_FS_stop (ctx); ret = 1; return; @@ -732,15 +737,18 @@ main (int argc, char *const *argv) 0, &GNUNET_GETOPT_set_one, &verbose}, GNUNET_GETOPT_OPTION_END }; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "GNUnet publish starts\n"); bo.expiration_time = GNUNET_FS_year_to_time (GNUNET_FS_get_current_year () + 2); - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-publish [OPTIONS] FILENAME", - gettext_noop - ("Publish a file or directory on GNUnet"), - options, &run, NULL)) ? ret : 1; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-publish [OPTIONS] FILENAME", + gettext_noop + ("Publish a file or directory on GNUnet"), + options, &run, NULL)) ? ret : 1; + GNUNET_free ((void*) argv); + return ret; } /* end of gnunet-publish.c */ diff --git a/src/fs/gnunet-search.c b/src/fs/gnunet-search.c index 60620a4..e90b761 100644 --- a/src/fs/gnunet-search.c +++ b/src/fs/gnunet-search.c @@ -42,11 +42,14 @@ static struct GNUNET_FS_DirectoryBuilder *db; static unsigned int anonymity = 1; -static unsigned long long timeout; +/** + * Timeout for the search, 0 means to wait for CTRL-C. + */ +static struct GNUNET_TIME_Relative timeout; static unsigned int results_limit; -static unsigned int results = 0; +static unsigned int results; static int verbose; @@ -220,7 +223,6 @@ run (void *cls, char *const *args, const char *cfgfile, struct GNUNET_FS_Uri *uri; unsigned int argc; enum GNUNET_FS_SearchOptions options; - struct GNUNET_TIME_Relative delay; argc = 0; while (NULL != args[argc]) @@ -257,16 +259,11 @@ run (void *cls, char *const *args, const char *cfgfile, ret = 1; return; } - if (timeout != 0) - { - delay.rel_value = timeout; - GNUNET_SCHEDULER_add_delayed (delay, &shutdown_task, NULL); - } + if (0 != timeout.rel_value) + GNUNET_SCHEDULER_add_delayed (timeout, &shutdown_task, NULL); else - { GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); - } } @@ -290,9 +287,9 @@ main (int argc, char *const *argv) {'o', "output", "PREFIX", gettext_noop ("write search results to file starting with PREFIX"), 1, &GNUNET_GETOPT_set_string, &output_filename}, - {'t', "timeout", "VALUE", - gettext_noop ("automatically terminate search after VALUE ms"), - 1, &GNUNET_GETOPT_set_ulong, &timeout}, + {'t', "timeout", "DELAY", + gettext_noop ("automatically terminate search after DELAY"), + 1, &GNUNET_GETOPT_set_relative_time, &timeout}, {'V', "verbose", NULL, gettext_noop ("be verbose (print progress information)"), 0, &GNUNET_GETOPT_set_one, &verbose}, @@ -302,11 +299,17 @@ main (int argc, char *const *argv) 1, &GNUNET_GETOPT_set_uint, &results_limit}, GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-search [OPTIONS] KEYWORD", - gettext_noop - ("Search GNUnet for files that were published on GNUnet"), - options, &run, NULL)) ? ret : 1; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-search [OPTIONS] KEYWORD", + gettext_noop + ("Search GNUnet for files that were published on GNUnet"), + options, &run, NULL)) ? ret : 1; + GNUNET_free ((void*) argv); + return ret; } /* end of gnunet-search.c */ diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index 06ac91c..0f4d513 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c @@ -22,9 +22,6 @@ * @file fs/gnunet-service-fs.c * @brief gnunet anonymity protocol implementation * @author Christian Grothoff - * - * To use: - * - consider re-issue GSF_dht_lookup_ after non-DHT reply received */ #include "platform.h" #include <float.h> @@ -46,6 +43,7 @@ #include "gnunet-service-fs_pr.h" #include "gnunet-service-fs_push.h" #include "gnunet-service-fs_put.h" +#include "gnunet-service-fs_stream.h" #include "fs.h" /** @@ -63,6 +61,11 @@ */ #define COVER_AGE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) +/** + * Collect an instane number of statistics? May cause excessive IPC. + */ +#define INSANE_STATISTICS GNUNET_NO + /* ****************************** globals ****************************** */ @@ -110,6 +113,11 @@ struct GNUNET_TIME_Relative GSF_avg_latency = { 500 }; double GSF_current_priorities; /** + * Size of the datastore queue we assume for common requests. + */ +unsigned int GSF_datastore_queue_size; + +/** * How many query messages have we received 'recently' that * have not yet been claimed as cover traffic? */ @@ -296,9 +304,11 @@ consider_request_for_forwarding (void *cls, if (GNUNET_YES != GSF_pending_request_test_target_ (pr, peer)) { +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# Loopback routes suppressed"), 1, GNUNET_NO); +#endif return; } GSF_plan_add_ (cp, pr); @@ -384,7 +394,30 @@ start_p2p_processing (void *cls, struct GSF_PendingRequest *pr, GSF_pending_request_cancel_ (pr, GNUNET_YES); return; } - GSF_dht_lookup_ (pr); + if (0 == prd->anonymity_level) + { + switch (prd->type) + { + case GNUNET_BLOCK_TYPE_FS_DBLOCK: + case GNUNET_BLOCK_TYPE_FS_IBLOCK: + /* the above block types MAY be available via 'stream' */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Considering stream-based download for block\n"); + GSF_stream_lookup_ (pr); + break; + case GNUNET_BLOCK_TYPE_FS_KBLOCK: + case GNUNET_BLOCK_TYPE_FS_SBLOCK: + case GNUNET_BLOCK_TYPE_FS_NBLOCK: + /* the above block types are in the DHT */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Considering DHT-based search for block\n"); + GSF_dht_lookup_ (pr); + break; + default: + GNUNET_break (0); + break; + } + } consider_forwarding (NULL, pr, result); } @@ -432,6 +465,7 @@ handle_start_search (void *cls, struct GNUNET_SERVER_Client *client, static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + GSF_stream_stop (); if (NULL != GSF_core) { GNUNET_CORE_disconnect (GSF_core); @@ -476,7 +510,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @return GNUNET_YES to continue to iterate */ static int -consider_peer_for_forwarding (void *cls, const GNUNET_HashCode * key, +consider_peer_for_forwarding (void *cls, const struct GNUNET_HashCode * key, struct GSF_PendingRequest *pr) { struct GSF_ConnectedPeer *cp = cls; @@ -548,6 +582,9 @@ static int main_init (struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c) { + static const struct GNUNET_CORE_MessageHandler no_p2p_handlers[] = { + {NULL, 0, 0} + }; static const struct GNUNET_CORE_MessageHandler p2p_handlers[] = { {&handle_p2p_get, GNUNET_MESSAGE_TYPE_FS_GET, 0}, @@ -570,11 +607,21 @@ main_init (struct GNUNET_SERVER_Handle *server, 0}, {NULL, NULL, 0, 0} }; - + int anon_p2p_off; + + /* this option is really only for testcases that need to disable + _anonymous_ file-sharing for some reason */ + anon_p2p_off = (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (GSF_cfg, + "fs", + "DISABLE_ANON_TRANSFER")); GSF_core = - GNUNET_CORE_connect (GSF_cfg, 1, NULL, &peer_init_handler, + GNUNET_CORE_connect (GSF_cfg, NULL, &peer_init_handler, &peer_connect_handler, &GSF_peer_disconnect_handler_, - NULL, GNUNET_NO, NULL, GNUNET_NO, p2p_handlers); + NULL, GNUNET_NO, NULL, GNUNET_NO, + (GNUNET_YES == anon_p2p_off) + ? no_p2p_handlers + : p2p_handlers); if (NULL == GSF_core) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -588,6 +635,7 @@ main_init (struct GNUNET_SERVER_Handle *server, GNUNET_SCHEDULER_add_delayed (COVER_AGE_FREQUENCY, &age_cover_counters, NULL); datastore_get_load = GNUNET_LOAD_value_init (DATASTORE_LOAD_AUTODECLINE); + GSF_stream_start (); GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); return GNUNET_OK; @@ -605,7 +653,18 @@ static void run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *cfg) { + unsigned long long dqs; + GSF_cfg = cfg; + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_size (GSF_cfg, "fs", "DATASTORE_QUEUE_SIZE", + &dqs)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_INFO, + "fs", "DATASTORE_QUEUE_SIZE"); + dqs = 1024; + } + GSF_datastore_queue_size = (unsigned int) dqs; GSF_enable_randomized_delays = GNUNET_CONFIGURATION_get_value_yesno (cfg, "fs", "DELAY"); GSF_dsh = GNUNET_DATASTORE_connect (cfg); diff --git a/src/fs/gnunet-service-fs.h b/src/fs/gnunet-service-fs.h index 0c796bf..3213712 100644 --- a/src/fs/gnunet-service-fs.h +++ b/src/fs/gnunet-service-fs.h @@ -119,7 +119,7 @@ struct GetMessage /** * Which of the optional hash codes are present at the end of the * message? See GET_MESSAGE_BIT_xx constants. For each bit that is - * set, an additional GNUNET_HashCode with the respective content + * set, an additional struct GNUNET_HashCode with the respective content * (in order of the bits) will be appended to the end of the GET * message. */ @@ -129,7 +129,7 @@ struct GetMessage * Hashcodes of the file(s) we're looking for. * Details depend on the query type. */ - GNUNET_HashCode query; + struct 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 @@ -183,10 +183,9 @@ struct GSF_LocalClient; struct GSF_RequestPlan; /** - * DLL of request plans a particular pending request is - * involved with. + * Bijection between request plans and pending requests. */ -struct GSF_RequestPlanReference; +struct GSF_PendingRequestPlanBijection; /** * Our connection to the datastore. @@ -259,6 +258,12 @@ extern struct GNUNET_BLOCK_Context *GSF_block_ctx; extern int GSF_enable_randomized_delays; /** + * Size of the datastore queue we assume for common requests. + */ +extern unsigned int GSF_datastore_queue_size; + + +/** * Test if the DATABASE (GET) load on this peer is too high * to even consider processing the query at * all. diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c index e84993b..e389a24 100644 --- a/src/fs/gnunet-service-fs_cp.c +++ b/src/fs/gnunet-service-fs_cp.c @@ -41,15 +41,20 @@ #define RUNAVG_DELAY_N 16 /** - * How often do we flush trust values to disk? + * How often do we flush respect values to disk? */ -#define TRUST_FLUSH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) +#define RESPECT_FLUSH_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) /** * After how long do we discard a reply? */ #define REPLY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) +/** + * Collect an instane number of statistics? May cause excessive IPC. + */ +#define INSANE_STATISTICS GNUNET_NO + /** * Handle to cancel a transmission request. @@ -68,12 +73,6 @@ struct GSF_PeerTransmitHandle struct GSF_PeerTransmitHandle *prev; /** - * Handle for an active request for transmission to this - * peer, or NULL (if core queue was full). - */ - struct GNUNET_CORE_TransmitHandle *cth; - - /** * Time when this transmission request was issued. */ struct GNUNET_TIME_Absolute transmission_request_start_time; @@ -109,14 +108,6 @@ struct GSF_PeerTransmitHandle size_t size; /** - * Set to 1 if we're currently in the process of calling - * 'GNUNET_CORE_notify_transmit_ready' (so while cth is - * NULL, we should not call notify_transmit_ready for this - * handle right now). - */ - unsigned int cth_in_progress; - - /** * GNUNET_YES if this is a query, GNUNET_NO for content. */ int is_query; @@ -264,15 +255,29 @@ struct GSF_ConnectedPeer struct GNUNET_CONTAINER_MultiHashMap *request_map; /** + * Handle for an active request for transmission to this + * peer, or NULL (if core queue was full). + */ + struct GNUNET_CORE_TransmitHandle *cth; + + /** * Increase in traffic preference still to be submitted * to the core service for this peer. */ uint64_t inc_preference; /** - * Trust rating for this peer on disk. + * Set to 1 if we're currently in the process of calling + * 'GNUNET_CORE_notify_transmit_ready' (so while cth is + * NULL, we should not call notify_transmit_ready for this + * handle right now). + */ + unsigned int cth_in_progress; + + /** + * Respect rating for this peer on disk. */ - uint32_t disk_trust; + uint32_t disk_respect; /** * Which offset in "last_p2p_replies" will be updated next? @@ -306,28 +311,31 @@ struct GSF_ConnectedPeer static struct GNUNET_CONTAINER_MultiHashMap *cp_map; /** - * Where do we store trust information? + * Where do we store respect information? */ -static char *trustDirectory; +static char *respectDirectory; /** * Handle to ATS service. */ static struct GNUNET_ATS_PerformanceHandle *ats; + /** - * Get the filename under which we would store the GNUNET_HELLO_Message - * for the given host and protocol. - * @return filename of the form DIRECTORY/HOSTID + * Get the filename under which we would store respect + * for the given peer. + * + * @param id peer to get the filename for + * @return filename of the form DIRECTORY/PEERID */ static char * -get_trust_filename (const struct GNUNET_PeerIdentity *id) +get_respect_filename (const struct GNUNET_PeerIdentity *id) { struct GNUNET_CRYPTO_HashAsciiEncoded fil; char *fn; GNUNET_CRYPTO_hash_to_enc (&id->hashPubKey, &fil); - GNUNET_asprintf (&fn, "%s%s%s", trustDirectory, DIR_SEPARATOR_STR, &fil); + GNUNET_asprintf (&fn, "%s%s%s", respectDirectory, DIR_SEPARATOR_STR, &fil); return fn; } @@ -423,9 +431,9 @@ schedule_transmission (struct GSF_PeerTransmitHandle *pth) struct GSF_ConnectedPeer *cp; struct GNUNET_PeerIdentity target; - if ((NULL != pth->cth) || (0 != pth->cth_in_progress)) - return; /* already done */ cp = pth->cp; + if ((NULL != cp->cth) || (0 != cp->cth_in_progress)) + return; /* already done */ GNUNET_assert (0 != cp->ppd.pid); GNUNET_PEER_resolve (cp->ppd.pid, &target); @@ -448,15 +456,17 @@ schedule_transmission (struct GSF_PeerTransmitHandle *pth) cp->rc = GNUNET_ATS_reserve_bandwidth (ats, &target, DBLOCK_SIZE, &ats_reserve_callback, cp); + return; } - GNUNET_assert (pth->cth == NULL); - pth->cth_in_progress++; - pth->cth = - GNUNET_CORE_notify_transmit_ready (GSF_core, GNUNET_YES, pth->priority, - GNUNET_TIME_absolute_get_remaining - (pth->timeout), &target, pth->size, - &peer_transmit_ready_cb, pth); - GNUNET_assert (0 < pth->cth_in_progress--); + GNUNET_assert (NULL == cp->cth); + cp->cth_in_progress++; + cp->cth = + GNUNET_CORE_notify_transmit_ready (GSF_core, GNUNET_YES, pth->priority, + GNUNET_TIME_absolute_get_remaining + (pth->timeout), &target, pth->size, + &peer_transmit_ready_cb, cp); + GNUNET_assert (NULL != cp->cth); + GNUNET_assert (0 < cp->cth_in_progress--); } @@ -471,19 +481,24 @@ schedule_transmission (struct GSF_PeerTransmitHandle *pth) static size_t peer_transmit_ready_cb (void *cls, size_t size, void *buf) { - struct GSF_PeerTransmitHandle *pth = cls; + struct GSF_ConnectedPeer *cp = cls; + struct GSF_PeerTransmitHandle *pth = cp->pth_head; struct GSF_PeerTransmitHandle *pos; - struct GSF_ConnectedPeer *cp; size_t ret; - GNUNET_assert ((NULL == buf) || (pth->size <= size)); - pth->cth = NULL; - if (pth->timeout_task != GNUNET_SCHEDULER_NO_TASK) + cp->cth = NULL; + if (NULL == pth) + return 0; + if (pth->size > size) + { + schedule_transmission (pth); + return 0; + } + if (GNUNET_SCHEDULER_NO_TASK != pth->timeout_task) { GNUNET_SCHEDULER_cancel (pth->timeout_task); pth->timeout_task = GNUNET_SCHEDULER_NO_TASK; } - cp = pth->cp; GNUNET_CONTAINER_DLL_remove (cp->pth_head, cp->pth_tail, pth); if (GNUNET_YES == pth->is_query) { @@ -500,14 +515,11 @@ peer_transmit_ready_cb (void *cls, size_t size, void *buf) GNUNET_TIME_absolute_get_duration (pth->transmission_request_start_time).rel_value); ret = pth->gmc (pth->gmc_cls, size, buf); - GNUNET_assert (NULL == pth->cth); - for (pos = cp->pth_head; pos != NULL; pos = pos->next) + if (NULL != (pos = cp->pth_head)) { GNUNET_assert (pos != pth); schedule_transmission (pos); } - GNUNET_assert (pth->cth == NULL); - GNUNET_assert (pth->cth_in_progress == 0); GNUNET_free (pth); return ret; } @@ -551,8 +563,9 @@ ats_reserve_callback (void *cls, const struct GNUNET_PeerIdentity *peer, struct GSF_PeerTransmitHandle *pth; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Reserved %d bytes / need to wait %llu ms for reservation\n", - (int) amount, (unsigned long long) res_delay.rel_value); + "Reserved %d bytes / need to wait %s for reservation\n", + (int) amount, + GNUNET_STRINGS_relative_time_to_string (res_delay, GNUNET_YES)); cp->rc = NULL; if (0 == amount) { @@ -562,16 +575,17 @@ ats_reserve_callback (void *cls, const struct GNUNET_PeerIdentity *peer, } cp->did_reserve = GNUNET_YES; pth = cp->pth_head; - if ((NULL != pth) && (NULL == pth->cth)) + if ((NULL != pth) && (NULL == cp->cth) && (0 == cp->cth_in_progress)) { /* reservation success, try transmission now! */ - pth->cth_in_progress++; - pth->cth = + cp->cth_in_progress++; + cp->cth = GNUNET_CORE_notify_transmit_ready (GSF_core, GNUNET_YES, pth->priority, GNUNET_TIME_absolute_get_remaining (pth->timeout), peer, pth->size, - &peer_transmit_ready_cb, pth); - GNUNET_assert (0 < pth->cth_in_progress--); + &peer_transmit_ready_cb, cp); + GNUNET_assert (NULL != cp->cth); + GNUNET_assert (0 < cp->cth_in_progress--); } } @@ -592,7 +606,7 @@ GSF_peer_connect_handler_ (const struct GNUNET_PeerIdentity *peer, { struct GSF_ConnectedPeer *cp; char *fn; - uint32_t trust; + uint32_t respect; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to peer %s\n", GNUNET_i2s (peer)); @@ -602,14 +616,15 @@ GSF_peer_connect_handler_ (const struct GNUNET_PeerIdentity *peer, cp->rc = GNUNET_ATS_reserve_bandwidth (ats, peer, DBLOCK_SIZE, &ats_reserve_callback, cp); - fn = get_trust_filename (peer); - if ((GNUNET_DISK_file_test (fn) == GNUNET_YES) && - (sizeof (trust) == GNUNET_DISK_fn_read (fn, &trust, sizeof (trust)))) - cp->disk_trust = cp->ppd.trust = ntohl (trust); + fn = get_respect_filename (peer); + if ((GNUNET_YES == GNUNET_DISK_file_test (fn)) && + (sizeof (respect) == GNUNET_DISK_fn_read (fn, &respect, sizeof (respect)))) + cp->disk_respect = cp->ppd.respect = ntohl (respect); GNUNET_free (fn); - cp->request_map = GNUNET_CONTAINER_multihashmap_create (128); + cp->request_map = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO); GNUNET_break (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (cp_map, &peer->hashPubKey, + GNUNET_CONTAINER_multihashmap_put (cp_map, + &GSF_connected_peer_get_identity2_ (cp)->hashPubKey, cp, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# peers connected"), @@ -687,7 +702,7 @@ GSF_handle_p2p_migration_stop_ (void *cls, msm = (const struct MigrationStopMessage *) message; cp = GSF_peer_get_ (other); - if (cp == NULL) + if (NULL == cp) { GNUNET_break (0); return GNUNET_OK; @@ -697,10 +712,11 @@ GSF_handle_p2p_migration_stop_ (void *cls, 1, GNUNET_NO); bt = GNUNET_TIME_relative_ntoh (msm->duration); GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Migration of content to peer `%s' blocked for %llu ms\n"), - GNUNET_i2s (other), (unsigned long long) bt.rel_value); + _("Migration of content to peer `%s' blocked for %s\n"), + GNUNET_i2s (other), + GNUNET_STRINGS_relative_time_to_string (bt, GNUNET_YES)); cp->ppd.migration_blocked_until = GNUNET_TIME_relative_to_absolute (bt); - if (cp->mig_revive_task == GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK == cp->mig_revive_task) { GSF_push_stop_ (cp); cp->mig_revive_task = @@ -725,7 +741,7 @@ copy_reply (void *cls, size_t buf_size, void *buf) struct PutMessage *pm = cls; size_t size; - if (buf != NULL) + if (NULL != buf) { GNUNET_assert (buf_size >= ntohs (pm->header.size)); size = ntohs (pm->header.size); @@ -754,11 +770,11 @@ copy_reply (void *cls, size_t buf_size, void *buf) */ static void free_pending_request (struct PeerRequest *peerreq, - const GNUNET_HashCode *query) + const struct GNUNET_HashCode *query) { struct GSF_ConnectedPeer *cp = peerreq->cp; - if (peerreq->kill_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != peerreq->kill_task) { GNUNET_SCHEDULER_cancel (peerreq->kill_task); peerreq->kill_task = GNUNET_SCHEDULER_NO_TASK; @@ -781,7 +797,7 @@ free_pending_request (struct PeerRequest *peerreq, * @return GNUNET_YES (continue to iterate) */ static int -cancel_pending_request (void *cls, const GNUNET_HashCode * query, void *value) +cancel_pending_request (void *cls, const struct GNUNET_HashCode * query, void *value) { struct PeerRequest *peerreq = value; struct GSF_PendingRequest *pr = peerreq->pr; @@ -853,11 +869,12 @@ get_randomized_delay () GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 2 * GSF_avg_latency.rel_value + 1)); +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# artificial delays introduced (ms)"), ret.rel_value, GNUNET_NO); - +#endif return ret; } @@ -903,8 +920,8 @@ handle_p2p_reply (void *cls, enum GNUNET_BLOCK_EvaluationResult eval, free_pending_request (peerreq, &prd->query); return; } - GNUNET_break (type != GNUNET_BLOCK_TYPE_ANY); - if ((prd->type != type) && (prd->type != GNUNET_BLOCK_TYPE_ANY)) + GNUNET_break (GNUNET_BLOCK_TYPE_ANY != type); + if ((prd->type != type) && (GNUNET_BLOCK_TYPE_ANY != prd->type)) { GNUNET_STATISTICS_update (GSF_stats, gettext_noop @@ -924,7 +941,7 @@ handle_p2p_reply (void *cls, enum GNUNET_BLOCK_EvaluationResult eval, GNUNET_break (0); return; } - if ((reply_anonymity_level != UINT32_MAX) && (reply_anonymity_level > 1)) + if ((UINT32_MAX != reply_anonymity_level) && (reply_anonymity_level > 1)) { if (reply_anonymity_level - 1 > GSF_cover_content_count) { @@ -943,8 +960,8 @@ handle_p2p_reply (void *cls, enum GNUNET_BLOCK_EvaluationResult eval, pm->type = htonl (type); pm->expiration = GNUNET_TIME_absolute_hton (expiration); memcpy (&pm[1], data, data_len); - if ((reply_anonymity_level != UINT32_MAX) && (reply_anonymity_level != 0) && - (GSF_enable_randomized_delays == GNUNET_YES)) + if ((UINT32_MAX != reply_anonymity_level) && (0 != reply_anonymity_level) && + (GNUNET_YES == GSF_enable_randomized_delays)) { struct GSF_DelayedHandle *dh; @@ -962,7 +979,7 @@ handle_p2p_reply (void *cls, enum GNUNET_BLOCK_EvaluationResult eval, (void) GSF_peer_transmit_ (cp, GNUNET_NO, UINT32_MAX, REPLY_TIMEOUT, msize, ©_reply, pm); } - if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST) + if (GNUNET_BLOCK_EVALUATION_OK_LAST != eval) return; if (GNUNET_SCHEDULER_NO_TASK == peerreq->kill_task) { @@ -977,38 +994,38 @@ handle_p2p_reply (void *cls, enum GNUNET_BLOCK_EvaluationResult eval, /** - * Increase the host credit by a value. + * Increase the peer's respect by a value. * - * @param cp which peer to change the trust value on + * @param cp which peer to change the respect value on * @param value is the int value by which the - * host credit is to be increased or decreased - * @returns the actual change in trust (positive or negative) + * peer's credit is to be increased or decreased + * @returns the actual change in respect (positive or negative) */ static int -change_host_trust (struct GSF_ConnectedPeer *cp, int value) +change_peer_respect (struct GSF_ConnectedPeer *cp, int value) { - if (value == 0) + if (0 == value) return 0; - GNUNET_assert (cp != NULL); + GNUNET_assert (NULL != cp); if (value > 0) { - if (cp->ppd.trust + value < cp->ppd.trust) + if (cp->ppd.respect + value < cp->ppd.respect) { - value = UINT32_MAX - cp->ppd.trust; - cp->ppd.trust = UINT32_MAX; + value = UINT32_MAX - cp->ppd.respect; + cp->ppd.respect = UINT32_MAX; } else - cp->ppd.trust += value; + cp->ppd.respect += value; } else { - if (cp->ppd.trust < -value) + if (cp->ppd.respect < -value) { - value = -cp->ppd.trust; - cp->ppd.trust = 0; + value = -cp->ppd.respect; + cp->ppd.respect = 0; } else - cp->ppd.trust += value; + cp->ppd.respect += value; } return value; } @@ -1016,7 +1033,7 @@ change_host_trust (struct GSF_ConnectedPeer *cp, int value) /** * We've received a request with the specified priority. Bound it - * according to how much we trust the given peer. + * according to how much we respect the given peer. * * @param prio_in requested priority * @param cp the peer making the request @@ -1031,17 +1048,19 @@ bound_priority (uint32_t prio_in, struct GSF_ConnectedPeer *cp) int ld; ld = GSF_test_get_load_too_high_ (0); - if (ld == GNUNET_SYSERR) + if (GNUNET_SYSERR == ld) { +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# requests done for free (low load)"), 1, GNUNET_NO); +#endif return 0; /* excess resources */ } if (prio_in > INT32_MAX) prio_in = INT32_MAX; - ret = -change_host_trust (cp, -(int) prio_in); + ret = -change_peer_respect (cp, -(int) prio_in); if (ret > 0) { if (ret > GSF_current_priorities + N) @@ -1050,19 +1069,19 @@ bound_priority (uint32_t prio_in, struct GSF_ConnectedPeer *cp) rret = ret; GSF_current_priorities = (GSF_current_priorities * (N - 1) + rret) / N; } - if ((ld == GNUNET_YES) && (ret > 0)) + if ((GNUNET_YES == ld) && (ret > 0)) { /* try with charging */ ld = GSF_test_get_load_too_high_ (ret); } - if (ld == GNUNET_YES) + if (GNUNET_YES == ld) { GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# request dropped, priority insufficient"), 1, GNUNET_NO); /* undo charge */ - change_host_trust (cp, (int) ret); + change_peer_respect (cp, (int) ret); return -1; /* not enough resources */ } else @@ -1124,13 +1143,13 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, struct GSF_PendingRequestData *prd; struct GSF_ConnectedPeer *cp; struct GSF_ConnectedPeer *cps; - const GNUNET_HashCode *namespace; + const struct GNUNET_HashCode *namespace; const struct GNUNET_PeerIdentity *target; enum GSF_PendingRequestOptions options; uint16_t msize; const struct GetMessage *gm; unsigned int bits; - const GNUNET_HashCode *opt; + const struct GNUNET_HashCode *opt; uint32_t bm; size_t bfsize; uint32_t ttl_decrement; @@ -1160,13 +1179,13 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, bits++; bm >>= 1; } - if (msize < sizeof (struct GetMessage) + bits * sizeof (GNUNET_HashCode)) + if (msize < sizeof (struct GetMessage) + bits * sizeof (struct GNUNET_HashCode)) { GNUNET_break_op (0); return NULL; } - opt = (const GNUNET_HashCode *) &gm[1]; - bfsize = msize - sizeof (struct GetMessage) - bits * sizeof (GNUNET_HashCode); + opt = (const struct GNUNET_HashCode *) &gm[1]; + bfsize = msize - sizeof (struct GetMessage) - bits * sizeof (struct GNUNET_HashCode); /* bfsize must be power of 2, check! */ if (0 != ((bfsize - 1) & bfsize)) { @@ -1190,7 +1209,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, cp = GSF_peer_get_ ((const struct GNUNET_PeerIdentity *) &opt[bits++]); else cp = cps; - if (cp == NULL) + if (NULL == cp) { if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO)) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1202,10 +1221,12 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to find peer `%4s' in connection set. Dropping query.\n", GNUNET_i2s (other)); +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# requests dropped due to missing reverse route"), 1, GNUNET_NO); +#endif return NULL; } /* note that we can really only check load here since otherwise @@ -1224,12 +1245,12 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, GNUNET_h2s (&gm->query), (unsigned int) type, GNUNET_i2s (other), (unsigned int) bm); namespace = (0 != (bm & GET_MESSAGE_BIT_SKS_NAMESPACE)) ? &opt[bits++] : NULL; - if ((type == GNUNET_BLOCK_TYPE_FS_SBLOCK) && (namespace == NULL)) + if ((GNUNET_BLOCK_TYPE_FS_SBLOCK == type) && (NULL == namespace)) { GNUNET_break_op (0); return NULL; } - if ((type != GNUNET_BLOCK_TYPE_FS_SBLOCK) && (namespace != NULL)) + if ((GNUNET_BLOCK_TYPE_FS_SBLOCK != type) && (NULL != namespace)) { GNUNET_break_op (0); return NULL; @@ -1279,7 +1300,7 @@ GSF_handle_p2p_query_ (const struct GNUNET_PeerIdentity *other, prd = GSF_pending_request_get_data_ (pr); if ((prd->type == type) && ((type != GNUNET_BLOCK_TYPE_FS_SBLOCK) || - (0 == memcmp (&prd->namespace, namespace, sizeof (GNUNET_HashCode))))) + (0 == memcmp (&prd->namespace, namespace, sizeof (struct GNUNET_HashCode))))) { if (prd->ttl.abs_value >= GNUNET_TIME_absolute_get ().abs_value + ttl) { @@ -1350,13 +1371,13 @@ peer_transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) else if (GNUNET_NO == pth->is_query) GNUNET_assert (0 < cp->ppd.pending_replies--); GNUNET_LOAD_update (cp->ppd.transmission_delay, UINT64_MAX); - if (NULL != pth->cth) + if (NULL != cp->cth) { - GNUNET_CORE_notify_transmit_ready_cancel (pth->cth); - pth->cth = NULL; + GNUNET_CORE_notify_transmit_ready_cancel (cp->cth); + cp->cth = NULL; } pth->gmc (pth->gmc_cls, 0, NULL); - GNUNET_assert (0 == pth->cth_in_progress); + GNUNET_assert (0 == cp->cth_in_progress); GNUNET_free (pth); } @@ -1396,15 +1417,12 @@ GSF_peer_transmit_ (struct GSF_ConnectedPeer *cp, int is_query, /* insertion sort (by priority, descending) */ prev = NULL; pos = cp->pth_head; - while ((pos != NULL) && (pos->priority > priority)) + while ((NULL != pos) && (pos->priority > priority)) { prev = pos; pos = pos->next; } - if (prev == NULL) - GNUNET_CONTAINER_DLL_insert (cp->pth_head, cp->pth_tail, pth); - else - GNUNET_CONTAINER_DLL_insert_after (cp->pth_head, cp->pth_tail, prev, pth); + GNUNET_CONTAINER_DLL_insert_after (cp->pth_head, cp->pth_tail, prev, pth); if (GNUNET_YES == is_query) cp->ppd.pending_queries++; else if (GNUNET_NO == is_query) @@ -1426,23 +1444,17 @@ GSF_peer_transmit_cancel_ (struct GSF_PeerTransmitHandle *pth) { struct GSF_ConnectedPeer *cp; - if (pth->timeout_task != GNUNET_SCHEDULER_NO_TASK) + if (GNUNET_SCHEDULER_NO_TASK != pth->timeout_task) { GNUNET_SCHEDULER_cancel (pth->timeout_task); pth->timeout_task = GNUNET_SCHEDULER_NO_TASK; } - if (NULL != pth->cth) - { - GNUNET_CORE_notify_transmit_ready_cancel (pth->cth); - pth->cth = NULL; - } cp = pth->cp; GNUNET_CONTAINER_DLL_remove (cp->pth_head, cp->pth_tail, pth); if (GNUNET_YES == pth->is_query) GNUNET_assert (0 < cp->ppd.pending_queries--); else if (GNUNET_NO == pth->is_query) GNUNET_assert (0 < cp->ppd.pending_replies--); - GNUNET_assert (0 == pth->cth_in_progress); GNUNET_free (pth); } @@ -1556,20 +1568,20 @@ GSF_peer_disconnect_handler_ (void *cls, const struct GNUNET_PeerIdentity *peer) GNUNET_PEER_decrement_rcs (cp->ppd.last_p2p_replies, P2P_SUCCESS_LIST_SIZE); memset (cp->ppd.last_p2p_replies, 0, sizeof (cp->ppd.last_p2p_replies)); GSF_push_stop_ (cp); + if (NULL != cp->cth) + { + GNUNET_CORE_notify_transmit_ready_cancel (cp->cth); + cp->cth = NULL; + } + GNUNET_assert (0 == cp->cth_in_progress); while (NULL != (pth = cp->pth_head)) { - if (NULL != pth->cth) - { - GNUNET_CORE_notify_transmit_ready_cancel (pth->cth); - pth->cth = NULL; - } if (pth->timeout_task != GNUNET_SCHEDULER_NO_TASK) { GNUNET_SCHEDULER_cancel (pth->timeout_task); pth->timeout_task = GNUNET_SCHEDULER_NO_TASK; } GNUNET_CONTAINER_DLL_remove (cp->pth_head, cp->pth_tail, pth); - GNUNET_assert (0 == pth->cth_in_progress); pth->gmc (pth->gmc_cls, 0, NULL); GNUNET_free (pth); } @@ -1616,7 +1628,7 @@ struct IterationContext * @return GNUNET_YES to continue iteration */ static int -call_iterator (void *cls, const GNUNET_HashCode * key, void *value) +call_iterator (void *cls, const struct GNUNET_HashCode * key, void *value) { struct IterationContext *ic = cls; struct GSF_ConnectedPeer *cp = value; @@ -1646,7 +1658,7 @@ GSF_iterate_connected_peers_ (GSF_ConnectedPeerIterator it, void *it_cls) /** * Obtain the identity of a connected peer. * - * @param cp peer to reserve bandwidth from + * @param cp peer to get identity of * @param id identity to set (written to) */ void @@ -1659,6 +1671,20 @@ GSF_connected_peer_get_identity_ (const struct GSF_ConnectedPeer *cp, /** + * Obtain the identity of a connected peer. + * + * @param cp peer to get identity of + * @return reference to peer identity, valid until peer disconnects (!) + */ +const struct GNUNET_PeerIdentity * +GSF_connected_peer_get_identity2_ (const struct GSF_ConnectedPeer *cp) +{ + GNUNET_assert (0 != cp->ppd.pid); + return GNUNET_PEER_resolve2 (cp->ppd.pid); +} + + +/** * Assemble a migration stop message for transmission. * * @param cls the 'struct GSF_ConnectedPeer' to use @@ -1704,16 +1730,15 @@ GSF_block_peer_migration_ (struct GSF_ConnectedPeer *cp, if (cp->last_migration_block.abs_value > block_time.abs_value) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Migration already blocked for another %llu ms\n", - (unsigned long long) - GNUNET_TIME_absolute_get_remaining - (cp->last_migration_block).rel_value); + "Migration already blocked for another %s\n", + GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining + (cp->last_migration_block), GNUNET_YES)); return; /* already blocked */ } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking to stop migration for %llu ms\n", (unsigned long long) GNUNET_TIME_absolute_get_remaining (block_time).rel_value); cp->last_migration_block = block_time; - if (cp->migration_pth != NULL) + if (NULL != cp->migration_pth) GSF_peer_transmit_cancel_ (cp->migration_pth); cp->migration_pth = GSF_peer_transmit_ (cp, GNUNET_SYSERR, UINT32_MAX, @@ -1724,27 +1749,27 @@ GSF_block_peer_migration_ (struct GSF_ConnectedPeer *cp, /** - * Write host-trust information to a file - flush the buffer entry! + * Write peer-respect information to a file - flush the buffer entry! * - * @param cls closure, not used - * @param key host identity + * @param cls unused + * @param key peer identity * @param value the 'struct GSF_ConnectedPeer' to flush * @return GNUNET_OK to continue iteration */ static int -flush_trust (void *cls, const GNUNET_HashCode * key, void *value) +flush_respect (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GSF_ConnectedPeer *cp = value; char *fn; - uint32_t trust; + uint32_t respect; struct GNUNET_PeerIdentity pid; - if (cp->ppd.trust == cp->disk_trust) + if (cp->ppd.respect == cp->disk_respect) return GNUNET_OK; /* unchanged */ GNUNET_assert (0 != cp->ppd.pid); GNUNET_PEER_resolve (cp->ppd.pid, &pid); - fn = get_trust_filename (&pid); - if (cp->ppd.trust == 0) + fn = get_respect_filename (&pid); + if (cp->ppd.respect == 0) { if ((0 != UNLINK (fn)) && (errno != ENOENT)) GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING | @@ -1752,14 +1777,14 @@ flush_trust (void *cls, const GNUNET_HashCode * key, void *value) } else { - trust = htonl (cp->ppd.trust); + respect = htonl (cp->ppd.respect); if (sizeof (uint32_t) == - GNUNET_DISK_fn_write (fn, &trust, sizeof (uint32_t), + GNUNET_DISK_fn_write (fn, &respect, sizeof (uint32_t), GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE | GNUNET_DISK_PERM_GROUP_READ | GNUNET_DISK_PERM_OTHER_READ)) - cp->disk_trust = cp->ppd.trust; + cp->disk_respect = cp->ppd.respect; } GNUNET_free (fn); return GNUNET_OK; @@ -1784,25 +1809,25 @@ GSF_connected_peer_change_preference_ (struct GSF_ConnectedPeer *cp, /** - * Call this method periodically to flush trust information to disk. + * Call this method periodically to flush respect information to disk. * * @param cls closure, not used * @param tc task context, not used */ static void -cron_flush_trust (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +cron_flush_respect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { if (NULL == cp_map) return; - GNUNET_CONTAINER_multihashmap_iterate (cp_map, &flush_trust, NULL); + GNUNET_CONTAINER_multihashmap_iterate (cp_map, &flush_respect, NULL); if (NULL == tc) return; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) return; - GNUNET_SCHEDULER_add_delayed_with_priority (TRUST_FLUSH_FREQ, + GNUNET_SCHEDULER_add_delayed_with_priority (RESPECT_FLUSH_FREQ, GNUNET_SCHEDULER_PRIORITY_HIGH, - &cron_flush_trust, NULL); + &cron_flush_respect, NULL); } @@ -1812,15 +1837,15 @@ cron_flush_trust (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) void GSF_connected_peer_init_ () { - cp_map = GNUNET_CONTAINER_multihashmap_create (128); + cp_map = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_YES); ats = GNUNET_ATS_performance_init (GSF_cfg, NULL, NULL); GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename (GSF_cfg, "fs", - "TRUST", - &trustDirectory)); - GNUNET_DISK_directory_create (trustDirectory); + "RESPECT", + &respectDirectory)); + GNUNET_DISK_directory_create (respectDirectory); GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_HIGH, - &cron_flush_trust, NULL); + &cron_flush_respect, NULL); } @@ -1833,7 +1858,7 @@ GSF_connected_peer_init_ () * @return GNUNET_YES (we should continue to iterate) */ static int -clean_peer (void *cls, const GNUNET_HashCode * key, void *value) +clean_peer (void *cls, const struct GNUNET_HashCode * key, void *value) { GSF_peer_disconnect_handler_ (NULL, (const struct GNUNET_PeerIdentity *) key); return GNUNET_YES; @@ -1846,12 +1871,12 @@ clean_peer (void *cls, const GNUNET_HashCode * key, void *value) void GSF_connected_peer_done_ () { - cron_flush_trust (NULL, NULL); + cron_flush_respect (NULL, NULL); GNUNET_CONTAINER_multihashmap_iterate (cp_map, &clean_peer, NULL); GNUNET_CONTAINER_multihashmap_destroy (cp_map); cp_map = NULL; - GNUNET_free (trustDirectory); - trustDirectory = NULL; + GNUNET_free (respectDirectory); + respectDirectory = NULL; GNUNET_ATS_performance_done (ats); ats = NULL; } @@ -1866,7 +1891,7 @@ GSF_connected_peer_done_ () * @return GNUNET_YES (we should continue to iterate) */ static int -clean_local_client (void *cls, const GNUNET_HashCode * key, void *value) +clean_local_client (void *cls, const struct GNUNET_HashCode * key, void *value) { const struct GSF_LocalClient *lc = cls; struct GSF_ConnectedPeer *cp = value; diff --git a/src/fs/gnunet-service-fs_cp.h b/src/fs/gnunet-service-fs_cp.h index e3c7cd2..3bb05ac 100644 --- a/src/fs/gnunet-service-fs_cp.h +++ b/src/fs/gnunet-service-fs_cp.h @@ -133,9 +133,9 @@ struct GSF_PeerPerformanceData GNUNET_PEER_Id pid; /** - * Trust rating for this peer + * Respect rating for this peer */ - uint32_t trust; + uint32_t respect; /** * Number of pending queries (replies are not counted) @@ -384,7 +384,7 @@ GSF_connected_peer_change_preference_ (struct GSF_ConnectedPeer *cp, /** * Obtain the identity of a connected peer. * - * @param cp peer to reserve bandwidth from + * @param cp peer to get identity of * @param id identity to set (written to) */ void @@ -393,6 +393,17 @@ GSF_connected_peer_get_identity_ (const struct GSF_ConnectedPeer *cp, /** + * Obtain the identity of a connected peer. + * + * @param cp peer to get identity of + * @return reference to peer identity, valid until peer disconnects (!) + */ +const struct GNUNET_PeerIdentity * +GSF_connected_peer_get_identity2_ (const struct GSF_ConnectedPeer *cp); + + + +/** * Iterate over all connected peers. * * @param it function to call for each peer diff --git a/src/fs/gnunet-service-fs_indexing.c b/src/fs/gnunet-service-fs_indexing.c index e452894..1baab4c 100644 --- a/src/fs/gnunet-service-fs_indexing.c +++ b/src/fs/gnunet-service-fs_indexing.c @@ -43,11 +43,16 @@ struct IndexInfo { /** - * This is a linked list. + * This is a doubly linked list. */ struct IndexInfo *next; /** + * This is a doubly linked list. + */ + struct IndexInfo *prev; + + /** * Name of the indexed file. Memory allocated * at the end of this struct (do not free). */ @@ -67,18 +72,23 @@ struct IndexInfo /** * Hash of the contents of the file. */ - GNUNET_HashCode file_id; + struct GNUNET_HashCode file_id; }; /** - * Linked list of indexed files. + * Head of linked list of indexed files. + */ +static struct IndexInfo *indexed_files_head; + +/** + * Tail of linked list of indexed files. */ -static struct IndexInfo *indexed_files; +static struct IndexInfo *indexed_files_tail; /** - * Maps hash over content of indexed files to the respective filename. + * Maps hash over content of indexed files to the respective 'struct IndexInfo'. * The filenames are pointers into the indexed_files linked list and * do not need to be freed. */ @@ -109,9 +119,8 @@ write_index_list () if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "FS", "INDEXDB", &fn)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - _("Configuration option `%s' in section `%s' missing.\n"), - "INDEXDB", "FS"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + "fs", "INDEXDB"); return; } wh = GNUNET_BIO_write_open (fn); @@ -122,15 +131,11 @@ write_index_list () GNUNET_free (fn); return; } - pos = indexed_files; - while (pos != NULL) - { + for (pos = indexed_files_head; NULL != pos; pos = pos->next) if ((GNUNET_OK != - GNUNET_BIO_write (wh, &pos->file_id, sizeof (GNUNET_HashCode))) || + GNUNET_BIO_write (wh, &pos->file_id, sizeof (struct GNUNET_HashCode))) || (GNUNET_OK != GNUNET_BIO_write_string (wh, pos->filename))) break; - pos = pos->next; - } if (GNUNET_OK != GNUNET_BIO_write_close (wh)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, @@ -152,16 +157,15 @@ read_index_list () char *fn; struct IndexInfo *pos; char *fname; - GNUNET_HashCode hc; + struct GNUNET_HashCode hc; size_t slen; char *emsg; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "FS", "INDEXDB", &fn)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, - _("Configuration option `%s' in section `%s' missing.\n"), - "INDEXDB", "FS"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, + "fs", "INDEXDB"); return; } if (GNUNET_NO == GNUNET_DISK_file_test (fn)) @@ -180,7 +184,7 @@ read_index_list () } while ((GNUNET_OK == GNUNET_BIO_read (rh, "Hash of indexed file", &hc, - sizeof (GNUNET_HashCode))) && + sizeof (struct GNUNET_HashCode))) && (GNUNET_OK == GNUNET_BIO_read_string (rh, "Name of indexed file", &fname, 1024 * 16)) && (fname != NULL)) @@ -191,15 +195,16 @@ read_index_list () pos->filename = (const char *) &pos[1]; memcpy (&pos[1], fname, slen); if (GNUNET_SYSERR == - GNUNET_CONTAINER_multihashmap_put (ifm, &hc, (void *) pos->filename, + GNUNET_CONTAINER_multihashmap_put (ifm, &pos->file_id, pos, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) { GNUNET_free (pos); } else { - pos->next = indexed_files; - indexed_files = pos; + GNUNET_CONTAINER_DLL_insert (indexed_files_head, + indexed_files_tail, + pos); } GNUNET_free (fname); } @@ -218,25 +223,29 @@ read_index_list () static void signal_index_ok (struct IndexInfo *ii) { + struct IndexInfo *ir; if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (ifm, &ii->file_id, - (void *) ii->filename, + ii, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) { + ir = GNUNET_CONTAINER_multihashmap_get (ifm, + &ii->file_id); + GNUNET_assert (NULL != ir); GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Index request received for file `%s' is already indexed as `%s'. Permitting anyway.\n"), ii->filename, - (const char *) GNUNET_CONTAINER_multihashmap_get (ifm, - &ii->file_id)); + ir->filename); GNUNET_SERVER_transmit_context_append_data (ii->tc, NULL, 0, GNUNET_MESSAGE_TYPE_FS_INDEX_START_OK); GNUNET_SERVER_transmit_context_run (ii->tc, GNUNET_TIME_UNIT_MINUTES); GNUNET_free (ii); return; } - ii->next = indexed_files; - indexed_files = ii; + GNUNET_CONTAINER_DLL_insert (indexed_files_head, + indexed_files_tail, + ii); write_index_list (); GNUNET_SERVER_transmit_context_append_data (ii->tc, NULL, 0, GNUNET_MESSAGE_TYPE_FS_INDEX_START_OK); @@ -253,13 +262,13 @@ signal_index_ok (struct IndexInfo *ii) * @param res resulting hash, NULL on error */ static void -hash_for_index_val (void *cls, const GNUNET_HashCode * res) +hash_for_index_val (void *cls, const struct GNUNET_HashCode * res) { struct IndexInfo *ii = cls; ii->fhc = NULL; if ((res == NULL) || - (0 != memcmp (res, &ii->file_id, sizeof (GNUNET_HashCode)))) + (0 != memcmp (res, &ii->file_id, sizeof (struct GNUNET_HashCode)))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ @@ -375,8 +384,7 @@ GNUNET_FS_handle_index_list_get (void *cls, struct GNUNET_SERVER_Client *client, tc = GNUNET_SERVER_transmit_context_create (client); iim = (struct IndexInfoMessage *) buf; - pos = indexed_files; - while (NULL != pos) + for (pos = indexed_files_head; NULL != pos; pos = pos->next) { fn = pos->filename; slen = strlen (fn) + 1; @@ -392,7 +400,6 @@ GNUNET_FS_handle_index_list_get (void *cls, struct GNUNET_SERVER_Client *client, iim->file_id = pos->file_id; memcpy (&iim[1], fn, slen); GNUNET_SERVER_transmit_context_append_message (tc, &iim->header); - pos = pos->next; } GNUNET_SERVER_transmit_context_append_data (tc, NULL, 0, GNUNET_MESSAGE_TYPE_FS_INDEX_LIST_END); @@ -413,8 +420,6 @@ GNUNET_FS_handle_unindex (void *cls, struct GNUNET_SERVER_Client *client, { const struct UnindexMessage *um; struct IndexInfo *pos; - struct IndexInfo *prev; - struct IndexInfo *next; struct GNUNET_SERVER_TransmitContext *tc; int found; @@ -426,29 +431,20 @@ GNUNET_FS_handle_unindex (void *cls, struct GNUNET_SERVER_Client *client, return; } found = GNUNET_NO; - prev = NULL; - pos = indexed_files; - while (NULL != pos) + for (pos = indexed_files_head; NULL != pos; pos = pos->next) { - next = pos->next; - if (0 == memcmp (&pos->file_id, &um->file_id, sizeof (GNUNET_HashCode))) + if (0 == memcmp (&pos->file_id, &um->file_id, sizeof (struct GNUNET_HashCode))) { - if (prev == NULL) - indexed_files = next; - else - prev->next = next; + GNUNET_CONTAINER_DLL_remove (indexed_files_head, + indexed_files_tail, + pos); GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (ifm, &pos->file_id, - (void *) - pos->filename)); + pos)); GNUNET_free (pos); found = GNUNET_YES; + break; } - else - { - prev = pos; - } - pos = next; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client requested unindexing of file `%s': %s\n", @@ -502,7 +498,7 @@ remove_cont (void *cls, int success, * @return GNUNET_OK on success */ int -GNUNET_FS_handle_on_demand_block (const GNUNET_HashCode * key, uint32_t size, +GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, @@ -511,16 +507,17 @@ GNUNET_FS_handle_on_demand_block (const GNUNET_HashCode * key, uint32_t size, void *cont_cls) { const struct OnDemandBlock *odb; - GNUNET_HashCode nkey; + struct GNUNET_HashCode nkey; struct GNUNET_CRYPTO_AesSessionKey skey; struct GNUNET_CRYPTO_AesInitializationVector iv; - GNUNET_HashCode query; + struct GNUNET_HashCode query; ssize_t nsize; char ndata[DBLOCK_SIZE]; char edata[DBLOCK_SIZE]; const char *fn; struct GNUNET_DISK_FileHandle *fh; uint64_t off; + struct IndexInfo *ii; if (size != sizeof (struct OnDemandBlock)) { @@ -531,7 +528,13 @@ GNUNET_FS_handle_on_demand_block (const GNUNET_HashCode * key, uint32_t size, } odb = (const struct OnDemandBlock *) data; off = GNUNET_ntohll (odb->offset); - fn = (const char *) GNUNET_CONTAINER_multihashmap_get (ifm, &odb->file_id); + ii = GNUNET_CONTAINER_multihashmap_get (ifm, &odb->file_id); + if (NULL == ii) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + fn = ii->filename; if ((NULL == fn) || (0 != ACCESS (fn, R_OK))) { GNUNET_STATISTICS_update (GSF_stats, @@ -565,7 +568,7 @@ GNUNET_FS_handle_on_demand_block (const GNUNET_HashCode * key, uint32_t size, GNUNET_CRYPTO_hash_to_aes_key (&nkey, &skey, &iv); GNUNET_CRYPTO_aes_encrypt (ndata, nsize, &skey, &iv, edata); GNUNET_CRYPTO_hash (edata, nsize, &query); - if (0 != memcmp (&query, key, sizeof (GNUNET_HashCode))) + if (0 != memcmp (&query, key, sizeof (struct GNUNET_HashCode))) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Indexed file `%s' changed at offset %llu\n"), fn, @@ -590,15 +593,20 @@ GNUNET_FS_indexing_done () { struct IndexInfo *pos; - GNUNET_CONTAINER_multihashmap_destroy (ifm); - ifm = NULL; - while (NULL != (pos = indexed_files)) + while (NULL != (pos = indexed_files_head)) { - indexed_files = pos->next; + GNUNET_CONTAINER_DLL_remove (indexed_files_head, + indexed_files_tail, + pos); if (pos->fhc != NULL) GNUNET_CRYPTO_hash_file_cancel (pos->fhc); + GNUNET_break (GNUNET_OK == + GNUNET_CONTAINER_multihashmap_remove (ifm, + &pos->file_id, pos)); GNUNET_free (pos); } + GNUNET_CONTAINER_multihashmap_destroy (ifm); + ifm = NULL; cfg = NULL; } @@ -615,7 +623,7 @@ GNUNET_FS_indexing_init (const struct GNUNET_CONFIGURATION_Handle *c, { cfg = c; dsh = d; - ifm = GNUNET_CONTAINER_multihashmap_create (128); + ifm = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_YES); read_index_list (); return GNUNET_OK; } diff --git a/src/fs/gnunet-service-fs_indexing.h b/src/fs/gnunet-service-fs_indexing.h index 4295b20..3bb0af2 100644 --- a/src/fs/gnunet-service-fs_indexing.h +++ b/src/fs/gnunet-service-fs_indexing.h @@ -55,7 +55,7 @@ * @return GNUNET_OK on success */ int -GNUNET_FS_handle_on_demand_block (const GNUNET_HashCode * key, uint32_t size, +GNUNET_FS_handle_on_demand_block (const struct GNUNET_HashCode * key, uint32_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, diff --git a/src/fs/gnunet-service-fs_lc.c b/src/fs/gnunet-service-fs_lc.c index 20d430e..c3b6f40 100644 --- a/src/fs/gnunet-service-fs_lc.c +++ b/src/fs/gnunet-service-fs_lc.c @@ -197,7 +197,7 @@ client_request_destroy (void *cls, cr->kill_task = GNUNET_SCHEDULER_NO_TASK; lc = cr->lc; GNUNET_CONTAINER_DLL_remove (lc->cr_head, lc->cr_tail, cr); - GSF_pending_request_cancel_ (cr->pr, GNUNET_NO); + GSF_pending_request_cancel_ (cr->pr, GNUNET_YES); GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# client searches active"), -1, GNUNET_NO); @@ -267,15 +267,22 @@ client_response_handler (void *cls, enum GNUNET_BLOCK_EvaluationResult eval, pm->type = htonl (type); pm->expiration = GNUNET_TIME_absolute_hton (expiration); pm->last_transmission = GNUNET_TIME_absolute_hton (last_transmission); + pm->num_transmissions = htonl (prd->num_transmissions); + pm->respect_offered = htonl (prd->respect_offered); memcpy (&pm[1], data, data_len); GSF_local_client_transmit_ (lc, &pm->header); } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queued reply to query `%s' for local client\n", GNUNET_h2s (&prd->query), (unsigned int) prd->type); - if (eval != GNUNET_BLOCK_EVALUATION_OK_LAST) + if (GNUNET_BLOCK_EVALUATION_OK_LAST != eval) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Evaluation %d - keeping query alive\n", + (int) eval); return; - if (GNUNET_SCHEDULER_NO_TASK != cr->kill_task) + } + if (GNUNET_SCHEDULER_NO_TASK == cr->kill_task) cr->kill_task = GNUNET_SCHEDULER_add_now (&client_request_destroy, cr); } @@ -299,7 +306,7 @@ GSF_local_client_start_search_handler_ (struct GNUNET_SERVER_Client *client, *message, struct GSF_PendingRequest **prptr) { - static GNUNET_HashCode all_zeros; + static struct GNUNET_HashCode all_zeros; const struct SearchMessage *sm; struct GSF_LocalClient *lc; struct ClientRequest *cr; @@ -311,7 +318,7 @@ GSF_local_client_start_search_handler_ (struct GNUNET_SERVER_Client *client, msize = ntohs (message->size); if ((msize < sizeof (struct SearchMessage)) || - (0 != (msize - sizeof (struct SearchMessage)) % sizeof (GNUNET_HashCode))) + (0 != (msize - sizeof (struct SearchMessage)) % sizeof (struct GNUNET_HashCode))) { GNUNET_break (0); *prptr = NULL; @@ -320,7 +327,7 @@ GSF_local_client_start_search_handler_ (struct GNUNET_SERVER_Client *client, GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# client searches received"), 1, GNUNET_NO); - sc = (msize - sizeof (struct SearchMessage)) / sizeof (GNUNET_HashCode); + sc = (msize - sizeof (struct SearchMessage)) / sizeof (struct GNUNET_HashCode); sm = (const struct SearchMessage *) message; type = ntohl (sm->type); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -340,7 +347,7 @@ GSF_local_client_start_search_handler_ (struct GNUNET_SERVER_Client *client, (SEARCH_MESSAGE_OPTION_CONTINUED was always set) and that have a matching query and type */ if ((GNUNET_YES != prd->has_started) && - (0 != memcmp (&prd->query, &sm->query, sizeof (GNUNET_HashCode))) && + (0 != memcmp (&prd->query, &sm->query, sizeof (struct GNUNET_HashCode))) && (prd->type == type)) break; cr = cr->next; @@ -350,7 +357,7 @@ GSF_local_client_start_search_handler_ (struct GNUNET_SERVER_Client *client, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have existing request, merging content-seen lists.\n"); - GSF_pending_request_update_ (cr->pr, (const GNUNET_HashCode *) &sm[1], sc); + GSF_pending_request_update_ (cr->pr, (const struct GNUNET_HashCode *) &sm[1], sc); GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# client searches updated (merged content seen list)"), @@ -371,7 +378,7 @@ GSF_local_client_start_search_handler_ (struct GNUNET_SERVER_Client *client, : NULL, (0 != memcmp (&sm->target, &all_zeros, - sizeof (GNUNET_HashCode))) + sizeof (struct GNUNET_HashCode))) ? (const struct GNUNET_PeerIdentity *) &sm->target : NULL, NULL, 0, 0 /* bf */ , @@ -380,7 +387,7 @@ GSF_local_client_start_search_handler_ (struct GNUNET_SERVER_Client *client, 0 /* ttl */ , 0 /* sender PID */ , 0 /* origin PID */ , - (const GNUNET_HashCode *) &sm[1], sc, + (const struct GNUNET_HashCode *) &sm[1], sc, &client_response_handler, cr); } *prptr = cr->pr; @@ -478,18 +485,13 @@ GSF_client_disconnect_handler_ (void *cls, struct GNUNET_SERVER_Client *client) pos = client_head; while ((pos != NULL) && (pos->client != client)) pos = pos->next; - if (pos == NULL) + if (NULL == pos) return; while (NULL != (cr = pos->cr_head)) { - GNUNET_CONTAINER_DLL_remove (pos->cr_head, pos->cr_tail, cr); - GSF_pending_request_cancel_ (cr->pr, GNUNET_NO); - GNUNET_STATISTICS_update (GSF_stats, - gettext_noop ("# client searches active"), -1, - GNUNET_NO); if (GNUNET_SCHEDULER_NO_TASK != cr->kill_task) GNUNET_SCHEDULER_cancel (cr->kill_task); - GNUNET_free (cr); + client_request_destroy (cr, NULL); } while (NULL != (res = pos->res_head)) { diff --git a/src/fs/gnunet-service-fs_pe.c b/src/fs/gnunet-service-fs_pe.c index 71b0fc0..0992d21 100644 --- a/src/fs/gnunet-service-fs_pe.c +++ b/src/fs/gnunet-service-fs_pe.c @@ -29,6 +29,10 @@ #include "gnunet-service-fs_pe.h" #include "gnunet-service-fs_pr.h" +/** + * Collect an instane number of statistics? May cause excessive IPC. + */ +#define INSANE_STATISTICS GNUNET_NO /** * List of GSF_PendingRequests this request plan @@ -43,61 +47,55 @@ struct PeerPlan; /** - * DLL of request plans a particular pending request is - * involved with. + * M:N binding of plans to pending requests. + * Each pending request can be in a number of plans, + * and each plan can have a number of pending requests. + * Objects of this type indicate a mapping of a plan to + * a particular pending request. + * + * The corresponding head and tail of the "PE" MDLL + * are stored in a 'struct GSF_RequestPlan'. (We need + * to be able to lookup all pending requests corresponding + * to a given plan entry.) + * + * Similarly head and tail of the "PR" MDLL are stored + * with the 'struct GSF_PendingRequest'. (We need + * to be able to lookup all plan entries corresponding + * to a given pending request.) */ -struct GSF_RequestPlanReference +struct GSF_PendingRequestPlanBijection { /** * This is a doubly-linked list. */ - struct GSF_RequestPlanReference *next; + struct GSF_PendingRequestPlanBijection *next_PR; /** * This is a doubly-linked list. */ - struct GSF_RequestPlanReference *prev; + struct GSF_PendingRequestPlanBijection *prev_PR; /** - * Associated request plan. - */ - struct GSF_RequestPlan *rp; - - /** - * Corresponding PendingRequestList. + * This is a doubly-linked list. */ - struct PendingRequestList *prl; -}; - - -/** - * List of GSF_PendingRequests this request plan - * participates with. - */ -struct PendingRequestList -{ + struct GSF_PendingRequestPlanBijection *next_PE; /** * This is a doubly-linked list. */ - struct PendingRequestList *next; + struct GSF_PendingRequestPlanBijection *prev_PE; /** - * This is a doubly-linked list. + * Associated request plan. */ - struct PendingRequestList *prev; + struct GSF_RequestPlan *rp; /** * Associated pending request. */ struct GSF_PendingRequest *pr; - /** - * Corresponding GSF_RequestPlanReference. - */ - struct GSF_RequestPlanReference *rpr; - }; @@ -133,12 +131,12 @@ struct GSF_RequestPlan /** * Head of list of associated pending requests. */ - struct PendingRequestList *prl_head; + struct GSF_PendingRequestPlanBijection *pe_head; /** * Tail of list of associated pending requests. */ - struct PendingRequestList *prl_tail; + struct GSF_PendingRequestPlanBijection *pe_tail; /** * Earliest time we'd be happy to (re)transmit this request. @@ -220,14 +218,20 @@ static unsigned long long plan_count; /** * Return the query (key in the plan_map) for the given request plan. + * Note that this key may change as there can be multiple pending + * requests for the same key and we just return _one_ of them; this + * particular one might complete while another one might still be + * active, hence the lifetime of the returned hash code is NOT + * necessarily identical to that of the 'struct GSF_RequestPlan' + * given. * * @param rp a request plan * @return the associated query */ -static const GNUNET_HashCode * +static const struct GNUNET_HashCode * get_rp_key (struct GSF_RequestPlan *rp) { - return &GSF_pending_request_get_data_ (rp->prl_head->pr)->query; + return &GSF_pending_request_get_data_ (rp->pe_head->pr)->query; } @@ -264,7 +268,7 @@ plan (struct PeerPlan *pp, struct GSF_RequestPlan *rp) GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# average retransmission delay (ms)"), total_delay * 1000LL / plan_count, GNUNET_NO); - prd = GSF_pending_request_get_data_ (rp->prl_head->pr); + prd = GSF_pending_request_get_data_ (rp->pe_head->pr); if (rp->transmission_counter < 8) delay = @@ -350,17 +354,19 @@ struct GSF_PendingRequest * get_latest (const struct GSF_RequestPlan *rp) { struct GSF_PendingRequest *ret; - struct PendingRequestList *prl; - - prl = rp->prl_head; - ret = prl->pr; - prl = prl->next; - while (NULL != prl) + struct GSF_PendingRequestPlanBijection *bi; + + bi = rp->pe_head; + if (NULL == bi) + return NULL; /* should never happen */ + ret = bi->pr; + bi = bi->next_PE; + while (NULL != bi) { - if (GSF_pending_request_get_data_ (prl->pr)->ttl.abs_value > + if (GSF_pending_request_get_data_ (bi->pr)->ttl.abs_value > GSF_pending_request_get_data_ (ret)->ttl.abs_value) - ret = prl->pr; - prl = prl->next; + ret = bi->pr; + bi = bi->next_PE; } return ret; } @@ -385,6 +391,9 @@ transmit_message_callback (void *cls, size_t buf_size, void *buf) if (NULL == buf) { /* failed, try again... */ + if (GNUNET_SCHEDULER_NO_TASK != pp->task) + GNUNET_SCHEDULER_cancel (pp->task); + pp->task = GNUNET_SCHEDULER_add_now (&schedule_peer_transmission, pp); GNUNET_STATISTICS_update (GSF_stats, gettext_noop @@ -395,12 +404,16 @@ transmit_message_callback (void *cls, size_t buf_size, void *buf) rp = GNUNET_CONTAINER_heap_peek (pp->priority_heap); if (NULL == rp) { + if (GNUNET_SCHEDULER_NO_TASK != pp->task) + GNUNET_SCHEDULER_cancel (pp->task); pp->task = GNUNET_SCHEDULER_add_now (&schedule_peer_transmission, pp); return 0; } msize = GSF_pending_request_get_message_ (get_latest (rp), buf_size, buf); if (msize > buf_size) { + if (GNUNET_SCHEDULER_NO_TASK != pp->task) + GNUNET_SCHEDULER_cancel (pp->task); /* buffer to small (message changed), try again */ pp->task = GNUNET_SCHEDULER_add_now (&schedule_peer_transmission, pp); return 0; @@ -439,7 +452,7 @@ schedule_peer_transmission (void *cls, struct GNUNET_TIME_Relative delay; pp->task = GNUNET_SCHEDULER_NO_TASK; - if (pp->pth != NULL) + if (NULL != pp->pth) { GSF_peer_transmit_cancel_ (pp->pth); pp->pth = NULL; @@ -473,8 +486,10 @@ schedule_peer_transmission (void *cls, GNUNET_SCHEDULER_add_delayed (delay, &schedule_peer_transmission, pp); return; } +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# query plans executed"), 1, GNUNET_NO); +#endif /* process from priority heap */ rp = GNUNET_CONTAINER_heap_peek (pp->priority_heap); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing query plan %p\n", rp); @@ -512,37 +527,37 @@ struct MergeContext * GNUNET_NO if not (merge success) */ static int -merge_pr (void *cls, const GNUNET_HashCode * query, void *element) +merge_pr (void *cls, const struct GNUNET_HashCode * query, void *element) { struct MergeContext *mpr = cls; struct GSF_RequestPlan *rp = element; struct GSF_PendingRequestData *prd; - struct GSF_RequestPlanReference *rpr; - struct PendingRequestList *prl; + struct GSF_PendingRequestPlanBijection *bi; struct GSF_PendingRequest *latest; if (GNUNET_OK != - GSF_pending_request_is_compatible_ (mpr->pr, rp->prl_head->pr)) + GSF_pending_request_is_compatible_ (mpr->pr, rp->pe_head->pr)) return GNUNET_YES; /* merge new request with existing request plan */ - rpr = GNUNET_malloc (sizeof (struct GSF_RequestPlanReference)); - prl = GNUNET_malloc (sizeof (struct PendingRequestList)); - rpr->rp = rp; - rpr->prl = prl; - prl->rpr = rpr; - prl->pr = mpr->pr; + bi = GNUNET_malloc (sizeof (struct GSF_PendingRequestPlanBijection)); + bi->rp = rp; + bi->pr = mpr->pr; prd = GSF_pending_request_get_data_ (mpr->pr); - GNUNET_CONTAINER_DLL_insert (prd->rpr_head, prd->rpr_tail, rpr); - GNUNET_CONTAINER_DLL_insert (rp->prl_head, rp->prl_tail, prl); + GNUNET_CONTAINER_MDLL_insert (PR, prd->pr_head, prd->pr_tail, bi); + GNUNET_CONTAINER_MDLL_insert (PE, rp->pe_head, rp->pe_tail, bi); mpr->merged = GNUNET_YES; +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# requests merged"), 1, GNUNET_NO); +#endif latest = get_latest (rp); if (GSF_pending_request_get_data_ (latest)->ttl.abs_value < prd->ttl.abs_value) { +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# requests refreshed"), 1, GNUNET_NO); +#endif rp->transmission_counter = 0; /* reset */ } return GNUNET_NO; @@ -558,40 +573,40 @@ merge_pr (void *cls, const GNUNET_HashCode * query, void *element) void GSF_plan_add_ (struct GSF_ConnectedPeer *cp, struct GSF_PendingRequest *pr) { - struct GNUNET_PeerIdentity id; + const struct GNUNET_PeerIdentity *id; struct PeerPlan *pp; struct GSF_PendingRequestData *prd; struct GSF_RequestPlan *rp; - struct GSF_RequestPlanReference *rpr; - struct PendingRequestList *prl; + struct GSF_PendingRequestPlanBijection *bi; struct MergeContext mpc; GNUNET_assert (NULL != cp); - GSF_connected_peer_get_identity_ (cp, &id); - pp = GNUNET_CONTAINER_multihashmap_get (plans, &id.hashPubKey); + id = GSF_connected_peer_get_identity2_ (cp); + pp = GNUNET_CONTAINER_multihashmap_get (plans, &id->hashPubKey); if (NULL == pp) { pp = GNUNET_malloc (sizeof (struct PeerPlan)); - pp->plan_map = GNUNET_CONTAINER_multihashmap_create (128); + pp->plan_map = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO); pp->priority_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MAX); pp->delay_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); pp->cp = cp; - GNUNET_CONTAINER_multihashmap_put (plans, &id.hashPubKey, pp, + GNUNET_CONTAINER_multihashmap_put (plans, + &id->hashPubKey, pp, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); } mpc.merged = GNUNET_NO; mpc.pr = pr; GNUNET_CONTAINER_multihashmap_get_multiple (pp->plan_map, &GSF_pending_request_get_data_ - (pr)->query, &merge_pr, &mpc); - if (mpc.merged != GNUNET_NO) + (pr)->query, &merge_pr, &mpc); // 8 MB in 'merge_pr' + if (GNUNET_NO != mpc.merged) return; GNUNET_CONTAINER_multihashmap_get_multiple (pp->plan_map, &GSF_pending_request_get_data_ (pr)->query, &merge_pr, &mpc); - if (mpc.merged != GNUNET_NO) + if (GNUNET_NO != mpc.merged) return; plan_count++; GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# query plan entries"), 1, @@ -599,22 +614,19 @@ GSF_plan_add_ (struct GSF_ConnectedPeer *cp, struct GSF_PendingRequest *pr) prd = GSF_pending_request_get_data_ (pr); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Planning transmission of query `%s' to peer `%s'\n", - GNUNET_h2s (&prd->query), GNUNET_i2s (&id)); - rp = GNUNET_malloc (sizeof (struct GSF_RequestPlan)); - rpr = GNUNET_malloc (sizeof (struct GSF_RequestPlanReference)); - prl = GNUNET_malloc (sizeof (struct PendingRequestList)); - rpr->rp = rp; - rpr->prl = prl; - prl->rpr = rpr; - prl->pr = pr; - GNUNET_CONTAINER_DLL_insert (prd->rpr_head, prd->rpr_tail, rpr); - GNUNET_CONTAINER_DLL_insert (rp->prl_head, rp->prl_tail, prl); + GNUNET_h2s (&prd->query), GNUNET_i2s (id)); + rp = GNUNET_malloc (sizeof (struct GSF_RequestPlan)); // 8 MB + bi = GNUNET_malloc (sizeof (struct GSF_PendingRequestPlanBijection)); + bi->rp = rp; + bi->pr = pr; + GNUNET_CONTAINER_MDLL_insert (PR, prd->pr_head, prd->pr_tail, bi); + GNUNET_CONTAINER_MDLL_insert (PE, rp->pe_head, rp->pe_tail, bi); rp->pp = pp; GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_put (pp->plan_map, get_rp_key (rp), rp, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); - plan (pp, rp); + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); // 8 MB + plan (pp, rp); // +5 MB (plan/heap-insert) } @@ -627,21 +639,24 @@ GSF_plan_add_ (struct GSF_ConnectedPeer *cp, struct GSF_PendingRequest *pr) void GSF_plan_notify_peer_disconnect_ (const struct GSF_ConnectedPeer *cp) { - struct GNUNET_PeerIdentity id; + const struct GNUNET_PeerIdentity *id; struct PeerPlan *pp; struct GSF_RequestPlan *rp; struct GSF_PendingRequestData *prd; - struct PendingRequestList *prl; + struct GSF_PendingRequestPlanBijection *bi; - GSF_connected_peer_get_identity_ (cp, &id); - pp = GNUNET_CONTAINER_multihashmap_get (plans, &id.hashPubKey); + id = GSF_connected_peer_get_identity2_ (cp); + pp = GNUNET_CONTAINER_multihashmap_get (plans, &id->hashPubKey); if (NULL == pp) return; /* nothing was ever planned for this peer */ GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (plans, &id.hashPubKey, + GNUNET_CONTAINER_multihashmap_remove (plans, &id->hashPubKey, pp)); if (NULL != pp->pth) + { GSF_peer_transmit_cancel_ (pp->pth); + pp->pth = NULL; + } if (GNUNET_SCHEDULER_NO_TASK != pp->task) { GNUNET_SCHEDULER_cancel (pp->task); @@ -652,14 +667,14 @@ GSF_plan_notify_peer_disconnect_ (const struct GSF_ConnectedPeer *cp) GNUNET_break (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (pp->plan_map, get_rp_key (rp), rp)); - while (NULL != (prl = rp->prl_head)) + while (NULL != (bi = rp->pe_head)) { - GNUNET_CONTAINER_DLL_remove (rp->prl_head, rp->prl_tail, prl); - prd = GSF_pending_request_get_data_ (prl->pr); - GNUNET_CONTAINER_DLL_remove (prd->rpr_head, prd->rpr_tail, prl->rpr); - GNUNET_free (prl->rpr); - GNUNET_free (prl); + GNUNET_CONTAINER_MDLL_remove (PE, rp->pe_head, rp->pe_tail, bi); + prd = GSF_pending_request_get_data_ (bi->pr); + GNUNET_CONTAINER_MDLL_remove (PR, prd->pr_head, prd->pr_tail, bi); + GNUNET_free (bi); } + plan_count--; GNUNET_free (rp); } GNUNET_CONTAINER_heap_destroy (pp->priority_heap); @@ -668,50 +683,55 @@ GSF_plan_notify_peer_disconnect_ (const struct GSF_ConnectedPeer *cp) GNUNET_break (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (pp->plan_map, get_rp_key (rp), rp)); - while (NULL != (prl = rp->prl_head)) + while (NULL != (bi = rp->pe_head)) { - GNUNET_CONTAINER_DLL_remove (rp->prl_head, rp->prl_tail, prl); - prd = GSF_pending_request_get_data_ (prl->pr); - GNUNET_CONTAINER_DLL_remove (prd->rpr_head, prd->rpr_tail, prl->rpr); - GNUNET_free (prl->rpr); - GNUNET_free (prl); + prd = GSF_pending_request_get_data_ (bi->pr); + GNUNET_CONTAINER_MDLL_remove (PE, rp->pe_head, rp->pe_tail, bi); + GNUNET_CONTAINER_MDLL_remove (PR, prd->pr_head, prd->pr_tail, bi); + GNUNET_free (bi); } + plan_count--; GNUNET_free (rp); } GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# query plan entries"), plan_count, GNUNET_NO); - GNUNET_CONTAINER_heap_destroy (pp->delay_heap); GNUNET_CONTAINER_multihashmap_destroy (pp->plan_map); GNUNET_free (pp); } + /** * Get the last transmission attempt time for the request plan list - * referenced by 'rpr_head', that was sent to 'sender' + * referenced by 'pr_head', that was sent to 'sender' * - * @param rpr_head request plan reference list to check. + * @param pr_head request plan reference list to check. * @param sender the peer that we've sent the request to. - * @param result the timestamp to fill. + * @param result the timestamp to fill, set to "FOREVER" if never transmitted * @return GNUNET_YES if 'result' was changed, GNUNET_NO otherwise. */ int GSF_request_plan_reference_get_last_transmission_ ( - struct GSF_RequestPlanReference *rpr_head, struct GSF_ConnectedPeer *sender, + struct GSF_PendingRequestPlanBijection *pr_head, struct GSF_ConnectedPeer *sender, struct GNUNET_TIME_Absolute *result) { - struct GSF_RequestPlanReference *rpr; - for (rpr = rpr_head; rpr; rpr = rpr->next) + struct GSF_PendingRequestPlanBijection *bi; + + for (bi = pr_head; NULL != bi; bi = bi->next_PR) { - if (rpr->rp->pp->cp == sender) + if (bi->rp->pp->cp == sender) { - *result = rpr->rp->last_transmission; + if (0 == bi->rp->last_transmission.abs_value) + *result = GNUNET_TIME_UNIT_FOREVER_ABS; + else + *result = bi->rp->last_transmission; return GNUNET_YES; } } return GNUNET_NO; } + /** * Notify the plan about a request being done; destroy all entries * associated with this request. @@ -723,27 +743,26 @@ GSF_plan_notify_request_done_ (struct GSF_PendingRequest *pr) { struct GSF_RequestPlan *rp; struct GSF_PendingRequestData *prd; - struct GSF_RequestPlanReference *rpr; + struct GSF_PendingRequestPlanBijection *bi; prd = GSF_pending_request_get_data_ (pr); - while (NULL != (rpr = prd->rpr_head)) + while (NULL != (bi = prd->pr_head)) { - GNUNET_CONTAINER_DLL_remove (prd->rpr_head, prd->rpr_tail, rpr); - rp = rpr->rp; - GNUNET_CONTAINER_DLL_remove (rp->prl_head, rp->prl_tail, rpr->prl); - if (NULL == rp->prl_head) + rp = bi->rp; + GNUNET_CONTAINER_MDLL_remove (PR, prd->pr_head, prd->pr_tail, bi); + GNUNET_CONTAINER_MDLL_remove (PE, rp->pe_head, rp->pe_tail, bi); + if (NULL == rp->pe_head) { GNUNET_CONTAINER_heap_remove_node (rp->hn); plan_count--; GNUNET_break (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (rp->pp->plan_map, - &GSF_pending_request_get_data_ - (rpr->prl->pr)->query, + &GSF_pending_request_get_data_ + (bi->pr)->query, rp)); GNUNET_free (rp); } - GNUNET_free (rpr->prl); - GNUNET_free (rpr); + GNUNET_free (bi); } GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# query plan entries"), plan_count, GNUNET_NO); @@ -756,7 +775,7 @@ GSF_plan_notify_request_done_ (struct GSF_PendingRequest *pr) void GSF_plan_init () { - plans = GNUNET_CONTAINER_multihashmap_create (256); + plans = GNUNET_CONTAINER_multihashmap_create (256, GNUNET_YES); } diff --git a/src/fs/gnunet-service-fs_pe.h b/src/fs/gnunet-service-fs_pe.h index 3a18715..d136267 100644 --- a/src/fs/gnunet-service-fs_pe.h +++ b/src/fs/gnunet-service-fs_pe.h @@ -62,15 +62,15 @@ GSF_plan_notify_request_done_ (struct GSF_PendingRequest *pr); * Get the last transmission attempt time for the request plan list * referenced by 'rpr_head', that was sent to 'sender' * - * @param rpr_head request plan reference list to check. + * @param pr_head request plan reference list to check. * @param sender the peer that we've sent the request to. * @param result the timestamp to fill. * @return GNUNET_YES if 'result' was changed, GNUNET_NO otherwise. */ int -GSF_request_plan_reference_get_last_transmission_ ( - struct GSF_RequestPlanReference *rpr_head, struct GSF_ConnectedPeer *sender, - struct GNUNET_TIME_Absolute *result); +GSF_request_plan_reference_get_last_transmission_ (struct GSF_PendingRequestPlanBijection *pr_head, + struct GSF_ConnectedPeer *sender, + struct GNUNET_TIME_Absolute *result); /** * Initialize plan subsystem. diff --git a/src/fs/gnunet-service-fs_pr.c b/src/fs/gnunet-service-fs_pr.c index 8ca4121..76e04f5 100644 --- a/src/fs/gnunet-service-fs_pr.c +++ b/src/fs/gnunet-service-fs_pr.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2010, 2011 Christian Grothoff (and other contributing authors) + (C) 2009, 2010, 2011, 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 @@ -30,6 +30,13 @@ #include "gnunet-service-fs_indexing.h" #include "gnunet-service-fs_pe.h" #include "gnunet-service-fs_pr.h" +#include "gnunet-service-fs_stream.h" + + +/** + * Desired replication level for GETs. + */ +#define DHT_GET_REPLICATION 5 /** * Maximum size of the datastore queue for P2P operations. Needs to @@ -52,6 +59,18 @@ #define MAX_RESULTS (100 * 1024) /** + * Collect an instane number of statistics? May cause excessive IPC. + */ +#define INSANE_STATISTICS GNUNET_NO + +/** + * If obtaining a block via stream fails, how often do we retry it before + * giving up for good (and sticking to non-anonymous transfer)? + */ +#define STREAM_RETRY_MAX 3 + + +/** * An active request. */ struct GSF_PendingRequest @@ -74,7 +93,7 @@ struct GSF_PendingRequest /** * Array of hash codes of replies we've already seen. */ - GNUNET_HashCode *replies_seen; + struct GNUNET_HashCode *replies_seen; /** * Bloomfilter masking replies we've already seen. @@ -97,6 +116,11 @@ struct GSF_PendingRequest struct GNUNET_DHT_GetHandle *gh; /** + * Stream request handle for this request (or NULL for none). + */ + struct GSF_StreamRequest *stream_request; + + /** * Function to call upon completion of the local get * request, or NULL for none. */ @@ -149,6 +173,12 @@ struct GSF_PendingRequest uint64_t first_uid; /** + * How often have we retried this request via 'stream'? + * (used to bound overall retries). + */ + unsigned int stream_retry_count; + + /** * Number of valid entries in the 'replies_seen' array. */ unsigned int replies_seen_count; @@ -191,12 +221,6 @@ static int active_to_migration; /** - * Size of the datastore queue we assume for common requests. - * Determined based on the network quota. - */ -static unsigned int datastore_queue_size; - -/** * Heap with the request that will expire next at the top. Contains * pointers of type "struct PendingRequest*"; these will *also* be * aliased from the "requests_by_peer" data structures and the @@ -263,40 +287,52 @@ refresh_bloomfilter (struct GSF_PendingRequest *pr) struct GSF_PendingRequest * GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, enum GNUNET_BLOCK_Type type, - const GNUNET_HashCode * query, - const GNUNET_HashCode * namespace, + const struct GNUNET_HashCode *query, + const struct GNUNET_HashCode *namespace, const struct GNUNET_PeerIdentity *target, const char *bf_data, size_t bf_size, uint32_t mingle, uint32_t anonymity_level, uint32_t priority, int32_t ttl, GNUNET_PEER_Id sender_pid, GNUNET_PEER_Id origin_pid, - const GNUNET_HashCode * replies_seen, + const struct GNUNET_HashCode *replies_seen, unsigned int replies_seen_count, GSF_PendingRequestReplyHandler rh, void *rh_cls) { struct GSF_PendingRequest *pr; struct GSF_PendingRequest *dpr; + size_t extra; + struct GNUNET_HashCode *eptr; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating request handle for `%s' of type %d\n", GNUNET_h2s (query), type); +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# Pending requests created"), 1, GNUNET_NO); - pr = GNUNET_malloc (sizeof (struct GSF_PendingRequest)); +#endif + extra = 0; + if (GNUNET_BLOCK_TYPE_FS_SBLOCK == type) + extra += sizeof (struct GNUNET_HashCode); + if (NULL != target) + extra += sizeof (struct GNUNET_PeerIdentity); + pr = GNUNET_malloc (sizeof (struct GSF_PendingRequest) + extra); pr->local_result_offset = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); pr->public_data.query = *query; + eptr = (struct GNUNET_HashCode *) &pr[1]; if (GNUNET_BLOCK_TYPE_FS_SBLOCK == type) { - GNUNET_assert (NULL != namespace); - pr->public_data.namespace = *namespace; + GNUNET_assert (NULL != namespace); + pr->public_data.namespace = eptr; + memcpy (eptr, namespace, sizeof (struct GNUNET_HashCode)); + eptr++; } if (NULL != target) { - pr->public_data.target = *target; - pr->public_data.has_target = GNUNET_YES; + pr->public_data.target = (struct GNUNET_PeerIdentity *) eptr; + memcpy (eptr, target, sizeof (struct GNUNET_PeerIdentity)); } pr->public_data.anonymity_level = anonymity_level; pr->public_data.priority = priority; @@ -324,9 +360,9 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, { pr->replies_seen_size = replies_seen_count; pr->replies_seen = - GNUNET_malloc (sizeof (GNUNET_HashCode) * pr->replies_seen_size); + GNUNET_malloc (sizeof (struct GNUNET_HashCode) * pr->replies_seen_size); memcpy (pr->replies_seen, replies_seen, - replies_seen_count * sizeof (GNUNET_HashCode)); + replies_seen_count * sizeof (struct GNUNET_HashCode)); pr->replies_seen_count = replies_seen_count; } if (NULL != bf_data) @@ -341,7 +377,8 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, { refresh_bloomfilter (pr); } - GNUNET_CONTAINER_multihashmap_put (pr_map, query, pr, + GNUNET_CONTAINER_multihashmap_put (pr_map, + &pr->public_data.query, pr, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); if (0 == (options & GSF_PRO_REQUEST_NEVER_EXPIRES)) { @@ -398,11 +435,12 @@ GSF_pending_request_is_compatible_ (struct GSF_PendingRequest *pra, if ((pra->public_data.type != prb->public_data.type) || (0 != memcmp (&pra->public_data.query, &prb->public_data.query, - sizeof (GNUNET_HashCode))) || + sizeof (struct GNUNET_HashCode))) || ((pra->public_data.type == GNUNET_BLOCK_TYPE_FS_SBLOCK) && (0 != - memcmp (&pra->public_data.namespace, &prb->public_data.namespace, - sizeof (GNUNET_HashCode))))) + memcmp (pra->public_data.namespace, + prb->public_data.namespace, + sizeof (struct GNUNET_HashCode))))) return GNUNET_NO; return GNUNET_OK; } @@ -419,11 +457,11 @@ GSF_pending_request_is_compatible_ (struct GSF_PendingRequest *pra, */ void GSF_pending_request_update_ (struct GSF_PendingRequest *pr, - const GNUNET_HashCode * replies_seen, + const struct GNUNET_HashCode * replies_seen, unsigned int replies_seen_count) { unsigned int i; - GNUNET_HashCode mhash; + struct GNUNET_HashCode mhash; if (replies_seen_count + pr->replies_seen_count < pr->replies_seen_count) return; /* integer overflow */ @@ -434,7 +472,7 @@ GSF_pending_request_update_ (struct GSF_PendingRequest *pr, GNUNET_array_grow (pr->replies_seen, pr->replies_seen_size, replies_seen_count + pr->replies_seen_count); memcpy (&pr->replies_seen[pr->replies_seen_count], replies_seen, - sizeof (GNUNET_HashCode) * replies_seen_count); + sizeof (struct GNUNET_HashCode) * replies_seen_count); pr->replies_seen_count += replies_seen_count; refresh_bloomfilter (pr); } @@ -459,6 +497,10 @@ GSF_pending_request_update_ (struct GSF_PendingRequest *pr, } } } + if (NULL != pr->gh) + GNUNET_DHT_get_filter_known_results (pr->gh, + replies_seen_count, + replies_seen); } @@ -477,7 +519,7 @@ GSF_pending_request_get_message_ (struct GSF_PendingRequest *pr, { char lbuf[GNUNET_SERVER_MAX_MESSAGE_SIZE]; struct GetMessage *gm; - GNUNET_HashCode *ext; + struct GNUNET_HashCode *ext; size_t msize; unsigned int k; uint32_t bm; @@ -509,13 +551,13 @@ GSF_pending_request_get_message_ (struct GSF_PendingRequest *pr, bm |= GET_MESSAGE_BIT_SKS_NAMESPACE; k++; } - if (GNUNET_YES == pr->public_data.has_target) + if (NULL != pr->public_data.target) { bm |= GET_MESSAGE_BIT_TRANSMIT_TO; k++; } bf_size = GNUNET_CONTAINER_bloomfilter_get_size (pr->bf); - msize = sizeof (struct GetMessage) + bf_size + k * sizeof (GNUNET_HashCode); + msize = sizeof (struct GetMessage) + bf_size + k * sizeof (struct GNUNET_HashCode); GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); if (buf_size < msize) return msize; @@ -530,6 +572,8 @@ GSF_pending_request_get_message_ (struct GSF_PendingRequest *pr, else prio = 0; pr->public_data.priority -= prio; + pr->public_data.num_transmissions++; + pr->public_data.respect_offered += prio; gm->priority = htonl (prio); now = GNUNET_TIME_absolute_get (); ttl = (int64_t) (pr->public_data.ttl.abs_value - now.abs_value); @@ -537,15 +581,17 @@ GSF_pending_request_get_message_ (struct GSF_PendingRequest *pr, gm->filter_mutator = htonl (pr->mingle); gm->hash_bitmap = htonl (bm); gm->query = pr->public_data.query; - ext = (GNUNET_HashCode *) & gm[1]; + ext = (struct GNUNET_HashCode *) & gm[1]; k = 0; if (!do_route) GNUNET_PEER_resolve (pr->sender_pid, (struct GNUNET_PeerIdentity *) &ext[k++]); if (GNUNET_BLOCK_TYPE_FS_SBLOCK == pr->public_data.type) - memcpy (&ext[k++], &pr->public_data.namespace, sizeof (GNUNET_HashCode)); - if (GNUNET_YES == pr->public_data.has_target) - ext[k++] = pr->public_data.target.hashPubKey; + memcpy (&ext[k++], pr->public_data.namespace, sizeof (struct GNUNET_HashCode)); + if (NULL != pr->public_data.target) + memcpy (&ext[k++], + pr->public_data.target, + sizeof (struct GNUNET_PeerIdentity)); if (pr->bf != NULL) GNUNET_assert (GNUNET_SYSERR != GNUNET_CONTAINER_bloomfilter_get_raw_data (pr->bf, @@ -565,7 +611,7 @@ GSF_pending_request_get_message_ (struct GSF_PendingRequest *pr, * @return GNUNET_YES (we should continue to iterate) */ static int -clean_request (void *cls, const GNUNET_HashCode * key, void *value) +clean_request (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GSF_PendingRequest *pr = value; GSF_LocalLookupContinuation cont; @@ -603,6 +649,11 @@ clean_request (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_DHT_get_stop (pr->gh); pr->gh = NULL; } + if (NULL != pr->stream_request) + { + GSF_stream_query_cancel (pr->stream_request); + pr->stream_request = NULL; + } if (GNUNET_SCHEDULER_NO_TASK != pr->warn_task) { GNUNET_SCHEDULER_cancel (pr->warn_task); @@ -655,6 +706,11 @@ GSF_pending_request_cancel_ (struct GSF_PendingRequest *pr, int full_cleanup) GNUNET_DHT_get_stop (pr->gh); pr->gh = NULL; } + if (NULL != pr->stream_request) + { + GSF_stream_query_cancel (pr->stream_request); + pr->stream_request = NULL; + } if (GNUNET_SCHEDULER_NO_TASK != pr->warn_task) { GNUNET_SCHEDULER_cancel (pr->warn_task); @@ -763,11 +819,11 @@ update_request_performance_data (struct ProcessReplyClosure *prq, * @return GNUNET_YES (we should continue to iterate) */ static int -process_reply (void *cls, const GNUNET_HashCode * key, void *value) +process_reply (void *cls, const struct GNUNET_HashCode * key, void *value) { struct ProcessReplyClosure *prq = cls; struct GSF_PendingRequest *pr = value; - GNUNET_HashCode chash; + struct GNUNET_HashCode chash; struct GNUNET_TIME_Absolute last_transmission; if (NULL == pr->rh) @@ -780,10 +836,10 @@ process_reply (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_NO); prq->eval = GNUNET_BLOCK_evaluate (GSF_block_ctx, prq->type, key, &pr->bf, pr->mingle, - &pr->public_data.namespace, + pr->public_data.namespace, (prq->type == GNUNET_BLOCK_TYPE_FS_SBLOCK) ? - sizeof (GNUNET_HashCode) : 0, prq->data, + sizeof (struct GNUNET_HashCode) : 0, prq->data, prq->size); switch (prq->eval) { @@ -796,20 +852,33 @@ process_reply (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_LOAD_update (GSF_rt_entry_lifetime, GNUNET_TIME_absolute_get_duration (pr-> public_data.start_time).rel_value); - if (!GSF_request_plan_reference_get_last_transmission_ (pr->public_data.rpr_head, prq->sender, &last_transmission)) + if (GNUNET_YES != + GSF_request_plan_reference_get_last_transmission_ (pr->public_data.pr_head, + prq->sender, + &last_transmission)) last_transmission.abs_value = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value; /* pass on to other peers / local clients */ pr->rh (pr->rh_cls, prq->eval, pr, prq->anonymity_level, prq->expiration, last_transmission, prq->type, prq->data, prq->size); return GNUNET_YES; case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# duplicate replies discarded (bloomfilter)"), 1, GNUNET_NO); +#endif GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Duplicate response, discarding.\n"); return GNUNET_YES; /* duplicate */ + case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: + GNUNET_STATISTICS_update (GSF_stats, + gettext_noop + ("# irrelevant replies discarded"), + 1, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Irrelevant response, ignoring.\n"); + return GNUNET_YES; case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: return GNUNET_YES; /* wrong namespace */ case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: @@ -845,9 +914,12 @@ process_reply (void *cls, const GNUNET_HashCode * key, void *value) pr->public_data.results_found++; prq->request_found = GNUNET_YES; /* finally, pass on to other peer / local client */ - if (!GSF_request_plan_reference_get_last_transmission_ (pr->public_data.rpr_head, prq->sender, &last_transmission)) + if (! GSF_request_plan_reference_get_last_transmission_ (pr->public_data.pr_head, + prq->sender, + &last_transmission)) last_transmission.abs_value = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value; - pr->rh (pr->rh_cls, prq->eval, pr, prq->anonymity_level, prq->expiration, + pr->rh (pr->rh_cls, prq->eval, pr, + prq->anonymity_level, prq->expiration, last_transmission, prq->type, prq->data, prq->size); return GNUNET_YES; } @@ -929,8 +1001,8 @@ put_migration_continuation (void *cls, int success, if (min_expiration.abs_value > 0) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Asking to stop migration for %llu ms because datastore is full\n", - (unsigned long long) GNUNET_TIME_absolute_get_remaining (min_expiration).rel_value); + "Asking to stop migration for %s because datastore is full\n", + GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (min_expiration), GNUNET_YES)); GSF_block_peer_migration_ (cp, min_expiration); } else @@ -943,8 +1015,8 @@ put_migration_continuation (void *cls, int success, ppd->migration_delay.rel_value); ppd->migration_delay = GNUNET_TIME_relative_multiply (ppd->migration_delay, 2); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Replicated content already exists locally, asking to stop migration for %llu ms\n", - (unsigned long long) mig_pause.rel_value); + "Replicated content already exists locally, asking to stop migration for %s\n", + GNUNET_STRINGS_relative_time_to_string (mig_pause, GNUNET_YES)); GSF_block_peer_migration_ (cp, GNUNET_TIME_relative_to_absolute (mig_pause)); } } @@ -1000,7 +1072,7 @@ test_put_load_too_high (uint32_t priority) */ static void handle_dht_reply (void *cls, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, const struct GNUNET_PeerIdentity *get_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *put_path, @@ -1057,7 +1129,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] GNUNET_ALIGN; + char buf[sizeof (struct GNUNET_HashCode) * 2] GNUNET_ALIGN; if (0 != pr->public_data.anonymity_level) return; @@ -1071,8 +1143,8 @@ GSF_dht_lookup_ (struct GSF_PendingRequest *pr) if (GNUNET_BLOCK_TYPE_FS_SBLOCK == pr->public_data.type) { xquery = buf; - memcpy (buf, &pr->public_data.namespace, sizeof (GNUNET_HashCode)); - xquery_size = sizeof (GNUNET_HashCode); + memcpy (buf, pr->public_data.namespace, sizeof (struct GNUNET_HashCode)); + xquery_size = sizeof (struct GNUNET_HashCode); } if (0 != (pr->public_data.options & GSF_PRO_FORWARD_ONLY)) { @@ -1084,10 +1156,105 @@ GSF_dht_lookup_ (struct GSF_PendingRequest *pr) pr->gh = GNUNET_DHT_get_start (GSF_dht, pr->public_data.type, &pr->public_data.query, - 5 /* DEFAULT_GET_REPLICATION */ , + DHT_GET_REPLICATION, GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, - /* FIXME: can no longer pass pr->bf/pr->mingle... */ xquery, xquery_size, &handle_dht_reply, pr); + if ( (NULL != pr->gh) && + (0 != pr->replies_seen_count) ) + GNUNET_DHT_get_filter_known_results (pr->gh, + pr->replies_seen_count, + pr->replies_seen); +} + + +/** + * Function called with a reply from the stream. + * + * @param cls the pending request struct + * @param type type of the block, ANY on error + * @param expiration expiration time for the block + * @param data_size number of bytes in 'data', 0 on error + * @param data reply block data, NULL on error + */ +static void +stream_reply_proc (void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_TIME_Absolute expiration, + size_t data_size, + const void *data) +{ + struct GSF_PendingRequest *pr = cls; + struct ProcessReplyClosure prq; + struct GNUNET_HashCode query; + + pr->stream_request = NULL; + if (GNUNET_BLOCK_TYPE_ANY == type) + { + GNUNET_break (NULL == data); + GNUNET_break (0 == data_size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Error retrieiving block via stream\n"); + pr->stream_retry_count++; + if (pr->stream_retry_count >= STREAM_RETRY_MAX) + return; /* give up on stream */ + /* retry -- without delay, as this is non-anonymous + and mesh/stream connect will take some time anyway */ + pr->stream_request = GSF_stream_query (pr->public_data.target, + &pr->public_data.query, + pr->public_data.type, + &stream_reply_proc, + pr); + return; + } + if (GNUNET_YES != + GNUNET_BLOCK_get_key (GSF_block_ctx, + type, + data, data_size, &query)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Failed to derive key for block of type %d\n", + (int) type); + GNUNET_break_op (0); + return; + } + GNUNET_STATISTICS_update (GSF_stats, + gettext_noop ("# Replies received from STREAM"), 1, + GNUNET_NO); + memset (&prq, 0, sizeof (prq)); + prq.data = data; + prq.expiration = expiration; + /* do not allow migrated content to live longer than 1 year */ + prq.expiration = GNUNET_TIME_absolute_min (GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_YEARS), + prq.expiration); + prq.size = data_size; + prq.type = type; + process_reply (&prq, &query, pr); +} + + +/** + * Consider downloading via stream (if possible) + * + * @param pr the pending request to process + */ +void +GSF_stream_lookup_ (struct GSF_PendingRequest *pr) +{ + if (0 != pr->public_data.anonymity_level) + return; + if (0 == pr->public_data.target) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Cannot do stream-based download, target peer not known\n"); + return; + } + if (NULL != pr->stream_request) + return; + pr->stream_request = GSF_stream_query (pr->public_data.target, + &pr->public_data.query, + pr->public_data.type, + &stream_reply_proc, + pr); } @@ -1103,9 +1270,8 @@ warn_delay_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GSF_PendingRequest *pr = cls; GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Datastore lookup already took %llu ms!\n"), - (unsigned long long) - GNUNET_TIME_absolute_get_duration (pr->qe_start).rel_value); + _("Datastore lookup already took %s!\n"), + GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (pr->qe_start), GNUNET_YES)); pr->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &warn_delay_task, pr); @@ -1124,9 +1290,8 @@ odc_warn_delay_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GSF_PendingRequest *pr = cls; GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("On-demand lookup already took %llu ms!\n"), - (unsigned long long) - GNUNET_TIME_absolute_get_duration (pr->qe_start).rel_value); + _("On-demand lookup already took %s!\n"), + GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (pr->qe_start), GNUNET_YES)); pr->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &odc_warn_delay_task, pr); @@ -1151,7 +1316,7 @@ odc_warn_delay_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * maybe 0 if no unique identifier is available */ static void -process_local_reply (void *cls, const GNUNET_HashCode * key, size_t size, +process_local_reply (void *cls, const struct GNUNET_HashCode * key, size_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, uint64_t uid) @@ -1159,7 +1324,7 @@ process_local_reply (void *cls, const GNUNET_HashCode * key, size_t size, struct GSF_PendingRequest *pr = cls; GSF_LocalLookupContinuation cont; struct ProcessReplyClosure prq; - GNUNET_HashCode query; + struct GNUNET_HashCode query; unsigned int old_rf; GNUNET_SCHEDULER_cancel (pr->warn_task); @@ -1169,10 +1334,12 @@ process_local_reply (void *cls, const GNUNET_HashCode * key, size_t size, pr->qe = NULL; if (NULL == key) { +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# Datastore lookups concluded (no results)"), 1, GNUNET_NO); +#endif } if (GNUNET_NO == pr->have_first_uid) { @@ -1204,12 +1371,14 @@ process_local_reply (void *cls, const GNUNET_HashCode * key, size_t size, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, "No further local responses available.\n"); +#if INSANE_STATISTICS if ((pr->public_data.type == GNUNET_BLOCK_TYPE_FS_DBLOCK) || (pr->public_data.type == GNUNET_BLOCK_TYPE_FS_IBLOCK)) GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# requested DBLOCK or IBLOCK not found"), 1, GNUNET_NO); +#endif goto check_error_and_continue; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1258,7 +1427,7 @@ process_local_reply (void *cls, const GNUNET_HashCode * key, size_t size, (0 != (GSF_PRO_PRIORITY_UNLIMITED & pr->public_data.options)) ? UINT_MAX : - datastore_queue_size + GSF_datastore_queue_size /* max queue size */ , GNUNET_TIME_UNIT_FOREVER_REL, &process_local_reply, pr); @@ -1298,7 +1467,7 @@ process_local_reply (void *cls, const GNUNET_HashCode * key, size_t size, (0 != (GSF_PRO_PRIORITY_UNLIMITED & pr->public_data.options)) ? UINT_MAX : - datastore_queue_size + GSF_datastore_queue_size /* max queue size */ , GNUNET_TIME_UNIT_FOREVER_REL, &process_local_reply, pr); @@ -1356,7 +1525,7 @@ process_local_reply (void *cls, const GNUNET_HashCode * key, size_t size, (0 != (GSF_PRO_PRIORITY_UNLIMITED & pr-> public_data.options)) ? UINT_MAX : - datastore_queue_size + GSF_datastore_queue_size /* max queue size */ , GNUNET_TIME_UNIT_FOREVER_REL, &process_local_reply, pr); @@ -1413,6 +1582,7 @@ GSF_local_lookup_ (struct GSF_PendingRequest *pr, GSF_LocalLookupContinuation cont, void *cont_cls) { GNUNET_assert (NULL == pr->gh); + GNUNET_assert (NULL == pr->stream_request); GNUNET_assert (NULL == pr->llc_cont); pr->llc_cont = cont; pr->llc_cont_cls = cont_cls; @@ -1420,9 +1590,11 @@ GSF_local_lookup_ (struct GSF_PendingRequest *pr, pr->warn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &warn_delay_task, pr); +#if INSANE_STATISTICS GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# Datastore lookups initiated"), 1, GNUNET_NO); +#endif pr->qe = GNUNET_DATASTORE_get_key (GSF_dsh, pr->local_result_offset++, &pr->public_data.query, @@ -1436,7 +1608,7 @@ GSF_local_lookup_ (struct GSF_PendingRequest *pr, (0 != (GSF_PRO_PRIORITY_UNLIMITED & pr-> public_data.options)) ? UINT_MAX : - datastore_queue_size + GSF_datastore_queue_size /* max queue size */ , GNUNET_TIME_UNIT_FOREVER_REL, &process_local_reply, pr); @@ -1477,7 +1649,7 @@ GSF_handle_p2p_content_ (struct GSF_ConnectedPeer *cp, size_t dsize; enum GNUNET_BLOCK_Type type; struct GNUNET_TIME_Absolute expiration; - GNUNET_HashCode query; + struct GNUNET_HashCode query; struct ProcessReplyClosure prq; struct GNUNET_TIME_Relative block_time; double putl; @@ -1509,10 +1681,7 @@ GSF_handle_p2p_content_ (struct GSF_ConnectedPeer *cp, GNUNET_NO); /* now, lookup 'query' */ prq.data = (const void *) &put[1]; - if (NULL != cp) - prq.sender = cp; - else - prq.sender = NULL; + prq.sender = cp; prq.size = dsize; prq.type = type; prq.expiration = expiration; @@ -1526,9 +1695,10 @@ GSF_handle_p2p_content_ (struct GSF_ConnectedPeer *cp, GSF_connected_peer_change_preference_ (cp, CONTENT_BANDWIDTH_VALUE + 1000 * prq.priority); - GSF_get_peer_performance_data_ (cp)->trust += prq.priority; + GSF_get_peer_performance_data_ (cp)->respect += prq.priority; } if ((GNUNET_YES == active_to_migration) && + (NULL != cp) && (GNUNET_NO == test_put_load_too_high (prq.priority))) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1551,7 +1721,7 @@ GSF_handle_p2p_content_ (struct GSF_ConnectedPeer *cp, put_migration_continuation (pmc, GNUNET_SYSERR, GNUNET_TIME_UNIT_ZERO_ABS, NULL); } } - else + else if (NULL != cp) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Choosing not to keep content `%s' (%d/%d)\n", @@ -1559,9 +1729,10 @@ GSF_handle_p2p_content_ (struct GSF_ConnectedPeer *cp, test_put_load_too_high (prq.priority)); } putl = GNUNET_LOAD_get_load (datastore_put_load); - if ((NULL != (cp = prq.sender)) && (GNUNET_NO == prq.request_found) && - ((GNUNET_YES != active_to_migration) || - (putl > 2.5 * (1 + prq.priority)))) + if ( (NULL != cp) && + (GNUNET_NO == prq.request_found) && + ( (GNUNET_YES != active_to_migration) || + (putl > 2.5 * (1 + prq.priority)) ) ) { if (GNUNET_YES != active_to_migration) putl = 1.0 + GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 5); @@ -1589,37 +1760,18 @@ GSF_handle_p2p_content_ (struct GSF_ConnectedPeer *cp, void GSF_pending_request_init_ () { - unsigned long long bps; - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (GSF_cfg, "fs", "MAX_PENDING_REQUESTS", &max_pending_requests)) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _ - ("Configuration fails to specify `%s', assuming default value."), - "MAX_PENDING_REQUESTS"); + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_INFO, + "fs", "MAX_PENDING_REQUESTS"); } - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_size (GSF_cfg, "ats", "WAN_QUOTA_OUT", - &bps)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _ - ("Configuration fails to specify `%s', assuming default value."), - "WAN_QUOTA_OUT"); - bps = 65536; - } - /* queue size should be #queries we can have pending and satisfy within - * a carry interval: */ - datastore_queue_size = - bps * GNUNET_CONSTANTS_MAX_BANDWIDTH_CARRY_S / DBLOCK_SIZE; - active_to_migration = GNUNET_CONFIGURATION_get_value_yesno (GSF_cfg, "FS", "CONTENT_CACHING"); datastore_put_load = GNUNET_LOAD_value_init (DATASTORE_LOAD_AUTODECLINE); - pr_map = GNUNET_CONTAINER_multihashmap_create (32 * 1024); + pr_map = GNUNET_CONTAINER_multihashmap_create (32 * 1024, GNUNET_YES); requests_by_expiration_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); } diff --git a/src/fs/gnunet-service-fs_pr.h b/src/fs/gnunet-service-fs_pr.h index 92827f7..371aa66 100644 --- a/src/fs/gnunet-service-fs_pr.h +++ b/src/fs/gnunet-service-fs_pr.h @@ -84,28 +84,29 @@ struct GSF_PendingRequestData /** * Primary query hash for this request. */ - GNUNET_HashCode query; + struct GNUNET_HashCode query; /** * Namespace to query, only set if the type is SBLOCK. + * Allocated after struct only if needed. Do not free! */ - GNUNET_HashCode namespace; + const struct GNUNET_HashCode *namespace; /** - * Identity of a peer hosting the content, only set if - * 'has_target' is GNUNET_YES. + * Identity of a peer hosting the content, otherwise NULl. + * Allocated after struct only if needed. Do not free! */ - struct GNUNET_PeerIdentity target; + const struct GNUNET_PeerIdentity *target; /** * Fields for the plan module to track a DLL with the request. */ - struct GSF_RequestPlanReference *rpr_head; + struct GSF_PendingRequestPlanBijection *pr_head; /** * Fields for the plan module to track a DLL with the request. */ - struct GSF_RequestPlanReference *rpr_tail; + struct GSF_PendingRequestPlanBijection *pr_tail; /** * Current TTL for the request. @@ -133,6 +134,22 @@ struct GSF_PendingRequestData uint32_t original_priority; /** + * Counter for how often this request has been transmitted (estimate, + * because we might have the same request pending for multiple clients, + * and of course because a transmission may have failed at a lower + * layer). + */ + uint32_t num_transmissions; + + /** + * How much respect did we (in total) offer for this request so far (estimate, + * because we might have the same request pending for multiple clients, + * and of course because a transmission may have failed at a lower + * layer). + */ + uint32_t respect_offered; + + /** * Options for the request. */ enum GSF_PendingRequestOptions options; @@ -148,11 +165,6 @@ struct GSF_PendingRequestData unsigned int results_found; /** - * Is the 'target' value set to a valid peer identity? - */ - int has_target; - - /** * Has this request been started yet (local/p2p operations)? Or are * we still constructing it? */ @@ -220,15 +232,15 @@ typedef void (*GSF_PendingRequestReplyHandler) (void *cls, struct GSF_PendingRequest * GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, enum GNUNET_BLOCK_Type type, - const GNUNET_HashCode * query, - const GNUNET_HashCode * namespace, + const struct GNUNET_HashCode * query, + const struct GNUNET_HashCode * namespace, const struct GNUNET_PeerIdentity *target, const char *bf_data, size_t bf_size, uint32_t mingle, uint32_t anonymity_level, uint32_t priority, int32_t ttl, GNUNET_PEER_Id sender_pid, GNUNET_PEER_Id origin_pid, - const GNUNET_HashCode * replies_seen, + const struct GNUNET_HashCode * replies_seen, unsigned int replies_seen_count, GSF_PendingRequestReplyHandler rh, void *rh_cls); @@ -243,7 +255,7 @@ GSF_pending_request_create_ (enum GSF_PendingRequestOptions options, */ void GSF_pending_request_update_ (struct GSF_PendingRequest *pr, - const GNUNET_HashCode * replies_seen, + const struct GNUNET_HashCode * replies_seen, unsigned int replies_seen_count); @@ -305,7 +317,7 @@ GSF_pending_request_cancel_ (struct GSF_PendingRequest *pr, int full_cleanup); * @return GNUNET_YES to continue to iterate */ typedef int (*GSF_PendingRequestIterator) (void *cls, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, struct GSF_PendingRequest * pr); @@ -347,6 +359,15 @@ GSF_dht_lookup_ (struct GSF_PendingRequest *pr); /** + * Consider downloading via stream (if possible) + * + * @param pr the pending request to process + */ +void +GSF_stream_lookup_ (struct GSF_PendingRequest *pr); + + +/** * Function to be called after we're done processing * replies from the local lookup. * diff --git a/src/fs/gnunet-service-fs_push.c b/src/fs/gnunet-service-fs_push.c index 22a76f3..936cf51 100644 --- a/src/fs/gnunet-service-fs_push.c +++ b/src/fs/gnunet-service-fs_push.c @@ -71,7 +71,7 @@ struct MigrationReadyBlock /** * Query for the block. */ - GNUNET_HashCode query; + struct GNUNET_HashCode query; /** * When does this block expire? @@ -467,7 +467,7 @@ consider_gathering () * maybe 0 if no unique identifier is available */ static void -process_migration_content (void *cls, const GNUNET_HashCode * key, size_t size, +process_migration_content (void *cls, const struct GNUNET_HashCode * key, size_t size, const void *data, enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, uint64_t uid) @@ -624,10 +624,9 @@ GSF_push_init_ () GNUNET_CONFIGURATION_get_value_time (GSF_cfg, "fs", "MIN_MIGRATION_DELAY", &min_migration_delay)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value specified for option `%s' in section `%s', content pushing disabled\n"), - "MIN_MIGRATION_DELAY", "fs"); + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING, + "fs", "MIN_MIGRATION_DELAY", + _("time required, content pushing disabled")); return; } consider_gathering (); diff --git a/src/fs/gnunet-service-fs_put.c b/src/fs/gnunet-service-fs_put.c index 463acc0..49962d3 100644 --- a/src/fs/gnunet-service-fs_put.c +++ b/src/fs/gnunet-service-fs_put.c @@ -180,8 +180,11 @@ delay_dht_put_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * maybe 0 if no unique identifier is available */ static void -process_dht_put_content (void *cls, const GNUNET_HashCode * key, size_t size, - const void *data, enum GNUNET_BLOCK_Type type, +process_dht_put_content (void *cls, + const struct GNUNET_HashCode * key, + size_t size, + const void *data, + enum GNUNET_BLOCK_Type type, uint32_t priority, uint32_t anonymity, struct GNUNET_TIME_Absolute expiration, uint64_t uid) { diff --git a/src/fs/gnunet-service-fs_stream.c b/src/fs/gnunet-service-fs_stream.c new file mode 100644 index 0000000..3838b1c --- /dev/null +++ b/src/fs/gnunet-service-fs_stream.c @@ -0,0 +1,1466 @@ +/* + 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/gnunet-service-fs_stream.c + * @brief non-anonymous file-transfer + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_constants.h" +#include "gnunet_util_lib.h" +#include "gnunet_stream_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_applications.h" +#include "gnunet-service-fs.h" +#include "gnunet-service-fs_indexing.h" +#include "gnunet-service-fs_stream.h" + +/** + * After how long do we termiante idle connections? + */ +#define IDLE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) + +/** + * After how long do we reset connections without replies? + */ +#define CLIENT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) + + +/** + * A message in the queue to be written to the stream. + */ +struct WriteQueueItem +{ + /** + * Kept in a DLL. + */ + struct WriteQueueItem *next; + + /** + * Kept in a DLL. + */ + struct WriteQueueItem *prev; + + /** + * Number of bytes of payload, allocated at the end of this struct. + */ + size_t msize; +}; + + +/** + * Information we keep around for each active streaming client. + */ +struct StreamClient +{ + /** + * DLL + */ + struct StreamClient *next; + + /** + * DLL + */ + struct StreamClient *prev; + + /** + * Socket for communication. + */ + struct GNUNET_STREAM_Socket *socket; + + /** + * Handle for active read operation, or NULL. + */ + struct GNUNET_STREAM_ReadHandle *rh; + + /** + * Handle for active write operation, or NULL. + */ + struct GNUNET_STREAM_WriteHandle *wh; + + /** + * Head of write queue. + */ + struct WriteQueueItem *wqi_head; + + /** + * Tail of write queue. + */ + struct WriteQueueItem *wqi_tail; + + /** + * Tokenizer for requests. + */ + struct GNUNET_SERVER_MessageStreamTokenizer *mst; + + /** + * Current active request to the datastore, if we have one pending. + */ + struct GNUNET_DATASTORE_QueueEntry *qe; + + /** + * Task that is scheduled to asynchronously terminate the connection. + */ + GNUNET_SCHEDULER_TaskIdentifier terminate_task; + + /** + * Task that is scheduled to terminate idle connections. + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + + /** + * Size of the last write that was initiated. + */ + size_t reply_size; + +}; + + +/** + * Query from one peer, asking the other for CHK-data. + */ +struct StreamQueryMessage +{ + + /** + * Type is GNUNET_MESSAGE_TYPE_FS_STREAM_QUERY. + */ + struct GNUNET_MessageHeader header; + + /** + * Block type must be DBLOCK or IBLOCK. + */ + uint32_t type; + + /** + * Query hash from CHK (hash of encrypted block). + */ + struct GNUNET_HashCode query; + +}; + + +/** + * Reply to a StreamQueryMessage. + */ +struct StreamReplyMessage +{ + + /** + * Type is GNUNET_MESSAGE_TYPE_FS_STREAM_REPLY. + */ + struct GNUNET_MessageHeader header; + + /** + * Block type must be DBLOCK or IBLOCK. + */ + uint32_t type; + + /** + * Expiration time for the block. + */ + struct GNUNET_TIME_AbsoluteNBO expiration; + + /* followed by the encrypted block */ + +}; + + +/** + * Handle for a stream to another peer. + */ +struct StreamHandle; + + +/** + * Handle for a request that is going out via stream API. + */ +struct GSF_StreamRequest +{ + + /** + * DLL. + */ + struct GSF_StreamRequest *next; + + /** + * DLL. + */ + struct GSF_StreamRequest *prev; + + /** + * Which stream is this request associated with? + */ + struct StreamHandle *sh; + + /** + * Function to call with the result. + */ + GSF_StreamReplyProcessor proc; + + /** + * Closure for 'proc' + */ + void *proc_cls; + + /** + * Query to transmit to the other peer. + */ + struct GNUNET_HashCode query; + + /** + * Desired type for the reply. + */ + enum GNUNET_BLOCK_Type type; + + /** + * Did we transmit this request already? YES if we are + * in the 'waiting' DLL, NO if we are in the 'pending' DLL. + */ + int was_transmitted; +}; + + +/** + * Handle for a stream to another peer. + */ +struct StreamHandle +{ + /** + * Head of DLL of pending requests on this stream. + */ + struct GSF_StreamRequest *pending_head; + + /** + * Tail of DLL of pending requests on this stream. + */ + struct GSF_StreamRequest *pending_tail; + + /** + * Map from query to 'struct GSF_StreamRequest's waiting for + * a reply. + */ + struct GNUNET_CONTAINER_MultiHashMap *waiting_map; + + /** + * Connection to the other peer. + */ + struct GNUNET_STREAM_Socket *stream; + + /** + * Handle for active read operation, or NULL. + */ + struct GNUNET_STREAM_ReadHandle *rh; + + /** + * Handle for active write operation, or NULL. + */ + struct GNUNET_STREAM_WriteHandle *wh; + + /** + * Tokenizer for replies. + */ + struct GNUNET_SERVER_MessageStreamTokenizer *mst; + + /** + * Which peer does this stream go to? + */ + struct GNUNET_PeerIdentity target; + + /** + * Task to kill inactive streams (we keep them around for + * a few seconds to give the application a chance to give + * us another query). + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + + /** + * Task to reset streams that had errors (asynchronously, + * as we may not be able to do it immediately during a + * callback from the stream API). + */ + GNUNET_SCHEDULER_TaskIdentifier reset_task; + + /** + * Is this stream ready for transmission? + */ + int is_ready; + +}; + + +/** + * Listen socket for incoming requests. + */ +static struct GNUNET_STREAM_ListenSocket *listen_socket; + +/** + * Head of DLL of stream clients. + */ +static struct StreamClient *sc_head; + +/** + * Tail of DLL of stream clients. + */ +static struct StreamClient *sc_tail; + +/** + * Number of active stream clients in the 'sc_*'-DLL. + */ +static unsigned int sc_count; + +/** + * Maximum allowed number of stream clients. + */ +static unsigned long long sc_count_max; + +/** + * Map from peer identities to 'struct StreamHandles' with streams to + * those peers. + */ +static struct GNUNET_CONTAINER_MultiHashMap *stream_map; + + +/* ********************* client-side code ************************* */ + +/** + * Iterator called on each entry in a waiting map to + * call the 'proc' continuation and release associated + * resources. + * + * @param cls the 'struct StreamHandle' + * @param key the key of the entry in the map (the query) + * @param value the 'struct GSF_StreamRequest' to clean up + * @return GNUNET_YES (continue to iterate) + */ +static int +free_waiting_entry (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct GSF_StreamRequest *sr = value; + + sr->proc (sr->proc_cls, GNUNET_BLOCK_TYPE_ANY, + GNUNET_TIME_UNIT_FOREVER_ABS, + 0, NULL); + GSF_stream_query_cancel (sr); + return GNUNET_YES; +} + + +/** + * Destroy a stream handle. + * + * @param sh stream to process + */ +static void +destroy_stream_handle (struct StreamHandle *sh) +{ + struct GSF_StreamRequest *sr; + + while (NULL != (sr = sh->pending_head)) + { + sr->proc (sr->proc_cls, GNUNET_BLOCK_TYPE_ANY, + GNUNET_TIME_UNIT_FOREVER_ABS, + 0, NULL); + GSF_stream_query_cancel (sr); + } + GNUNET_CONTAINER_multihashmap_iterate (sh->waiting_map, + &free_waiting_entry, + sh); + if (NULL != sh->wh) + GNUNET_STREAM_write_cancel (sh->wh); + if (NULL != sh->rh) + GNUNET_STREAM_read_cancel (sh->rh); + if (GNUNET_SCHEDULER_NO_TASK != sh->timeout_task) + GNUNET_SCHEDULER_cancel (sh->timeout_task); + if (GNUNET_SCHEDULER_NO_TASK != sh->reset_task) + GNUNET_SCHEDULER_cancel (sh->reset_task); + GNUNET_STREAM_close (sh->stream); + GNUNET_assert (GNUNET_OK == + GNUNET_CONTAINER_multihashmap_remove (stream_map, + &sh->target.hashPubKey, + sh)); + GNUNET_CONTAINER_multihashmap_destroy (sh->waiting_map); + GNUNET_free (sh); +} + + +/** + * Transmit pending requests via the stream. + * + * @param sh stream to process + */ +static void +transmit_pending (struct StreamHandle *sh); + + +/** + * Function called once the stream is ready for transmission. + * + * @param cls the 'struct StreamHandle' + * @param socket stream socket handle + */ +static void +stream_ready_cb (void *cls, + struct GNUNET_STREAM_Socket *socket) +{ + struct StreamHandle *sh = cls; + + sh->is_ready = GNUNET_YES; + transmit_pending (sh); +} + + +/** + * Iterator called on each entry in a waiting map to + * move it back to the pending list. + * + * @param cls the 'struct StreamHandle' + * @param key the key of the entry in the map (the query) + * @param value the 'struct GSF_StreamRequest' to move to pending + * @return GNUNET_YES (continue to iterate) + */ +static int +move_to_pending (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct StreamHandle *sh = cls; + struct GSF_StreamRequest *sr = value; + + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (sh->waiting_map, + key, + value)); + GNUNET_CONTAINER_DLL_insert (sh->pending_head, + sh->pending_tail, + sr); + sr->was_transmitted = GNUNET_NO; + return GNUNET_YES; +} + + +/** + * We had a serious error, tear down and re-create stream from scratch. + * + * @param sh stream to reset + */ +static void +reset_stream (struct StreamHandle *sh) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Resetting stream to %s\n", + GNUNET_i2s (&sh->target)); + if (NULL != sh->rh) + { + GNUNET_STREAM_read_cancel (sh->rh); + sh->rh = NULL; + } + GNUNET_STREAM_close (sh->stream); + sh->is_ready = GNUNET_NO; + GNUNET_CONTAINER_multihashmap_iterate (sh->waiting_map, + &move_to_pending, + sh); + sh->stream = GNUNET_STREAM_open (GSF_cfg, + &sh->target, + GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER, + &stream_ready_cb, sh, + GNUNET_STREAM_OPTION_END); +} + + +/** + * Task called when it is time to destroy an inactive stream. + * + * @param cls the 'struct StreamHandle' to tear down + * @param tc scheduler context, unused + */ +static void +stream_timeout (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct StreamHandle *sh = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Timeout on stream to %s\n", + GNUNET_i2s (&sh->target)); + sh->timeout_task = GNUNET_SCHEDULER_NO_TASK; + destroy_stream_handle (sh); +} + + +/** + * Task called when it is time to reset an stream. + * + * @param cls the 'struct StreamHandle' to tear down + * @param tc scheduler context, unused + */ +static void +reset_stream_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct StreamHandle *sh = cls; + + sh->reset_task = GNUNET_SCHEDULER_NO_TASK; + reset_stream (sh); +} + + +/** + * We had a serious error, tear down and re-create stream from scratch, + * but do so asynchronously. + * + * @param sh stream to reset + */ +static void +reset_stream_async (struct StreamHandle *sh) +{ + if (GNUNET_SCHEDULER_NO_TASK != sh->reset_task) + GNUNET_SCHEDULER_cancel (sh->reset_task); + sh->reset_task = GNUNET_SCHEDULER_add_now (&reset_stream_task, + sh); +} + + +/** + * We got a reply from the stream. Process it. + * + * @param cls the struct StreamHandle + * @param status the status of the stream at the time this function is called + * @param data traffic from the other side + * @param size the number of bytes available in data read; will be 0 on timeout + * @return number of bytes of processed from 'data' (any data remaining should be + * given to the next time the read processor is called). + */ +static size_t +handle_stream_reply (void *cls, + enum GNUNET_STREAM_Status status, + const void *data, + size_t size) +{ + struct StreamHandle *sh = cls; + + sh->rh = NULL; + GNUNET_SCHEDULER_cancel (sh->reset_task); + sh->reset_task = GNUNET_SCHEDULER_add_delayed (CLIENT_RETRY_TIMEOUT, + &reset_stream_task, + sh); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received %u bytes from stream to %s\n", + (unsigned int) size, + GNUNET_i2s (&sh->target)); + if (GNUNET_SYSERR == + GNUNET_SERVER_mst_receive (sh->mst, + NULL, + data, size, + GNUNET_NO, GNUNET_NO)) + { + GNUNET_break_op (0); + reset_stream_async (sh); + return size; + } + if (NULL == sh->rh) + sh->rh = GNUNET_STREAM_read (sh->stream, + GNUNET_TIME_UNIT_FOREVER_REL, + &handle_stream_reply, + sh); + return size; +} + + +/** + * Functions of this signature are called whenever we transmitted a + * query via a stream. + * + * @param cls the struct StreamHandle for which we did the write call + * @param status the status of the stream at the time this function is called; + * GNUNET_OK if writing to stream was completed successfully, + * GNUNET_STREAM_SHUTDOWN if the stream is shutdown for writing in the + * mean time. + * @param size the number of bytes written + */ +static void +query_write_continuation (void *cls, + enum GNUNET_STREAM_Status status, + size_t size) +{ + struct StreamHandle *sh = cls; + + sh->wh = NULL; + if ( (GNUNET_STREAM_OK != status) || + (sizeof (struct StreamQueryMessage) != size) ) + { + reset_stream (sh); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Successfully transmitted %u bytes via stream to %s\n", + (unsigned int) size, + GNUNET_i2s (&sh->target)); + if (NULL == sh->rh) + sh->rh = GNUNET_STREAM_read (sh->stream, + GNUNET_TIME_UNIT_FOREVER_REL, + &handle_stream_reply, + sh); + transmit_pending (sh); +} + + +/** + * Transmit pending requests via the stream. + * + * @param sh stream to process + */ +static void +transmit_pending (struct StreamHandle *sh) +{ + struct StreamQueryMessage sqm; + struct GSF_StreamRequest *sr; + + if (NULL != sh->wh) + return; + sr = sh->pending_head; + if (NULL == sr) + return; + GNUNET_CONTAINER_DLL_remove (sh->pending_head, + sh->pending_tail, + sr); + GNUNET_CONTAINER_multihashmap_put (sh->waiting_map, + &sr->query, + sr, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sending query via stream to %s\n", + GNUNET_i2s (&sh->target)); + sr->was_transmitted = GNUNET_YES; + sqm.header.size = htons (sizeof (sqm)); + sqm.header.type = htons (GNUNET_MESSAGE_TYPE_FS_STREAM_QUERY); + sqm.type = htonl (sr->type); + sqm.query = sr->query; + sh->wh = GNUNET_STREAM_write (sh->stream, + &sqm, sizeof (sqm), + GNUNET_TIME_UNIT_FOREVER_REL, + &query_write_continuation, + sh); +} + + +/** + * Closure for 'handle_reply'. + */ +struct HandleReplyClosure +{ + + /** + * Reply payload. + */ + const void *data; + + /** + * Expiration time for the block. + */ + struct GNUNET_TIME_Absolute expiration; + + /** + * Number of bytes in 'data'. + */ + size_t data_size; + + /** + * Type of the block. + */ + enum GNUNET_BLOCK_Type type; + + /** + * Did we have a matching query? + */ + int found; +}; + + +/** + * Iterator called on each entry in a waiting map to + * process a result. + * + * @param cls the 'struct HandleReplyClosure' + * @param key the key of the entry in the map (the query) + * @param value the 'struct GSF_StreamRequest' to handle result for + * @return GNUNET_YES (continue to iterate) + */ +static int +handle_reply (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct HandleReplyClosure *hrc = cls; + struct GSF_StreamRequest *sr = value; + + sr->proc (sr->proc_cls, + hrc->type, + hrc->expiration, + hrc->data_size, + hrc->data); + GSF_stream_query_cancel (sr); + hrc->found = GNUNET_YES; + return GNUNET_YES; +} + + +/** + * Functions with this signature are called whenever a + * complete reply is received. + * + * Do not call GNUNET_SERVER_mst_destroy in callback + * + * @param cls closure with the 'struct StreamHandle' + * @param client identification of the client, NULL + * @param message the actual message + * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing + */ +static int +reply_cb (void *cls, + void *client, + const struct GNUNET_MessageHeader *message) +{ + struct StreamHandle *sh = cls; + const struct StreamReplyMessage *srm; + struct HandleReplyClosure hrc; + uint16_t msize; + enum GNUNET_BLOCK_Type type; + struct GNUNET_HashCode query; + + msize = ntohs (message->size); + switch (ntohs (message->type)) + { + case GNUNET_MESSAGE_TYPE_FS_STREAM_REPLY: + if (sizeof (struct StreamReplyMessage) > msize) + { + GNUNET_break_op (0); + reset_stream_async (sh); + return GNUNET_SYSERR; + } + srm = (const struct StreamReplyMessage *) message; + msize -= sizeof (struct StreamReplyMessage); + type = (enum GNUNET_BLOCK_Type) ntohl (srm->type); + if (GNUNET_YES != + GNUNET_BLOCK_get_key (GSF_block_ctx, + type, + &srm[1], msize, &query)) + { + GNUNET_break_op (0); + reset_stream_async (sh); + return GNUNET_SYSERR; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received reply `%s' via stream\n", + GNUNET_h2s (&query)); + GNUNET_STATISTICS_update (GSF_stats, + gettext_noop ("# replies received via stream"), 1, + GNUNET_NO); + hrc.data = &srm[1]; + hrc.data_size = msize; + hrc.expiration = GNUNET_TIME_absolute_ntoh (srm->expiration); + hrc.type = type; + hrc.found = GNUNET_NO; + GNUNET_CONTAINER_multihashmap_get_multiple (sh->waiting_map, + &query, + &handle_reply, + &hrc); + if (GNUNET_NO == hrc.found) + { + GNUNET_STATISTICS_update (GSF_stats, + gettext_noop ("# replies received via stream dropped"), 1, + GNUNET_NO); + return GNUNET_OK; + } + return GNUNET_OK; + default: + GNUNET_break_op (0); + reset_stream_async (sh); + return GNUNET_SYSERR; + } +} + + +/** + * Get (or create) a stream to talk to the given peer. + * + * @param target peer we want to communicate with + */ +static struct StreamHandle * +get_stream (const struct GNUNET_PeerIdentity *target) +{ + struct StreamHandle *sh; + + sh = GNUNET_CONTAINER_multihashmap_get (stream_map, + &target->hashPubKey); + if (NULL != sh) + { + if (GNUNET_SCHEDULER_NO_TASK != sh->timeout_task) + { + GNUNET_SCHEDULER_cancel (sh->timeout_task); + sh->timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + return sh; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Creating stream to %s\n", + GNUNET_i2s (target)); + sh = GNUNET_malloc (sizeof (struct StreamHandle)); + sh->reset_task = GNUNET_SCHEDULER_add_delayed (CLIENT_RETRY_TIMEOUT, + &reset_stream_task, + sh); + sh->mst = GNUNET_SERVER_mst_create (&reply_cb, + sh); + sh->waiting_map = GNUNET_CONTAINER_multihashmap_create (512, GNUNET_YES); + sh->target = *target; + sh->stream = GNUNET_STREAM_open (GSF_cfg, + &sh->target, + GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER, + &stream_ready_cb, sh, + GNUNET_STREAM_OPTION_END); + GNUNET_assert (GNUNET_OK == + GNUNET_CONTAINER_multihashmap_put (stream_map, + &sh->target.hashPubKey, + sh, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + return sh; +} + + +/** + * Look for a block by directly contacting a particular peer. + * + * @param target peer that should have the block + * @param query hash to query for the block + * @param type desired type for the block + * @param proc function to call with result + * @param proc_cls closure for 'proc' + * @return handle to cancel the operation + */ +struct GSF_StreamRequest * +GSF_stream_query (const struct GNUNET_PeerIdentity *target, + const struct GNUNET_HashCode *query, + enum GNUNET_BLOCK_Type type, + GSF_StreamReplyProcessor proc, void *proc_cls) +{ + struct StreamHandle *sh; + struct GSF_StreamRequest *sr; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Preparing to send query for %s via stream to %s\n", + GNUNET_h2s (query), + GNUNET_i2s (target)); + sh = get_stream (target); + sr = GNUNET_malloc (sizeof (struct GSF_StreamRequest)); + sr->sh = sh; + sr->proc = proc; + sr->proc_cls = proc_cls; + sr->type = type; + sr->query = *query; + GNUNET_CONTAINER_DLL_insert (sh->pending_head, + sh->pending_tail, + sr); + if (GNUNET_YES == sh->is_ready) + transmit_pending (sh); + return sr; +} + + +/** + * Cancel an active request; must not be called after 'proc' + * was calld. + * + * @param sr request to cancel + */ +void +GSF_stream_query_cancel (struct GSF_StreamRequest *sr) +{ + struct StreamHandle *sh = sr->sh; + + if (GNUNET_YES == sr->was_transmitted) + GNUNET_assert (GNUNET_OK == + GNUNET_CONTAINER_multihashmap_remove (sh->waiting_map, + &sr->query, + sr)); + else + GNUNET_CONTAINER_DLL_remove (sh->pending_head, + sh->pending_tail, + sr); + GNUNET_free (sr); + if ( (0 == GNUNET_CONTAINER_multihashmap_size (sh->waiting_map)) && + (NULL == sh->pending_head) ) + sh->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, + &stream_timeout, + sh); +} + + +/* ********************* server-side code ************************* */ + + +/** + * We're done with a particular client, clean up. + * + * @param sc client to clean up + */ +static void +terminate_stream (struct StreamClient *sc) +{ + GNUNET_STATISTICS_update (GSF_stats, + gettext_noop ("# stream connections active"), -1, + GNUNET_NO); + if (GNUNET_SCHEDULER_NO_TASK != sc->terminate_task) + GNUNET_SCHEDULER_cancel (sc->terminate_task); + if (GNUNET_SCHEDULER_NO_TASK != sc->timeout_task) + GNUNET_SCHEDULER_cancel (sc->timeout_task); + if (NULL != sc->rh) + GNUNET_STREAM_read_cancel (sc->rh); + if (NULL != sc->wh) + GNUNET_STREAM_write_cancel (sc->wh); + if (NULL != sc->qe) + GNUNET_DATASTORE_cancel (sc->qe); + GNUNET_SERVER_mst_destroy (sc->mst); + GNUNET_STREAM_close (sc->socket); + struct WriteQueueItem *wqi; + while (NULL != (wqi = sc->wqi_head)) + { + GNUNET_CONTAINER_DLL_remove (sc->wqi_head, + sc->wqi_tail, + wqi); + GNUNET_free (wqi); + } + + + GNUNET_CONTAINER_DLL_remove (sc_head, + sc_tail, + sc); + sc_count--; + GNUNET_free (sc); +} + + +/** + * Task run to asynchronously terminate the stream. + * + * @param cls the 'struct StreamClient' + * @param tc scheduler context + */ +static void +terminate_stream_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct StreamClient *sc = cls; + + sc->terminate_task = GNUNET_SCHEDULER_NO_TASK; + terminate_stream (sc); +} + + +/** + * Task run to asynchronously terminate the stream due to timeout. + * + * @param cls the 'struct StreamClient' + * @param tc scheduler context + */ +static void +timeout_stream_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct StreamClient *sc = cls; + + sc->timeout_task = GNUNET_SCHEDULER_NO_TASK; + terminate_stream (sc); +} + + +/** + * Reset the timeout for the stream client (due to activity). + * + * @param sc client handle to reset timeout for + */ +static void +refresh_timeout_task (struct StreamClient *sc) +{ + if (GNUNET_SCHEDULER_NO_TASK != sc->timeout_task) + GNUNET_SCHEDULER_cancel (sc->timeout_task); + sc->timeout_task = GNUNET_SCHEDULER_add_delayed (IDLE_TIMEOUT, + &timeout_stream_task, + sc); +} + + +/** + * We had a serious error, termiante stream, + * but do so asynchronously. + * + * @param sc stream to reset + */ +static void +terminate_stream_async (struct StreamClient *sc) +{ + if (GNUNET_SCHEDULER_NO_TASK == sc->terminate_task) + sc->terminate_task = GNUNET_SCHEDULER_add_now (&terminate_stream_task, + sc); +} + + +/** + * Functions of this signature are called whenever data is available from the + * stream. + * + * @param cls the closure from GNUNET_STREAM_read + * @param status the status of the stream at the time this function is called + * @param data traffic from the other side + * @param size the number of bytes available in data read; will be 0 on timeout + * @return number of bytes of processed from 'data' (any data remaining should be + * given to the next time the read processor is called). + */ +static size_t +process_request (void *cls, + enum GNUNET_STREAM_Status status, + const void *data, + size_t size); + + +/** + * We're done handling a request from a client, read the next one. + * + * @param sc client to continue reading requests from + */ +static void +continue_reading (struct StreamClient *sc) +{ + int ret; + + ret = + GNUNET_SERVER_mst_receive (sc->mst, + NULL, + NULL, 0, + GNUNET_NO, GNUNET_NO); + if (GNUNET_NO == ret) + return; + refresh_timeout_task (sc); + if (NULL != sc->rh) + return; + sc->rh = GNUNET_STREAM_read (sc->socket, + GNUNET_TIME_UNIT_FOREVER_REL, + &process_request, + sc); +} + + +/** + * Transmit the next entry from the write queue. + * + * @param sc where to process the write queue + */ +static void +continue_writing (struct StreamClient *sc); + + +/** + * Functions of this signature are called whenever data is available from the + * stream. + * + * @param cls the closure from GNUNET_STREAM_read + * @param status the status of the stream at the time this function is called + * @param data traffic from the other side + * @param size the number of bytes available in data read; will be 0 on timeout + * @return number of bytes of processed from 'data' (any data remaining should be + * given to the next time the read processor is called). + */ +static size_t +process_request (void *cls, + enum GNUNET_STREAM_Status status, + const void *data, + size_t size) +{ + struct StreamClient *sc = cls; + int ret; + + sc->rh = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received %u byte query via stream\n", + (unsigned int) size); + switch (status) + { + case GNUNET_STREAM_OK: + ret = + GNUNET_SERVER_mst_receive (sc->mst, + NULL, + data, size, + GNUNET_NO, GNUNET_NO); + if (GNUNET_NO == ret) + return size; /* more messages in MST */ + if (GNUNET_SYSERR == ret) + { + GNUNET_break_op (0); + terminate_stream_async (sc); + return size; + } + break; + case GNUNET_STREAM_TIMEOUT: + case GNUNET_STREAM_SHUTDOWN: + case GNUNET_STREAM_SYSERR: + terminate_stream_async (sc); + return size; + default: + GNUNET_break (0); + return size; + } + continue_writing (sc); + return size; +} + + +/** + * Sending a reply was completed, continue processing. + * + * @param cls closure with the struct StreamClient which sent the query + * @param status result code for the operation + * @param size number of bytes that were transmitted + */ +static void +write_continuation (void *cls, + enum GNUNET_STREAM_Status status, + size_t size) +{ + struct StreamClient *sc = cls; + + sc->wh = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Write continuation called on 'server' side with status %d\n", + status); + if ( (GNUNET_STREAM_OK != status) || + (size != sc->reply_size) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Transmission of reply failed, terminating stream\n"); + terminate_stream (sc); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Transmitted %u byte reply via stream\n", + (unsigned int) size); + GNUNET_STATISTICS_update (GSF_stats, + gettext_noop ("# Blocks transferred via stream"), 1, + GNUNET_NO); + continue_writing (sc); +} + + +/** + * Transmit the next entry from the write queue. + * + * @param sc where to process the write queue + */ +static void +continue_writing (struct StreamClient *sc) +{ + struct WriteQueueItem *wqi; + + if (NULL != sc->wh) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Write pending, waiting for it to complete\n"); + return; /* write already pending */ + } + if (NULL == (wqi = sc->wqi_head)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Write queue empty, reading more requests\n"); + continue_reading (sc); + return; + } + GNUNET_CONTAINER_DLL_remove (sc->wqi_head, + sc->wqi_tail, + wqi); + sc->wh = GNUNET_STREAM_write (sc->socket, + &wqi[1], wqi->msize, + GNUNET_TIME_UNIT_FOREVER_REL, + &write_continuation, + sc); + if (NULL != sc->wh) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Gave %u bytes for stream for transmission\n", + (unsigned int) wqi->msize); + GNUNET_free (wqi); + if (NULL == sc->wh) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Write failed; terminating stream\n"); + terminate_stream (sc); + return; + } +} + + +/** + * Process a datum that was stored in the datastore. + * + * @param cls closure with the struct StreamClient which sent the query + * @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 +handle_datastore_reply (void *cls, + const struct GNUNET_HashCode * key, + size_t size, const void *data, + enum GNUNET_BLOCK_Type type, + uint32_t priority, + uint32_t anonymity, + struct GNUNET_TIME_Absolute + expiration, uint64_t uid) +{ + struct StreamClient *sc = cls; + size_t msize = size + sizeof (struct StreamReplyMessage); + struct WriteQueueItem *wqi; + struct StreamReplyMessage *srm; + + sc->qe = NULL; + if (GNUNET_BLOCK_TYPE_FS_ONDEMAND == type) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Performing on-demand encoding\n"); + if (GNUNET_OK != + GNUNET_FS_handle_on_demand_block (key, + size, data, type, + priority, anonymity, + expiration, uid, + &handle_datastore_reply, + sc)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "On-demand encoding request failed\n"); + continue_writing (sc); + } + return; + } + if (msize > GNUNET_SERVER_MAX_MESSAGE_SIZE) + { + GNUNET_break (0); + continue_writing (sc); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting transmission of %u byte reply for query `%s' via stream\n", + (unsigned int) size, + GNUNET_h2s (key)); + wqi = GNUNET_malloc (sizeof (struct WriteQueueItem) + msize); + wqi->msize = msize; + srm = (struct StreamReplyMessage *) &wqi[1]; + srm->header.size = htons ((uint16_t) msize); + srm->header.type = htons (GNUNET_MESSAGE_TYPE_FS_STREAM_REPLY); + srm->type = htonl (type); + srm->expiration = GNUNET_TIME_absolute_hton (expiration); + memcpy (&srm[1], data, size); + sc->reply_size = msize; + GNUNET_CONTAINER_DLL_insert (sc->wqi_head, + sc->wqi_tail, + wqi); + continue_writing (sc); +} + + +/** + * Functions with this signature are called whenever a + * complete query message is received. + * + * Do not call GNUNET_SERVER_mst_destroy in callback + * + * @param cls closure with the 'struct StreamClient' + * @param client identification of the client, NULL + * @param message the actual message + * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing + */ +static int +request_cb (void *cls, + void *client, + const struct GNUNET_MessageHeader *message) +{ + struct StreamClient *sc = cls; + const struct StreamQueryMessage *sqm; + + switch (ntohs (message->type)) + { + case GNUNET_MESSAGE_TYPE_FS_STREAM_QUERY: + if (sizeof (struct StreamQueryMessage) != + ntohs (message->size)) + { + GNUNET_break_op (0); + terminate_stream_async (sc); + return GNUNET_SYSERR; + } + sqm = (const struct StreamQueryMessage *) message; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received query for `%s' via stream\n", + GNUNET_h2s (&sqm->query)); + GNUNET_STATISTICS_update (GSF_stats, + gettext_noop ("# queries received via stream"), 1, + GNUNET_NO); + refresh_timeout_task (sc); + sc->qe = GNUNET_DATASTORE_get_key (GSF_dsh, + 0, + &sqm->query, + ntohl (sqm->type), + 0 /* priority */, + GSF_datastore_queue_size, + GNUNET_TIME_UNIT_FOREVER_REL, + &handle_datastore_reply, sc); + if (NULL == sc->qe) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Queueing request with datastore failed (queue full?)\n"); + continue_writing (sc); + } + return GNUNET_OK; + default: + GNUNET_break_op (0); + terminate_stream_async (sc); + return GNUNET_SYSERR; + } +} + + +/** + * Functions of this type are called upon new stream connection from other peers + * or upon binding error which happen when the app_port given in + * GNUNET_STREAM_listen() is already taken. + * + * @param cls the closure from GNUNET_STREAM_listen + * @param socket the socket representing the stream; NULL on binding error + * @param initiator the identity of the peer who wants to establish a stream + * with us; NULL on binding error + * @return GNUNET_OK to keep the socket open, GNUNET_SYSERR to close the + * stream (the socket will be invalid after the call) + */ +static int +accept_cb (void *cls, + struct GNUNET_STREAM_Socket *socket, + const struct GNUNET_PeerIdentity *initiator) +{ + struct StreamClient *sc; + + if (NULL == socket) + return GNUNET_SYSERR; + if (sc_count >= sc_count_max) + { + GNUNET_STATISTICS_update (GSF_stats, + gettext_noop ("# stream client connections rejected"), 1, + GNUNET_NO); + return GNUNET_SYSERR; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Accepting inbound stream connection from `%s'\n", + GNUNET_i2s (initiator)); + GNUNET_STATISTICS_update (GSF_stats, + gettext_noop ("# stream connections active"), 1, + GNUNET_NO); + sc = GNUNET_malloc (sizeof (struct StreamClient)); + sc->socket = socket; + sc->mst = GNUNET_SERVER_mst_create (&request_cb, + sc); + sc->rh = GNUNET_STREAM_read (sc->socket, + GNUNET_TIME_UNIT_FOREVER_REL, + &process_request, + sc); + GNUNET_CONTAINER_DLL_insert (sc_head, + sc_tail, + sc); + sc_count++; + refresh_timeout_task (sc); + return GNUNET_OK; +} + + +/** + * Initialize subsystem for non-anonymous file-sharing. + */ +void +GSF_stream_start () +{ + stream_map = GNUNET_CONTAINER_multihashmap_create (16, GNUNET_YES); + if (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_number (GSF_cfg, + "fs", + "MAX_STREAM_CLIENTS", + &sc_count_max)) + { + listen_socket = GNUNET_STREAM_listen (GSF_cfg, + GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER, + &accept_cb, NULL, + GNUNET_STREAM_OPTION_END); + } +} + + +/** + * Function called on each active streams to shut them down. + * + * @param cls NULL + * @param key target peer, unused + * @param value the 'struct StreamHandle' to destroy + * @return GNUNET_YES (continue to iterate) + */ +static int +release_streams (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct StreamHandle *sh = value; + + destroy_stream_handle (sh); + return GNUNET_YES; +} + + +/** + * Shutdown subsystem for non-anonymous file-sharing. + */ +void +GSF_stream_stop () +{ + struct StreamClient *sc; + + while (NULL != (sc = sc_head)) + terminate_stream (sc); + if (NULL != listen_socket) + { + GNUNET_STREAM_listen_close (listen_socket); + listen_socket = NULL; + } + GNUNET_CONTAINER_multihashmap_iterate (stream_map, + &release_streams, + NULL); + GNUNET_CONTAINER_multihashmap_destroy (stream_map); + stream_map = NULL; +} + +/* end of gnunet-service-fs_stream.c */ diff --git a/src/fs/gnunet-service-fs_stream.h b/src/fs/gnunet-service-fs_stream.h new file mode 100644 index 0000000..9827667 --- /dev/null +++ b/src/fs/gnunet-service-fs_stream.h @@ -0,0 +1,91 @@ +/* + 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/gnunet-service-fs_stream.h + * @brief non-anonymous file-transfer + * @author Christian Grothoff + */ +#ifndef GNUNET_SERVICE_FS_STREAM_H +#define GNUNET_SERVICE_FS_STREAM_H + +/** + * Handle for a request that is going out via stream API. + */ +struct GSF_StreamRequest; + + +/** + * Function called with a reply from the stream. + * + * @param cls closure + * @param type type of the block, ANY on error + * @param expiration expiration time for the block + * @param data_size number of bytes in 'data', 0 on error + * @param data reply block data, NULL on error + */ +typedef void (*GSF_StreamReplyProcessor)(void *cls, + enum GNUNET_BLOCK_Type type, + struct GNUNET_TIME_Absolute expiration, + size_t data_size, + const void *data); + + +/** + * Look for a block by directly contacting a particular peer. + * + * @param target peer that should have the block + * @param query hash to query for the block + * @param type desired type for the block + * @param proc function to call with result + * @param proc_cls closure for 'proc' + * @return handle to cancel the operation + */ +struct GSF_StreamRequest * +GSF_stream_query (const struct GNUNET_PeerIdentity *target, + const struct GNUNET_HashCode *query, + enum GNUNET_BLOCK_Type type, + GSF_StreamReplyProcessor proc, void *proc_cls); + + +/** + * Cancel an active request; must not be called after 'proc' + * was calld. + * + * @param sr request to cancel + */ +void +GSF_stream_query_cancel (struct GSF_StreamRequest *sr); + + +/** + * Initialize subsystem for non-anonymous file-sharing. + */ +void +GSF_stream_start (void); + + +/** + * Shutdown subsystem for non-anonymous file-sharing. + */ +void +GSF_stream_stop (void); + +#endif diff --git a/src/fs/gnunet-unindex.c b/src/fs/gnunet-unindex.c index 3e8308d..094d886 100644 --- a/src/fs/gnunet-unindex.c +++ b/src/fs/gnunet-unindex.c @@ -76,7 +76,7 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void * progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) { - char *s; + const char *s; switch (info->status) { @@ -85,11 +85,10 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *info) case GNUNET_FS_STATUS_UNINDEX_PROGRESS: if (verbose) { - s = GNUNET_STRINGS_relative_time_to_string (info->value.unindex.eta); + s = GNUNET_STRINGS_relative_time_to_string (info->value.unindex.eta, GNUNET_YES); FPRINTF (stdout, _("Unindexing at %llu/%llu (%s remaining)\n"), (unsigned long long) info->value.unindex.completed, (unsigned long long) info->value.unindex.size, s); - GNUNET_free (s); } break; case GNUNET_FS_STATUS_UNINDEX_ERROR: @@ -170,11 +169,17 @@ main (int argc, char *const *argv) 0, &GNUNET_GETOPT_set_one, &verbose}, GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-unindex [OPTIONS] FILENAME", - gettext_noop - ("Unindex a file that was previously indexed with gnunet-publish."), - options, &run, NULL)) ? ret : 1; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-unindex [OPTIONS] FILENAME", + gettext_noop + ("Unindex a file that was previously indexed with gnunet-publish."), + options, &run, NULL)) ? ret : 1; + GNUNET_free ((void*) argv); + return ret; } /* end of gnunet-unindex.c */ diff --git a/src/fs/perf_gnunet_service_fs_p2p.c b/src/fs/perf_gnunet_service_fs_p2p.c index 7b2c044..89db80c 100644 --- a/src/fs/perf_gnunet_service_fs_p2p.c +++ b/src/fs/perf_gnunet_service_fs_p2p.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010 Christian Grothoff (and other contributing authors) + (C) 2010, 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 @@ -25,7 +25,7 @@ */ #include "platform.h" #include "fs_test_lib.h" -#include "gnunet_testing_lib.h" +#include "gnunet_testbed_service.h" #define VERBOSE GNUNET_NO @@ -43,7 +43,7 @@ #define SEED 42 -static struct GNUNET_FS_TestDaemon *daemons[NUM_DAEMONS]; +static struct GNUNET_TESTBED_Peer *daemons[NUM_DAEMONS]; static int ok; @@ -51,12 +51,6 @@ static struct GNUNET_TIME_Absolute start_time; static const char *progname; -static void -do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); -} - /** * Master context for 'stat_run'. @@ -64,6 +58,7 @@ do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct StatMaster { struct GNUNET_STATISTICS_Handle *stat; + struct GNUNET_TESTBED_Operation *op; unsigned int daemon; unsigned int value; }; @@ -78,7 +73,6 @@ struct StatValues * Statistics we print out. */ static struct StatValues stats[] = { - {"fs", "# artificial delays introduced (ms)"}, {"fs", "# queries forwarded"}, {"fs", "# replies received and matched"}, {"fs", "# results found locally"}, @@ -130,7 +124,10 @@ print_stat (void *cls, const char *subsystem, const char *name, uint64_t value, * Function that gathers stats from all daemons. */ static void -stat_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); +stat_run (void *cls, + struct GNUNET_TESTBED_Operation *op, + void *ca_result, + const char *emsg); /** @@ -143,7 +140,41 @@ get_done (void *cls, int success) GNUNET_break (GNUNET_OK == success); sm->value++; - GNUNET_SCHEDULER_add_now (&stat_run, sm); + stat_run (sm, sm->op, sm->stat, NULL); +} + + +/** + * Adapter function called to establish a connection to + * statistics service. + * + * @param cls closure + * @param cfg configuration of the peer to connect to; will be available until + * GNUNET_TESTBED_operation_done() is called on the operation returned + * from GNUNET_TESTBED_service_connect() + * @return service handle to return in 'op_result', NULL on error + */ +static void * +statistics_connect_adapter (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + return GNUNET_STATISTICS_create ("<driver>", + cfg); +} + + +/** + * Adapter function called to destroy a connection to + * statistics service. + * + * @param cls closure + * @param op_result service handle returned from the connect adapter + */ +static void +statistics_disconnect_adapter (void *cls, + void *op_result) +{ + GNUNET_STATISTICS_destroy (op_result, GNUNET_NO); } @@ -151,10 +182,23 @@ get_done (void *cls, int success) * Function that gathers stats from all daemons. */ static void -stat_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +stat_run (void *cls, + struct GNUNET_TESTBED_Operation *op, + void *ca_result, + const char *emsg) { struct StatMaster *sm = cls; + if (NULL != emsg) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to statistics service: %s\n", + emsg); + GNUNET_SCHEDULER_shutdown (); + return; + } + sm->stat = ca_result; + if (stats[sm->value].name != NULL) { GNUNET_STATISTICS_get (sm->stat, @@ -167,67 +211,80 @@ stat_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) sm); return; } - GNUNET_STATISTICS_destroy (sm->stat, GNUNET_NO); + GNUNET_TESTBED_operation_done (sm->op); sm->value = 0; sm->daemon++; - if (sm->daemon == NUM_DAEMONS) + if (NUM_DAEMONS == sm->daemon) { GNUNET_free (sm); - GNUNET_SCHEDULER_add_now (&do_stop, NULL); + GNUNET_SCHEDULER_shutdown (); return; } - sm->stat = - GNUNET_STATISTICS_create ("<driver>", - GNUNET_FS_TEST_get_configuration (daemons, - sm->daemon)); - GNUNET_SCHEDULER_add_now (&stat_run, sm); + sm->op = + GNUNET_TESTBED_service_connect (NULL, + daemons[sm->daemon], + "statistics", + &stat_run, sm, + &statistics_connect_adapter, + &statistics_disconnect_adapter, + NULL); } static void do_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + char *fn = cls; struct GNUNET_TIME_Relative del; char *fancy; struct StatMaster *sm; - if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) + if (NULL != fn) { - del = GNUNET_TIME_absolute_get_duration (start_time); - if (del.rel_value == 0) - del.rel_value = 1; - fancy = - GNUNET_STRINGS_byte_size_fancy (((unsigned long long) FILESIZE) * - 1000LL / del.rel_value); - FPRINTF (stdout, "Download speed was %s/s\n", fancy); - GNUNET_free (fancy); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished download, shutting down\n", - (unsigned long long) FILESIZE); - sm = GNUNET_malloc (sizeof (struct StatMaster)); - sm->stat = - GNUNET_STATISTICS_create ("<driver>", - GNUNET_FS_TEST_get_configuration (daemons, - sm->daemon)); - GNUNET_SCHEDULER_add_now (&stat_run, sm); + GNUNET_DISK_directory_remove (fn); + GNUNET_free (fn); } - else + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Timeout during download, shutting down with error\n"); ok = 1; - GNUNET_SCHEDULER_add_now (&do_stop, NULL); + GNUNET_SCHEDULER_shutdown (); + return; } + + del = GNUNET_TIME_absolute_get_duration (start_time); + if (del.rel_value == 0) + del.rel_value = 1; + fancy = + GNUNET_STRINGS_byte_size_fancy (((unsigned long long) FILESIZE) * + 1000LL / del.rel_value); + FPRINTF (stdout, "Download speed was %s/s\n", fancy); + GNUNET_free (fancy); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished download, shutting down\n", + (unsigned long long) FILESIZE); + sm = GNUNET_malloc (sizeof (struct StatMaster)); + sm->op = + GNUNET_TESTBED_service_connect (NULL, + daemons[sm->daemon], + "statistics", + &stat_run, sm, + &statistics_connect_adapter, + &statistics_disconnect_adapter, + NULL); } static void -do_download (void *cls, const struct GNUNET_FS_Uri *uri) +do_download (void *cls, + const struct GNUNET_FS_Uri *uri, + const char *fn) { int anonymity; if (NULL == uri) - { - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); + { + GNUNET_SCHEDULER_shutdown (); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Timeout during upload attempt, shutting down with error\n"); ok = 1; @@ -241,23 +298,23 @@ do_download (void *cls, const struct GNUNET_FS_Uri *uri) else anonymity = 1; GNUNET_FS_TEST_download (daemons[0], TIMEOUT, anonymity, SEED, uri, VERBOSE, - &do_report, NULL); + &do_report, + (NULL == fn) ? NULL : GNUNET_strdup (fn)); } static void -do_publish (void *cls, const char *emsg) +do_publish (void *cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers) { + unsigned int i; int do_index; int anonymity; - - if (NULL != emsg) - { - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error trying to connect: %s\n", emsg); - ok = 1; - return; - } + + GNUNET_assert (NUM_DAEMONS == num_peers); + for (i=0;i<num_peers;i++) + daemons[i] = peers[i]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing %llu bytes\n", (unsigned long long) FILESIZE); if (NULL != strstr (progname, "index")) @@ -268,68 +325,21 @@ do_publish (void *cls, const char *emsg) anonymity = 0; else anonymity = 1; - GNUNET_FS_TEST_publish (daemons[NUM_DAEMONS - 1], TIMEOUT, anonymity, do_index, FILESIZE, SEED, VERBOSE, &do_download, NULL); } -static void -do_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_TESTING_PeerGroup *pg; - - GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Daemons started, will now try to connect them\n"); - pg = GNUNET_FS_TEST_get_group (daemons); - GNUNET_break ((NUM_DAEMONS - 1) * 2 == - (GNUNET_TESTING_create_topology - (pg, GNUNET_TESTING_TOPOLOGY_LINE, - GNUNET_TESTING_TOPOLOGY_NONE, NULL))); - GNUNET_TESTING_connect_topology (pg, GNUNET_TESTING_TOPOLOGY_LINE, - GNUNET_TESTING_TOPOLOGY_OPTION_NONE, 0.0, - TIMEOUT, NUM_DAEMONS, &do_publish, NULL); -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - GNUNET_FS_TEST_daemons_start ("fs_test_lib_data.conf", TIMEOUT, NUM_DAEMONS, - daemons, &do_connect, NULL); -} - - int main (int argc, char *argv[]) { - char *const argvx[] = { - "perf-gnunet-service-fs-p2p", - "-c", - "fs_test_lib_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; progname = argv[0]; - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); - GNUNET_log_setup ("perf_gnunet_service_fs_p2p_index", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "perf-gnunet-service-fs-p2p-index", "nohelp", options, - &run, NULL); + (void) GNUNET_TESTBED_test_run ("perf-gnunet-service-fs-p2p", + "perf_gnunet_service_fs_p2p.conf", + NUM_DAEMONS, + 0, NULL, NULL, + &do_publish, NULL); GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); return ok; } diff --git a/src/fs/perf_gnunet_service_fs_p2p.conf b/src/fs/perf_gnunet_service_fs_p2p.conf new file mode 100644 index 0000000..c9e472e --- /dev/null +++ b/src/fs/perf_gnunet_service_fs_p2p.conf @@ -0,0 +1,7 @@ +@INLINE@ fs_test_lib_data.conf +[PATHS] +SERVICEHOME = /tmp/gnunet-fs-test-lib/ + +[fs] +GAUGER_HEAP = "2-peer 10 MB P2P download" +# PREFIX = valgrind diff --git a/src/fs/perf_gnunet_service_fs_p2p_trust.c b/src/fs/perf_gnunet_service_fs_p2p_respect.c index c412e84..0a5dc05 100644 --- a/src/fs/perf_gnunet_service_fs_p2p_trust.c +++ b/src/fs/perf_gnunet_service_fs_p2p_respect.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010, 2011 Christian Grothoff (and other contributing authors) + (C) 2010, 2011, 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 @@ -19,8 +19,8 @@ */ /** - * @file fs/perf_gnunet_service_fs_p2p_trust.c - * @brief profile P2P routing trust mechanism. Creates + * @file fs/perf_gnunet_service_fs_p2p_respect.c + * @brief profile P2P routing respect mechanism. Creates * a clique of NUM_DAEMONS (i.e. 3) where two * peers share (seed) different files and download * them from each other while all the other peers @@ -45,7 +45,7 @@ */ #include "platform.h" #include "fs_test_lib.h" -#include "gnunet_testing_lib.h" +#include "gnunet_testbed_service.h" #define VERBOSE GNUNET_NO @@ -74,7 +74,7 @@ */ #define SEED2 43 -static struct GNUNET_FS_TestDaemon *daemons[NUM_DAEMONS]; +static struct GNUNET_TESTBED_Peer *daemons[NUM_DAEMONS]; static int ok; @@ -86,12 +86,9 @@ static struct GNUNET_FS_Uri *uri1; static struct GNUNET_FS_Uri *uri2; -static void -do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); -} +static char *fn1; +static char *fn2; /** * Master context for 'stat_run'. @@ -99,6 +96,7 @@ do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct StatMaster { struct GNUNET_STATISTICS_Handle *stat; + struct GNUNET_TESTBED_Operation *op; unsigned int daemon; unsigned int value; }; @@ -137,6 +135,23 @@ static struct StatValues stats[] = { }; +static void +cleanup () +{ + GNUNET_SCHEDULER_shutdown (); + if (NULL != fn1) + { + GNUNET_DISK_directory_remove (fn1); + GNUNET_free (fn1); + } + if (NULL != fn2) + { + GNUNET_DISK_directory_remove (fn2); + GNUNET_free (fn2); + } +} + + /** * Callback function to process statistic values. * @@ -163,7 +178,10 @@ print_stat (void *cls, const char *subsystem, const char *name, uint64_t value, * Function that gathers stats from all daemons. */ static void -stat_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); +stat_run (void *cls, + struct GNUNET_TESTBED_Operation *op, + void *ca_result, + const char *emsg); /** @@ -176,7 +194,42 @@ get_done (void *cls, int success) GNUNET_break (GNUNET_OK == success); sm->value++; - GNUNET_SCHEDULER_add_now (&stat_run, sm); + stat_run (sm, sm->op, sm->stat, NULL); +} + + + +/** + * Adapter function called to establish a connection to + * statistics service. + * + * @param cls closure + * @param cfg configuration of the peer to connect to; will be available until + * GNUNET_TESTBED_operation_done() is called on the operation returned + * from GNUNET_TESTBED_service_connect() + * @return service handle to return in 'op_result', NULL on error + */ +static void * +statistics_connect_adapter (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + return GNUNET_STATISTICS_create ("<driver>", + cfg); +} + + +/** + * Adapter function called to destroy a connection to + * statistics service. + * + * @param cls closure + * @param op_result service handle returned from the connect adapter + */ +static void +statistics_disconnect_adapter (void *cls, + void *op_result) +{ + GNUNET_STATISTICS_destroy (op_result, GNUNET_NO); } @@ -184,11 +237,16 @@ get_done (void *cls, int success) * Function that gathers stats from all daemons. */ static void -stat_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +stat_run (void *cls, + struct GNUNET_TESTBED_Operation *op, + void *ca_result, + const char *emsg) { struct StatMaster *sm = cls; - if (stats[sm->value].name != NULL) + sm->stat = ca_result; + GNUNET_assert (NULL != sm->stat); + if (NULL != stats[sm->value].name) { GNUNET_STATISTICS_get (sm->stat, #if 0 @@ -200,20 +258,23 @@ stat_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) sm); return; } - GNUNET_STATISTICS_destroy (sm->stat, GNUNET_NO); + GNUNET_TESTBED_operation_done (sm->op); sm->value = 0; sm->daemon++; - if (sm->daemon == NUM_DAEMONS) + if (NUM_DAEMONS == sm->daemon) { GNUNET_free (sm); - GNUNET_SCHEDULER_add_now (&do_stop, NULL); + cleanup (); return; } - sm->stat = - GNUNET_STATISTICS_create ("<driver>", - GNUNET_FS_TEST_get_configuration (daemons, - sm->daemon)); - GNUNET_SCHEDULER_add_now (&stat_run, sm); + sm->op = + GNUNET_TESTBED_service_connect (NULL, + daemons[sm->daemon], + "statistics", + &stat_run, sm, + &statistics_connect_adapter, + &statistics_disconnect_adapter, + NULL); } @@ -226,53 +287,56 @@ do_report (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) char *fancy; struct StatMaster *sm; - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) - { - del = GNUNET_TIME_absolute_get_duration (start_time); - if (del.rel_value == 0) - del.rel_value = 1; - fancy = - GNUNET_STRINGS_byte_size_fancy (((unsigned long long) FILESIZE) * - 1000LL / del.rel_value); - FPRINTF (stderr, "Download speed of type `%s' was %s/s\n", type, fancy); - GNUNET_free (fancy); - if (NUM_DAEMONS != ++download_counter) - return; /* more downloads to come */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Finished all downloads, shutting down\n", - (unsigned long long) FILESIZE); - sm = GNUNET_malloc (sizeof (struct StatMaster)); - sm->stat = - GNUNET_STATISTICS_create ("<driver>", - GNUNET_FS_TEST_get_configuration (daemons, - sm->daemon)); - GNUNET_SCHEDULER_add_now (&stat_run, sm); - } - else + if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Timeout during download for type `%s', shutting down with error\n", type); ok = 1; - GNUNET_SCHEDULER_add_now (&do_stop, NULL); + cleanup (); + return; } + del = GNUNET_TIME_absolute_get_duration (start_time); + if (del.rel_value == 0) + del.rel_value = 1; + fancy = + GNUNET_STRINGS_byte_size_fancy (((unsigned long long) FILESIZE) * + 1000LL / del.rel_value); + FPRINTF (stderr, "Download speed of type `%s' was %s/s\n", type, fancy); + GNUNET_free (fancy); + if (NUM_DAEMONS != ++download_counter) + return; /* more downloads to come */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Finished all downloads, getting statistics\n"); + sm = GNUNET_malloc (sizeof (struct StatMaster)); + sm->op = + GNUNET_TESTBED_service_connect (NULL, + daemons[sm->daemon], + "statistics", + &stat_run, sm, + &statistics_connect_adapter, + &statistics_disconnect_adapter, + NULL); } static void -do_downloads (void *cls, const struct GNUNET_FS_Uri *u2) +do_downloads (void *cls, const struct GNUNET_FS_Uri *u2, + const char *fn) { int anonymity; unsigned int i; if (NULL == u2) { - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); + cleanup (); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Timeout during upload attempt, shutting down with error\n"); ok = 1; return; } + if (NULL != fn) + fn2 = GNUNET_strdup (fn); uri2 = GNUNET_FS_uri_dup (u2); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Downloading %llu bytes\n", (unsigned long long) FILESIZE); @@ -298,19 +362,23 @@ do_downloads (void *cls, const struct GNUNET_FS_Uri *u2) static void -do_publish2 (void *cls, const struct GNUNET_FS_Uri *u1) +do_publish2 (void *cls, + const struct GNUNET_FS_Uri *u1, + const char *fn) { int do_index; int anonymity; if (NULL == u1) { - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); + cleanup (); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Timeout during upload attempt, shutting down with error\n"); ok = 1; return; } + if (NULL != fn) + fn1 = GNUNET_strdup (fn); uri1 = GNUNET_FS_uri_dup (u1); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing %llu bytes\n", (unsigned long long) FILESIZE); @@ -328,19 +396,26 @@ do_publish2 (void *cls, const struct GNUNET_FS_Uri *u1) NULL); } + static void -do_publish1 (void *cls, const char *emsg) +do_publish1 (void *cls, + struct GNUNET_TESTBED_Operation *op, + const char *emsg) { + unsigned int *coco = cls; int do_index; int anonymity; + GNUNET_TESTBED_operation_done (op); if (NULL != emsg) { - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); + cleanup (); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error trying to connect: %s\n", emsg); ok = 1; return; } + if (0 != (--(*coco))) + return; /* more connections to be created */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing %llu bytes\n", (unsigned long long) FILESIZE); if (NULL != strstr (progname, "index")) @@ -351,7 +426,6 @@ do_publish1 (void *cls, const char *emsg) anonymity = 0; else anonymity = 1; - GNUNET_FS_TEST_publish (daemons[NUM_DAEMONS - 1], TIMEOUT, anonymity, do_index, FILESIZE, SEED1, VERBOSE, &do_publish2, NULL); @@ -359,60 +433,41 @@ do_publish1 (void *cls, const char *emsg) static void -do_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +do_connect (void *cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers) { - struct GNUNET_TESTING_PeerGroup *pg; - - GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Daemons started, will now try to connect them\n"); - pg = GNUNET_FS_TEST_get_group (daemons); - GNUNET_TESTING_create_topology (pg, GNUNET_TESTING_TOPOLOGY_CLIQUE, - GNUNET_TESTING_TOPOLOGY_NONE, NULL); - GNUNET_TESTING_connect_topology (pg, GNUNET_TESTING_TOPOLOGY_CLIQUE, - GNUNET_TESTING_TOPOLOGY_OPTION_NONE, 0.0, - TIMEOUT, NUM_DAEMONS, &do_publish1, NULL); -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - GNUNET_FS_TEST_daemons_start ("fs_test_lib_data.conf", TIMEOUT, NUM_DAEMONS, - daemons, &do_connect, NULL); + static unsigned int coco; + unsigned int i; + unsigned int j; + + GNUNET_assert (NUM_DAEMONS == num_peers); + for (i=0;i<num_peers;i++) + daemons[i] = peers[i]; + for (i=0;i<NUM_DAEMONS;i++) + for (j=i+1;j<NUM_DAEMONS;j++) + { + coco++; + GNUNET_TESTBED_overlay_connect (NULL, + &do_publish1, + &coco, + peers[i], + peers[j]); + } } int main (int argc, char *argv[]) { - char *const argvx[] = { - "perf-gnunet-service-fs-p2p", - "-c", - "fs_test_lib_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; progname = argv[0]; - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); - GNUNET_log_setup ("perf_gnunet_service_fs_p2p_trust", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "perf-gnunet-service-fs-p2p-trust", "nohelp", options, - &run, NULL); + (void) GNUNET_TESTBED_test_run ("perf-gnunet-service-fs-p2p-respect", + "perf_gnunet_service_fs_p2p.conf", + NUM_DAEMONS, + 0, NULL, NULL, + &do_connect, NULL); GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); return ok; } -/* end of perf_gnunet_service_fs_p2p_trust.c */ +/* end of perf_gnunet_service_fs_p2p_respect.c */ diff --git a/src/fs/plugin_block_fs.c b/src/fs/plugin_block_fs.c index 9b73f24..8e90589 100644 --- a/src/fs/plugin_block_fs.c +++ b/src/fs/plugin_block_fs.c @@ -29,7 +29,6 @@ #include "block_fs.h" #include "gnunet_signatures.h" -#define DEBUG_FS_BLOCK GNUNET_EXTRA_LOGGING /** * Number of bits we set per entry in the bloomfilter. @@ -57,17 +56,17 @@ */ static enum GNUNET_BLOCK_EvaluationResult block_plugin_fs_evaluate (void *cls, enum GNUNET_BLOCK_Type type, - const GNUNET_HashCode * query, + const struct GNUNET_HashCode * query, struct GNUNET_CONTAINER_BloomFilter **bf, int32_t bf_mutator, const void *xquery, size_t xquery_size, const void *reply_block, size_t reply_block_size) { const struct SBlock *sb; - GNUNET_HashCode chash; - GNUNET_HashCode mhash; - const GNUNET_HashCode *nsid; - GNUNET_HashCode sh; + struct GNUNET_HashCode chash; + struct GNUNET_HashCode mhash; + const struct GNUNET_HashCode *nsid; + struct GNUNET_HashCode sh; switch (type) { @@ -107,7 +106,7 @@ block_plugin_fs_evaluate (void *cls, enum GNUNET_BLOCK_Type type, } return GNUNET_BLOCK_EVALUATION_OK_MORE; case GNUNET_BLOCK_TYPE_FS_SBLOCK: - if (xquery_size != sizeof (GNUNET_HashCode)) + if (xquery_size != sizeof (struct GNUNET_HashCode)) { GNUNET_break_op (0); return GNUNET_BLOCK_EVALUATION_REQUEST_INVALID; @@ -124,13 +123,8 @@ block_plugin_fs_evaluate (void *cls, enum GNUNET_BLOCK_Type type, GNUNET_CRYPTO_hash (&sb->subspace, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &sh); - if (0 != memcmp (nsid, &sh, sizeof (GNUNET_HashCode))) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "block-fs", - _ - ("Reply mismatched in terms of namespace. Discarded.\n")); - return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; - } + if (0 != memcmp (nsid, &sh, sizeof (struct GNUNET_HashCode))) + return GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT; if (NULL != bf) { GNUNET_CRYPTO_hash (reply_block, reply_block_size, &chash); @@ -167,7 +161,7 @@ block_plugin_fs_evaluate (void *cls, enum GNUNET_BLOCK_Type type, static int block_plugin_fs_get_key (void *cls, enum GNUNET_BLOCK_Type type, const void *block, size_t block_size, - GNUNET_HashCode * key) + struct GNUNET_HashCode * key) { const struct KBlock *kb; const struct SBlock *sb; diff --git a/src/fs/test_fs_data.conf b/src/fs/test_fs_data.conf index f2b4e1e..40e85ad 100644 --- a/src/fs/test_fs_data.conf +++ b/src/fs/test_fs_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-data/ -DEFAULTCONFIG = test_fs_data.conf [fs] ACTIVEMIGRATION = NO diff --git a/src/fs/test_fs_defaults.conf b/src/fs/test_fs_defaults.conf index fcb888c..278e659 100644 --- a/src/fs/test_fs_defaults.conf +++ b/src/fs/test_fs_defaults.conf @@ -1,16 +1,15 @@ [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-lib/ -DEFAULTCONFIG = fs_test_lib_data.conf [gnunetd] HOSTKEY = $SERVICEHOME/.hostkey [resolver] -PORT = 43464 +PORT = 4364 HOSTNAME = localhost [transport] -PORT = 43465 +PORT = 4365 PLUGINS = tcp [nat] @@ -20,10 +19,11 @@ BEHIND_NAT = NO ALLOW_NAT = NO INTERNAL_ADDRESS = 127.0.0.1 EXTERNAL_ADDRESS = 127.0.0.1 -USE_LOCALADDR = NO +USE_LOCALADDR = YES +RETURN_LOCAL_ADDRESSES = YES [arm] -PORT = 43466 +PORT = 4366 HOSTNAME = localhost DEFAULTSERVICES = fs @@ -31,15 +31,15 @@ DEFAULTSERVICES = fs QUOTA = 100 MB [statistics] -PORT = 43467 +PORT = 4367 HOSTNAME = localhost [transport-tcp] BINDTO = 127.0.0.1 -PORT = 43468 +PORT = 4368 [peerinfo] -PORT = 43469 +PORT = 4369 HOSTNAME = localhost [ats] @@ -47,11 +47,11 @@ WAN_QUOTA_IN = 65536 WAN_QUOTA_OUT = 65536 [core] -PORT = 43470 +PORT = 4370 HOSTNAME = localhost [fs] -PORT = 43471 +PORT = 4371 HOSTNAME = localhost CONTENT_CACHING = YES CONTENT_PUSHING = YES @@ -59,15 +59,14 @@ DELAY = YES [testing] WEAKRANDOM = YES -HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat + +[testing_old] +HOSTKEYSFILE = ${DATADIR}/testing_hostkeys.dat [dhtcache] QUOTA=65536 DATABASE=sqlite -[mesh] -AUTOSTART = NO - [dns] AUTOSTART = NO @@ -88,3 +87,6 @@ AUTOSTART = NO [namestore] AUTOSTART = NO + +[consensus] +AUTOSTART = NO diff --git a/src/fs/test_fs_directory.c b/src/fs/test_fs_directory.c index 96ad29c..95225d7 100644 --- a/src/fs/test_fs_directory.c +++ b/src/fs/test_fs_directory.c @@ -79,7 +79,7 @@ testDirectory (unsigned int i) char txt[128]; int ret = 0; struct GNUNET_TIME_Absolute start; - char *s; + const char *s; cls.max = i; uris = GNUNET_malloc (sizeof (struct GNUNET_FS_Uri *) * i); @@ -130,11 +130,11 @@ testDirectory (unsigned int i) GNUNET_FS_directory_builder_add (db, uris[p], mds[p], NULL); GNUNET_FS_directory_builder_finish (db, &dlen, (void **) &data); s = GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration - (start)); + (start), + GNUNET_YES); FPRINTF (stdout, "Creating directory with %u entires and total size %llu took %s\n", i, (unsigned long long) dlen, s); - GNUNET_free (s); if (i < 100) { cls.pos = 0; diff --git a/src/fs/test_fs_download.c b/src/fs/test_fs_download.c index 2781974..a62cf23 100644 --- a/src/fs/test_fs_download.c +++ b/src/fs/test_fs_download.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2004, 2005, 2006, 2008, 2009, 2011 Christian Grothoff (and other contributing authors) + (C) 2004, 2005, 2006, 2008, 2009, 2011, 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 @@ -26,14 +26,10 @@ #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" #include "gnunet_fs_service.h" +#include "gnunet_testing_lib.h" #include <gauger.h> -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES - /** * File-size we use for testing. */ @@ -49,15 +45,9 @@ */ #define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; +static unsigned int anonymity_level; -static struct PeerContext p1; +static int indexed; static struct GNUNET_TIME_Absolute start; @@ -71,17 +61,20 @@ static GNUNET_SCHEDULER_TaskIdentifier timeout_kill; static char *fn; +static char *fn1; + static int err; + static void timeout_kill_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - if (download != NULL) + if (NULL != download) { GNUNET_FS_download_stop (download, GNUNET_YES); download = NULL; } - else if (publish != NULL) + else if (NULL != publish) { GNUNET_FS_publish_stop (publish); publish = NULL; @@ -91,16 +84,18 @@ timeout_kill_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) err = 1; } + static void abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - if (publish != NULL) + if (NULL != publish) { GNUNET_FS_publish_stop (publish); publish = NULL; } } + static void stop_fs_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -108,12 +103,13 @@ 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) { uint64_t size; - if (download != NULL) + if (NULL != download) { GNUNET_FS_download_stop (download, GNUNET_YES); download = NULL; @@ -135,43 +131,51 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) switch (event->status) { case GNUNET_FS_STATUS_PUBLISH_PROGRESS: -#if VERBOSE - printf ("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); -#endif + 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: - printf ("Publishing complete, %llu kb/s.\n", - (unsigned long long) (FILESIZE * 1000LL / - (1 + - GNUNET_TIME_absolute_get_duration - (start).rel_value) / 1024LL)); - GAUGER ("FS", "Publishing speed (insertion)", - (unsigned long long) (FILESIZE * 1000LL / - (1 + - GNUNET_TIME_absolute_get_duration - (start).rel_value) / 1024LL), "kb/s"); + fprintf (stdout, + "Publishing complete, %llu kb/s.\n", + (unsigned long long) (FILESIZE * 1000LL / + (1 + + GNUNET_TIME_absolute_get_duration + (start).rel_value) / 1024LL)); + GAUGER ("FS", + (GNUNET_YES == indexed) + ? "Publishing speed (indexing)" + : "Publishing speed (insertion)", + (unsigned long long) (FILESIZE * 1000LL / + (1 + + GNUNET_TIME_absolute_get_duration + (start).rel_value) / 1024LL), "kb/s"); fn = GNUNET_DISK_mktemp ("gnunet-download-test-dst"); start = GNUNET_TIME_absolute_get (); download = GNUNET_FS_download_start (fs, event->value.publish.specifics. completed.chk_uri, NULL, fn, NULL, 0, - FILESIZE, 1, GNUNET_FS_DOWNLOAD_OPTION_NONE, + FILESIZE, anonymity_level, + GNUNET_FS_DOWNLOAD_OPTION_NONE, "download", NULL); GNUNET_assert (download != NULL); break; case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: - printf ("Download complete, %llu kb/s.\n", - (unsigned long long) (FILESIZE * 1000LL / - (1 + - GNUNET_TIME_absolute_get_duration - (start).rel_value) / 1024LL)); - GAUGER ("FS", "Local download speed (inserted)", + fprintf (stdout, + "Download complete, %llu kb/s.\n", + (unsigned long long) (FILESIZE * 1000LL / + (1 + + GNUNET_TIME_absolute_get_duration + (start).rel_value) / 1024LL)); + GAUGER ("FS", + (GNUNET_YES == indexed) + ? "Local download speed (indexed)" + : "Local download speed (inserted)", (unsigned long long) (FILESIZE * 1000LL / (1 + GNUNET_TIME_absolute_get_duration @@ -180,14 +184,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) break; case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: GNUNET_assert (download == event->value.download.dc); -#if VERBOSE - printf ("Download is progressing (%llu/%llu at level %u off %llu)...\n", - (unsigned long long) event->value.download.completed, - (unsigned long long) event->value.download.size, - event->value.download.specifics.progress.depth, - (unsigned long long) event->value.download.specifics. - progress.offset); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Download is progressing (%llu/%llu at level %u off %llu)...\n", + (unsigned long long) event->value.download.completed, + (unsigned long long) event->value.download.size, + event->value.download.specifics.progress.depth, + (unsigned long long) event->value.download.specifics. + progress.offset); break; case GNUNET_FS_STATUS_PUBLISH_ERROR: FPRINTF (stderr, "Error publishing file: %s\n", @@ -240,46 +243,11 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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", -#if VERBOSE - "-L", "DEBUG", -#endif - "-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) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { + const char *binary_name = cls; const char *keywords[] = { "down_foo", "down_bar", @@ -291,8 +259,14 @@ run (void *cls, char *const *args, const char *cfgfile, size_t i; struct GNUNET_FS_BlockOptions bo; - setup_peer (&p1, "test_fs_download_data.conf"); - fs = GNUNET_FS_start (cfg, "test-fs-download", &progress_cb, NULL, + if (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (cfg, + "download-test", + "USE_STREAM")) + anonymity_level = 0; + else + anonymity_level = 1; + fs = GNUNET_FS_start (cfg, binary_name, &progress_cb, NULL, GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); buf = GNUNET_malloc (FILESIZE); @@ -301,12 +275,34 @@ run (void *cls, char *const *args, const char *cfgfile, 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.anonymity_level = anonymity_level; 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); + + if (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (cfg, + "download-test", + "USE_INDEX")) + { + fn1 = GNUNET_DISK_mktemp ("gnunet-download-indexed-test"); + GNUNET_assert (FILESIZE == + GNUNET_DISK_fn_write (fn1, buf, FILESIZE, + GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE)); + GNUNET_free (buf); + fi = GNUNET_FS_file_information_create_from_file (fs, "publish-context", fn1, + kuri, meta, GNUNET_YES, + &bo); + indexed = GNUNET_YES; + } + else + { + fi = GNUNET_FS_file_information_create_from_data (fs, "publish-context", + FILESIZE, buf, kuri, meta, + GNUNET_NO, &bo); + /* note: buf will be free'd as part of 'fi' now */ + indexed = GNUNET_NO; + } GNUNET_FS_uri_destroy (kuri); GNUNET_CONTAINER_meta_data_destroy (meta); GNUNET_assert (NULL != fi); @@ -323,30 +319,30 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-download", - "-c", - "test_fs_download_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; + const char *binary_name; + const char *config_name; - GNUNET_log_setup ("test_fs_download", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-download", "nohelp", options, &run, NULL); - stop_arm (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-download/"); + binary_name = "test-fs-download"; + config_name = "test_fs_download_data.conf"; + if (NULL != strstr (argv[0], "indexed")) + { + binary_name = "test-fs-download-indexed"; + config_name = "test_fs_download_indexed.conf"; + } + if (NULL != strstr (argv[0], "stream")) + { + binary_name = "test-fs-download-stream"; + config_name = "test_fs_download_stream.conf"; + } + if (0 != GNUNET_TESTING_peer_run (binary_name, + config_name, + &run, (void *) binary_name)) + return 1; + if (NULL != fn1) + { + UNLINK (fn1); + GNUNET_free (fn1); + } return err; } diff --git a/src/fs/test_fs_download_data.conf b/src/fs/test_fs_download_data.conf index 25aad51..694926a 100644 --- a/src/fs/test_fs_download_data.conf +++ b/src/fs/test_fs_download_data.conf @@ -1,5 +1,10 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-download/ -DEFAULTCONFIG = test_fs_download_data.conf +[download-test] +# set to 'YES' to test non-anonymous download +USE_STREAM = NO + +# set to 'YES' to use indexing +USE_INDEX = NO
\ No newline at end of file diff --git a/src/fs/test_fs_download_indexed.c b/src/fs/test_fs_download_indexed.c deleted file mode 100644 index d16aa97..0000000 --- a/src/fs/test_fs_download_indexed.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2004, 2005, 2006, 2008, 2009, 2011 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_download_indexed.c - * @brief simple testcase for downloading of indexed file - * @author Christian Grothoff - */ - -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" -#include "gnunet_fs_service.h" -#include <gauger.h> - -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES - -/** - * File-size we use for testing. - */ -#define FILESIZE (1024 * 1024 * 2) - -/** - * How long until we give up on transmitting the message? - */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) - -/** - * 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; -#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_DownloadContext *download; - -static struct GNUNET_FS_PublishContext *publish; - -static GNUNET_SCHEDULER_TaskIdentifier timeout_kill; - -static char *fn; - -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); - download = NULL; - } - else if (publish != NULL) - { - GNUNET_FS_publish_stop (publish); - publish = NULL; - } - timeout_kill = GNUNET_SCHEDULER_NO_TASK; - err = 1; -} - -static void -abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - if (publish != NULL) - { - GNUNET_FS_publish_stop (publish); - publish = NULL; - } -} - - -static void -stop_fs_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_FS_stop (fs); - fs = NULL; -} - - -static void -abort_download_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - uint64_t size; - - if (download != NULL) - { - GNUNET_FS_download_stop (download, GNUNET_YES); - download = NULL; - } - 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); - fn = NULL; - GNUNET_SCHEDULER_cancel (timeout_kill); - timeout_kill = GNUNET_SCHEDULER_NO_TASK; -} - - -static void * -progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) -{ - - switch (event->status) - { - case GNUNET_FS_STATUS_PUBLISH_PROGRESS: -#if VERBOSE - printf ("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); -#endif - break; - case GNUNET_FS_STATUS_PUBLISH_COMPLETED: - printf ("Publishing complete, %llu kbps.\n", - (unsigned long long) (FILESIZE * 1000LL / - (1 + - GNUNET_TIME_absolute_get_duration - (start).rel_value) / 1024LL)); - GAUGER ("FS", "Publishing speed (indexing)", - (unsigned long long) (FILESIZE * 1000LL / - (1 + - GNUNET_TIME_absolute_get_duration - (start).rel_value) / 1024LL), "kb/s"); - fn = GNUNET_DISK_mktemp ("gnunet-download-test-dst"); - start = GNUNET_TIME_absolute_get (); - download = - GNUNET_FS_download_start (fs, - event->value.publish.specifics. - completed.chk_uri, NULL, fn, NULL, 0, - FILESIZE, 1, GNUNET_FS_DOWNLOAD_OPTION_NONE, - "download", NULL); - GNUNET_assert (download != NULL); - break; - case GNUNET_FS_STATUS_DOWNLOAD_COMPLETED: - printf ("Download complete, %llu kbps.\n", - (unsigned long long) (FILESIZE * 1000LL / - (1 + - GNUNET_TIME_absolute_get_duration - (start).rel_value) / 1024LL)); - GAUGER ("FS", "Local download speed (indexed)", - (unsigned long long) (FILESIZE * 1000LL / - (1 + - GNUNET_TIME_absolute_get_duration - (start).rel_value) / 1024LL), "kb/s"); - GNUNET_SCHEDULER_add_now (&abort_download_task, NULL); - break; - case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: - GNUNET_assert (download == event->value.download.dc); -#if VERBOSE - printf ("Download is progressing (%llu/%llu at level %u off %llu)...\n", - (unsigned long long) event->value.download.completed, - (unsigned long long) event->value.download.size, - event->value.download.specifics.progress.depth, - (unsigned long long) event->value.download.specifics. - progress.offset); -#endif - 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_DOWNLOAD_ERROR: - FPRINTF (stderr, "Error downloading file: %s\n", - event->value.download.specifics.error.message); - GNUNET_SCHEDULER_add_now (&abort_download_task, NULL); - break; - case GNUNET_FS_STATUS_DOWNLOAD_ACTIVE: - case GNUNET_FS_STATUS_DOWNLOAD_INACTIVE: - 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_SCHEDULER_add_now (&stop_fs_task, NULL); - break; - case GNUNET_FS_STATUS_DOWNLOAD_START: - GNUNET_assert (0 == strcmp ("download", event->value.download.cctx)); - GNUNET_assert (NULL == event->value.download.pctx); - GNUNET_assert (NULL != event->value.download.uri); - GNUNET_assert (0 == strcmp (fn, event->value.download.filename)); - GNUNET_assert (FILESIZE == event->value.download.size); - GNUNET_assert (0 == event->value.download.completed); - GNUNET_assert (1 == event->value.download.anonymity); - break; - case GNUNET_FS_STATUS_DOWNLOAD_STOPPED: - GNUNET_assert (download == event->value.download.dc); - GNUNET_SCHEDULER_add_continuation (&abort_publish_task, NULL, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); - break; - default: - printf ("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_FileInformation *fi; - struct GNUNET_FS_BlockOptions bo; - size_t i; - - setup_peer (&p1, "test_fs_download_data.conf"); - fs = GNUNET_FS_start (cfg, "test-fs-download-indexed", &progress_cb, NULL, - GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); - GNUNET_assert (NULL != fs); - - fn1 = GNUNET_DISK_mktemp ("gnunet-download-indexed-test"); - buf = GNUNET_malloc (FILESIZE); - for (i = 0; i < FILESIZE; i++) - buf[i] = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 256); - GNUNET_assert (FILESIZE == - GNUNET_DISK_fn_write (fn1, buf, FILESIZE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE)); - GNUNET_free (buf); - 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_file (fs, "publish-context", fn1, - kuri, meta, GNUNET_YES, - &bo); - GNUNET_FS_uri_destroy (kuri); - GNUNET_CONTAINER_meta_data_destroy (meta); - GNUNET_assert (NULL != fi); - timeout_kill = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_kill_task, NULL); - 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-download-indexed", - "-c", - "test_fs_download_data.conf", - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_log_setup ("test_fs_download_indexed", - "WARNING", - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-download-indexed", "nohelp", options, &run, - NULL); - stop_arm (&p1); - if (fn1 != NULL) - { - GNUNET_DISK_directory_remove (fn1); - GNUNET_free (fn1); - } - if (fn != NULL) - { - GNUNET_DISK_directory_remove (fn); - GNUNET_free (fn); - } - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-download/"); - return err; -} - -/* end of test_fs_download_indexed.c */ diff --git a/src/fs/test_fs_download_indexed.conf b/src/fs/test_fs_download_indexed.conf new file mode 100644 index 0000000..61954c1 --- /dev/null +++ b/src/fs/test_fs_download_indexed.conf @@ -0,0 +1,10 @@ +@INLINE@ test_fs_defaults.conf +[PATHS] +SERVICEHOME = /tmp/gnunet-test-fs-download/ + +[download-test] +# set to 'YES' to test non-anonymous download +USE_STREAM = NO + +# set to 'YES' to use indexing +USE_INDEX = YES diff --git a/src/fs/test_fs_download_persistence.c b/src/fs/test_fs_download_persistence.c index ba776dd..d588387 100644 --- a/src/fs/test_fs_download_persistence.c +++ b/src/fs/test_fs_download_persistence.c @@ -23,16 +23,11 @@ * @brief simple testcase for persistence of simple download operation * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES - /** * File-size we use for testing. */ @@ -48,15 +43,6 @@ */ #define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; - -static struct PeerContext p1; static struct GNUNET_TIME_Absolute start; @@ -74,6 +60,7 @@ static char *fn; static int err; + static void timeout_kill_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -92,6 +79,7 @@ timeout_kill_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) err = 1; } + static void abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -166,14 +154,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) switch (event->status) { case GNUNET_FS_STATUS_PUBLISH_PROGRESS: -#if VERBOSE - printf ("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); -#endif + 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: printf ("Publishing complete, %llu kbps.\n", @@ -201,14 +188,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) case GNUNET_FS_STATUS_DOWNLOAD_PROGRESS: consider_restart (event->status); GNUNET_assert (download == event->value.download.dc); -#if VERBOSE - printf ("Download is progressing (%llu/%llu at level %u off %llu)...\n", - (unsigned long long) event->value.download.completed, - (unsigned long long) event->value.download.size, - event->value.download.specifics.progress.depth, - (unsigned long long) event->value.download.specifics. - progress.offset); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Download is progressing (%llu/%llu at level %u off %llu)...\n", + (unsigned long long) event->value.download.completed, + (unsigned long long) event->value.download.size, + event->value.download.specifics.progress.depth, + (unsigned long long) event->value.download.specifics. + progress.offset); break; case GNUNET_FS_STATUS_PUBLISH_ERROR: FPRINTF (stderr, "Error publishing file: %s\n", @@ -290,45 +276,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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", -#if VERBOSE - "-L", "DEBUG", -#endif - "-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 *c) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", @@ -342,7 +292,6 @@ run (void *cls, char *const *args, const char *cfgfile, struct GNUNET_FS_BlockOptions bo; cfg = c; - setup_peer (&p1, "test_fs_download_data.conf"); fs = GNUNET_FS_start (cfg, "test-fs-download-persistence", &progress_cb, NULL, GNUNET_FS_FLAGS_PERSISTENCE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); @@ -374,31 +323,10 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-download-persistence", - "-c", - "test_fs_download_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - GNUNET_log_setup ("test_fs_download_persistence", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-download/"); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-download-persistence", "nohelp", options, &run, - NULL); - stop_arm (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-download/"); + if (0 != GNUNET_TESTING_peer_run ("test-fs-download-persistence", + "test_fs_download_data.conf", + &run, NULL)) + return 1; return err; } diff --git a/src/fs/test_fs_download_stream.conf b/src/fs/test_fs_download_stream.conf new file mode 100644 index 0000000..3ee0b41 --- /dev/null +++ b/src/fs/test_fs_download_stream.conf @@ -0,0 +1,10 @@ +@INLINE@ test_fs_defaults.conf +[PATHS] +SERVICEHOME = /tmp/gnunet-test-fs-download/ + +[download-test] +# set to 'YES' to test non-anonymous download +USE_STREAM = NO + +# set to 'YES' to use indexing +USE_INDEX = NO diff --git a/src/fs/test_fs_file_information.c b/src/fs/test_fs_file_information.c index fb7de7d..cc79c80 100644 --- a/src/fs/test_fs_file_information.c +++ b/src/fs/test_fs_file_information.c @@ -31,12 +31,10 @@ * - other API functions may not yet be tested (such as * filedata-from-callback) */ - #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO /** * File-size we use for testing. @@ -137,9 +135,6 @@ run (void *cls, char *const *args, const char *cfgfile, } - - - int main (int argc, char *argv[]) { @@ -147,9 +142,6 @@ main (int argc, char *argv[]) "test-fs-file_information", "-c", "test_fs_file_information_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif NULL }; struct GNUNET_GETOPT_CommandLineOption options[] = { @@ -157,11 +149,7 @@ main (int argc, char *argv[]) }; GNUNET_log_setup ("test_fs_file_information", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, "test-fs-file_information", "nohelp", options, &run, diff --git a/src/fs/test_fs_file_information_data.conf b/src/fs/test_fs_file_information_data.conf index 09cedf8..ea43807 100644 --- a/src/fs/test_fs_file_information_data.conf +++ b/src/fs/test_fs_file_information_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-file-information/ -DEFAULTCONFIG = test_fs_file_information_data.conf [transport] PLUGINS = diff --git a/src/fs/test_fs_getopt.c b/src/fs/test_fs_getopt.c index 571346f..7551202 100644 --- a/src/fs/test_fs_getopt.c +++ b/src/fs/test_fs_getopt.c @@ -25,15 +25,12 @@ #include "platform.h" #include "gnunet_fs_service.h" + int main (int argc, char *argv[]) { - GNUNET_log_setup ("test_fs_directory", -#if VERBOSE - "DEBUG", -#else + GNUNET_log_setup ("test_fs_getopt", "WARNING", -#endif NULL); FPRINTF (stderr, "%s", "WARNING: testcase not yet written.\n"); return 0; /* testcase passed */ diff --git a/src/fs/test_fs_list_indexed.c b/src/fs/test_fs_list_indexed.c index d046a20..91dad7c 100644 --- a/src/fs/test_fs_list_indexed.c +++ b/src/fs/test_fs_list_indexed.c @@ -27,16 +27,11 @@ * TODO: * - actually call list_indexed API! */ - #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES - /** * File-size we use for testing. */ @@ -52,15 +47,6 @@ */ #define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; - -static struct PeerContext p1; static struct GNUNET_TIME_Absolute start; @@ -74,6 +60,7 @@ static char *fn2; static int err; + static void abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -120,14 +107,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) case GNUNET_FS_STATUS_PUBLISH_PROGRESS: ret = event->value.publish.cctx; GNUNET_assert (publish == event->value.publish.pc); -#if VERBOSE - printf ("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); -#endif + 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_ERROR: ret = event->value.publish.cctx; @@ -183,45 +169,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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", -#if VERBOSE - "-L", "DEBUG", -#endif - "-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) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", @@ -236,7 +186,6 @@ run (void *cls, char *const *args, const char *cfgfile, size_t i; struct GNUNET_FS_BlockOptions bo; - setup_peer (&p1, "test_fs_list_indexed_data.conf"); fs = GNUNET_FS_start (cfg, "test-fs-list_indexed", &progress_cb, NULL, GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); @@ -298,41 +247,11 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-list_indexed", - "-c", - "test_fs_list_indexed_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_log_setup ("test_fs_list_indexed", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-list_indexed", "nohelp", options, &run, NULL); - stop_arm (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-list-indexed/"); - if (fn1 != NULL) - { - GNUNET_DISK_directory_remove (fn1); - GNUNET_free (fn1); - } - if (fn2 != NULL) - { - GNUNET_DISK_directory_remove (fn2); - GNUNET_free (fn2); - } - return err; + if (0 != GNUNET_TESTING_peer_run ("test-fs-list-indexed", + "test_fs_list_indexed_data.conf", + &run, NULL)) + return 1; + return 0; } /* end of test_fs_list_indexed.c */ diff --git a/src/fs/test_fs_list_indexed_data.conf b/src/fs/test_fs_list_indexed_data.conf index 704ba4d..99d4466 100644 --- a/src/fs/test_fs_list_indexed_data.conf +++ b/src/fs/test_fs_list_indexed_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-list-indexed/ -DEFAULTCONFIG = test_fs_list_indexed_data.conf [transport] PLUGINS = diff --git a/src/fs/test_fs_namespace.c b/src/fs/test_fs_namespace.c index 78af1f1..e4ac493 100644 --- a/src/fs/test_fs_namespace.c +++ b/src/fs/test_fs_namespace.c @@ -25,16 +25,11 @@ */ #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO -#define START_ARM GNUNET_YES - -static struct PeerContext p1; - -static GNUNET_HashCode nsid; +static struct GNUNET_HashCode nsid; static struct GNUNET_FS_Uri *sks_expect_uri; @@ -52,48 +47,6 @@ static int update_started; static int err; -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; - - -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 abort_ksk_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) @@ -143,7 +96,6 @@ do_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } - static void * progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) { @@ -314,7 +266,7 @@ adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) static void -ns_iterator (void *cls, const char *name, const GNUNET_HashCode * id) +ns_iterator (void *cls, const char *name, const struct GNUNET_HashCode * id) { int *ok = cls; @@ -365,10 +317,10 @@ testNamespace () static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { - setup_peer (&p1, "test_fs_namespace_data.conf"); fs = GNUNET_FS_start (cfg, "test-fs-namespace", &progress_cb, NULL, GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); testNamespace (); @@ -378,28 +330,10 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-namespace", - "-c", - "test_fs_namespace_data.conf", - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_log_setup ("test_fs_namespace", - "WARNING", - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-namespace", "nohelp", options, &run, NULL); - stop_arm (&p1); - if (GNUNET_YES != update_started) - { - FPRINTF (stderr, "%s", "Update search never started!\n"); - err = 1; - } - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-namespace/"); + if (0 != GNUNET_TESTING_peer_run ("test-fs-namespace", + "test_fs_namespace_data.conf", + &run, NULL)) + return 1; return err; } diff --git a/src/fs/test_fs_namespace_data.conf b/src/fs/test_fs_namespace_data.conf index 3cdd241..625eb2d 100644 --- a/src/fs/test_fs_namespace_data.conf +++ b/src/fs/test_fs_namespace_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-namespace/ -DEFAULTCONFIG = test_fs_namespace_data.conf [transport] PLUGINS = diff --git a/src/fs/test_fs_namespace_list_updateable.c b/src/fs/test_fs_namespace_list_updateable.c index 2cec67d..dc17ce4 100644 --- a/src/fs/test_fs_namespace_list_updateable.c +++ b/src/fs/test_fs_namespace_list_updateable.c @@ -25,14 +25,9 @@ */ #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES - -static struct PeerContext p1; static struct GNUNET_FS_Handle *fs; @@ -49,15 +44,6 @@ static struct GNUNET_FS_Uri *uri_next; static struct GNUNET_FS_BlockOptions bo; -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; - - static void * progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) { @@ -66,38 +52,8 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) static void -setup_peer (struct PeerContext *p, const char *cfgname) +do_shutdown () { - 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", -#if VERBOSE - "-L", "DEBUG", -#endif - "-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 if (uri_this != NULL) GNUNET_FS_uri_destroy (uri_this); if (uri_next != NULL) @@ -106,11 +62,9 @@ stop_arm (struct PeerContext *p) GNUNET_FS_namespace_delete (ns, GNUNET_NO); if (meta != NULL) GNUNET_CONTAINER_meta_data_destroy (meta); - GNUNET_CONFIGURATION_destroy (p->cfg); } - static void check_next (void *cls, const char *last_id, const struct GNUNET_FS_Uri *last_uri, @@ -143,7 +97,6 @@ sks_cont_next (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) GNUNET_assert (NULL == emsg); err += 2; GNUNET_FS_namespace_list_updateable (ns, NULL, &check_this_next, NULL); - } @@ -162,7 +115,6 @@ check_this (void *cls, const char *last_id, static void sks_cont_this (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) { - GNUNET_assert (NULL == emsg); err = 1; GNUNET_FS_namespace_list_updateable (ns, NULL, &check_this, NULL); @@ -172,11 +124,9 @@ sks_cont_this (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) } - static void testNamespace () { - ns = GNUNET_FS_namespace_create (fs, "testNamespace"); GNUNET_assert (NULL != ns); bo.content_priority = 1; @@ -200,10 +150,10 @@ testNamespace () static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { - setup_peer (&p1, "test_fs_namespace_data.conf"); fs = GNUNET_FS_start (cfg, "test-fs-namespace", &progress_cb, NULL, GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); testNamespace (); @@ -213,30 +163,11 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-namespace", - "-c", - "test_fs_namespace_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_log_setup ("test_fs_namespace_list_updateable", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-namespace", "nohelp", options, &run, NULL); - stop_arm (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-namespace/"); + if (0 != GNUNET_TESTING_peer_run ("test-fs-namespace-list-updateable", + "test_fs_namespace_data.conf", + &run, NULL)) + return 1; + do_shutdown (); return err; } diff --git a/src/fs/test_fs_publish.c b/src/fs/test_fs_publish.c index 1560f4e..e51d6e5 100644 --- a/src/fs/test_fs_publish.c +++ b/src/fs/test_fs_publish.c @@ -17,23 +17,17 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** * @file fs/test_fs_publish.c * @brief simple testcase for publish operation (indexing, listing * indexed, directory structure) * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES - /** * File-size we use for testing. */ @@ -49,15 +43,6 @@ */ #define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; - -static struct PeerContext p1; static struct GNUNET_TIME_Absolute start; @@ -71,6 +56,7 @@ static char *fn2; static int err; + static void abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -107,14 +93,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) case GNUNET_FS_STATUS_PUBLISH_PROGRESS: ret = event->value.publish.cctx; GNUNET_assert (publish == event->value.publish.pc); -#if VERBOSE - printf ("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); -#endif + 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_ERROR: ret = event->value.publish.cctx; @@ -168,45 +153,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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", -#if VERBOSE - "-L", "DEBUG", -#endif - "-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) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", @@ -221,7 +170,6 @@ run (void *cls, char *const *args, const char *cfgfile, size_t i; struct GNUNET_FS_BlockOptions bo; - setup_peer (&p1, "test_fs_publish_data.conf"); fs = GNUNET_FS_start (cfg, "test-fs-publish", &progress_cb, NULL, GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); @@ -283,40 +231,10 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-publish", - "-c", - "test_fs_publish_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_log_setup ("test_fs_publish", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-publish", "nohelp", options, &run, NULL); - stop_arm (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-publish/"); - if (fn1 != NULL) - { - GNUNET_DISK_directory_remove (fn1); - GNUNET_free (fn1); - } - if (fn2 != NULL) - { - GNUNET_DISK_directory_remove (fn2); - GNUNET_free (fn2); - } + if (0 != GNUNET_TESTING_peer_run ("test-fs-publish", + "test_fs_publish_data.conf", + &run, NULL)) + return 1; return err; } diff --git a/src/fs/test_fs_publish_data.conf b/src/fs/test_fs_publish_data.conf index 234f2b0..14e6919 100644 --- a/src/fs/test_fs_publish_data.conf +++ b/src/fs/test_fs_publish_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-publish/ -DEFAULTCONFIG = test_fs_publish_data.conf [transport] PLUGINS = diff --git a/src/fs/test_fs_publish_persistence.c b/src/fs/test_fs_publish_persistence.c index 7d3bc32..577831a 100644 --- a/src/fs/test_fs_publish_persistence.c +++ b/src/fs/test_fs_publish_persistence.c @@ -17,21 +17,16 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** * @file fs/test_fs_publish_persistence.c * @brief simple testcase for persistence of simple publish operation * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES /** * File-size we use for testing. @@ -48,15 +43,6 @@ */ #define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; - -static struct PeerContext p1; static struct GNUNET_TIME_Absolute start; @@ -76,6 +62,7 @@ static int err; static GNUNET_SCHEDULER_TaskIdentifier rtask; + static void abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -231,45 +218,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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", -#if VERBOSE - "-L", "DEBUG", -#endif - "-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 *c) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", @@ -285,7 +236,6 @@ run (void *cls, char *const *args, const char *cfgfile, struct GNUNET_FS_BlockOptions bo; cfg = c; - setup_peer (&p1, "test_fs_publish_data.conf"); fs = GNUNET_FS_start (cfg, "test-fs-publish-persistence", &progress_cb, NULL, GNUNET_FS_FLAGS_PERSISTENCE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); @@ -344,40 +294,10 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-publish-persistence", - "-c", - "test_fs_publish_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_log_setup ("test_fs_publish_persistence", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-publish", "nohelp", options, &run, NULL); - stop_arm (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-publish/"); - if (fn1 != NULL) - { - GNUNET_DISK_directory_remove (fn1); - GNUNET_free (fn1); - } - if (fn2 != NULL) - { - GNUNET_DISK_directory_remove (fn2); - GNUNET_free (fn2); - } + if (0 != GNUNET_TESTING_peer_run ("test-fs-publish-persistence", + "test_fs_publish_data.conf", + &run, NULL)) + return 1; return err; } diff --git a/src/fs/test_fs_search.c b/src/fs/test_fs_search.c index 04c5897..cf4a9cb 100644 --- a/src/fs/test_fs_search.c +++ b/src/fs/test_fs_search.c @@ -17,21 +17,16 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** * @file fs/test_fs_search.c * @brief simple testcase for simple publish + search operation * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES /** * File-size we use for testing. @@ -48,16 +43,6 @@ */ #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; @@ -96,14 +81,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) switch (event->status) { case GNUNET_FS_STATUS_PUBLISH_PROGRESS: -#if VERBOSE - printf ("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); -#endif + 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); @@ -115,9 +99,8 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) GNUNET_assert (search != NULL); break; case GNUNET_FS_STATUS_SEARCH_RESULT: -#if VERBOSE - printf ("Search complete.\n"); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Search complete.\n"); GNUNET_SCHEDULER_add_continuation (&abort_search_task, NULL, GNUNET_SCHEDULER_REASON_PREREQ_DONE); break; @@ -169,42 +152,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", @@ -217,7 +167,6 @@ run (void *cls, char *const *args, const char *cfgfile, 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_NONE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); @@ -247,23 +196,10 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-search", - "-c", - "test_fs_search_data.conf", - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_log_setup ("test_fs_search", - "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/"); + if (0 != GNUNET_TESTING_peer_run ("test-fs-search", + "test_fs_search_data.conf", + &run, NULL)) + return 1; return 0; } diff --git a/src/fs/test_fs_search_data.conf b/src/fs/test_fs_search_data.conf index ea5e4c5..812a7bf 100644 --- a/src/fs/test_fs_search_data.conf +++ b/src/fs/test_fs_search_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-search/ -DEFAULTCONFIG = test_fs_search_data.conf [transport] PLUGINS = diff --git a/src/fs/test_fs_search_persistence.c b/src/fs/test_fs_search_persistence.c index d18b50e..d66c5ec 100644 --- a/src/fs/test_fs_search_persistence.c +++ b/src/fs/test_fs_search_persistence.c @@ -17,21 +17,16 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** * @file fs/test_fs_search_persistence.c * @brief simple testcase for persistence of search operation * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES /** * File-size we use for testing. @@ -48,16 +43,6 @@ */ #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; @@ -69,6 +54,7 @@ static struct GNUNET_FS_PublishContext *publish; static const struct GNUNET_CONFIGURATION_Handle *cfg; + static void abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -99,8 +85,6 @@ restart_fs_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } - - /** * Consider scheduling the restart-task. * Only runs the restart task once per event @@ -135,14 +119,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) switch (event->status) { case GNUNET_FS_STATUS_PUBLISH_PROGRESS: -#if VERBOSE - printf ("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); -#endif + 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); @@ -163,9 +146,8 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) case GNUNET_FS_STATUS_SEARCH_RESULT: /* FIXME: consider_restart (event->status); cannot be tested with * search result since we exit here after the first one... */ -#if VERBOSE - printf ("Search complete.\n"); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Search complete.\n"); GNUNET_SCHEDULER_add_continuation (&abort_search_task, NULL, GNUNET_SCHEDULER_REASON_PREREQ_DONE); break; @@ -231,45 +213,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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", -#if VERBOSE - "-L", "DEBUG", -#endif - "-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 *c) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", @@ -283,7 +229,6 @@ run (void *cls, char *const *args, const char *cfgfile, struct GNUNET_FS_BlockOptions bo; cfg = c; - setup_peer (&p1, "test_fs_search_data.conf"); fs = GNUNET_FS_start (cfg, "test-fs-search-persistence", &progress_cb, NULL, GNUNET_FS_FLAGS_PERSISTENCE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); @@ -313,32 +258,10 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-search-persistence", - "-c", - "test_fs_search_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-search/"); - GNUNET_log_setup ("test_fs_search_persistence", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-search-persistence", "nohelp", options, &run, - NULL); - stop_arm (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-search/"); + if (0 != GNUNET_TESTING_peer_run ("test-fs-search-persistence", + "test_fs_search_data.conf", + &run, NULL)) + return 1; return 0; } diff --git a/src/fs/test_fs_search_probes.c b/src/fs/test_fs_search_probes.c index b816598..0b02532 100644 --- a/src/fs/test_fs_search_probes.c +++ b/src/fs/test_fs_search_probes.c @@ -25,10 +25,9 @@ */ #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define START_ARM GNUNET_YES /** * File-size we use for testing. @@ -45,16 +44,6 @@ */ #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; @@ -141,9 +130,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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); + if ( (0 < event->value.search.specifics.update.availability_rank) && + (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); @@ -166,42 +155,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", @@ -214,7 +170,6 @@ run (void *cls, char *const *args, const char *cfgfile, 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); @@ -245,23 +200,10 @@ run (void *cls, char *const *args, const char *cfgfile, 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/"); + if (0 != GNUNET_TESTING_peer_run ("test-fs-search-probes", + "test_fs_search_data.conf", + &run, NULL)) + return 1; return 0; } diff --git a/src/fs/test_fs_start_stop.c b/src/fs/test_fs_start_stop.c index 6bd698a..463274e 100644 --- a/src/fs/test_fs_start_stop.c +++ b/src/fs/test_fs_start_stop.c @@ -17,7 +17,6 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** * @file fs/test_fs_start_stop.c * @brief testcase for fs.c (start-stop only) @@ -26,23 +25,9 @@ #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES - -static struct PeerContext p1; - -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; - static void * progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) @@ -52,49 +37,12 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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", -#if VERBOSE - "-L", "DEBUG", -#endif - "-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) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { struct GNUNET_FS_Handle *fs; - setup_peer (&p1, "test_fs_data.conf"); fs = GNUNET_FS_start (cfg, "test-fs-start-stop", &progress_cb, NULL, GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); GNUNET_assert (NULL != fs); @@ -105,30 +53,10 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-start-stop", - "-c", - "test_fs_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_log_setup ("test_fs_start_stop", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-start-stop", "nohelp", options, &run, NULL); - stop_arm (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs/"); + if (0 != GNUNET_TESTING_peer_run ("test-fs-start-stop", + "test_fs_data.conf", + &run, NULL)) + return 1; return 0; } diff --git a/src/fs/test_fs_test_lib.c b/src/fs/test_fs_test_lib.c index 29d5fe4..2fe5a81 100644 --- a/src/fs/test_fs_test_lib.c +++ b/src/fs/test_fs_test_lib.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010 Christian Grothoff (and other contributing authors) + (C) 2010, 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 @@ -42,20 +42,16 @@ #define SEED 42 -static struct GNUNET_FS_TestDaemon *daemons[NUM_DAEMONS]; - -static struct GNUNET_FS_TEST_ConnectContext *cc; +static struct GNUNET_TESTBED_Peer *the_peers[NUM_DAEMONS]; static int ret; + static void do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - if (NULL != cc) - { - GNUNET_FS_TEST_daemons_connect_cancel (cc); - cc = NULL; - } + char *fn = cls; + if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) { GNUNET_break (0); @@ -66,90 +62,96 @@ do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Finished download, shutting down\n", (unsigned long long) FILESIZE); } - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); + if (NULL != fn) + { + GNUNET_DISK_directory_remove (fn); + GNUNET_free (fn); + } + GNUNET_SCHEDULER_shutdown (); } static void -do_download (void *cls, const struct GNUNET_FS_Uri *uri) +do_download (void *cls, const struct GNUNET_FS_Uri *uri, + const char *fn) { if (NULL == uri) { GNUNET_break (0); - GNUNET_SCHEDULER_add_now (&do_stop, NULL); + GNUNET_SCHEDULER_shutdown (); ret = 1; return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Downloading %llu bytes\n", (unsigned long long) FILESIZE); - GNUNET_FS_TEST_download (daemons[0], TIMEOUT, 1, SEED, uri, VERBOSE, &do_stop, - NULL); + GNUNET_FS_TEST_download (the_peers[0], TIMEOUT, 1, SEED, uri, VERBOSE, &do_stop, + (NULL == fn) ? NULL : GNUNET_strdup (fn)); } static void -do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +do_publish (void *cls, + struct GNUNET_TESTBED_Operation *op, + const char *emsg) { - cc = NULL; - if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) + GNUNET_TESTBED_operation_done (op); + if (NULL != emsg) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to connect peers: %s\n", emsg); GNUNET_break (0); ret = 1; - GNUNET_SCHEDULER_add_now (&do_stop, NULL); + GNUNET_SCHEDULER_shutdown (); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing %llu bytes\n", (unsigned long long) FILESIZE); - GNUNET_FS_TEST_publish (daemons[0], TIMEOUT, 1, GNUNET_NO, FILESIZE, SEED, + GNUNET_FS_TEST_publish (the_peers[0], TIMEOUT, 1, GNUNET_NO, FILESIZE, SEED, VERBOSE, &do_download, NULL); -} - -static void -do_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) - { - GNUNET_break (0); - ret = 1; - GNUNET_SCHEDULER_add_now (&do_stop, NULL); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Daemons started, will now try to connect them\n"); - cc = GNUNET_FS_TEST_daemons_connect (daemons[0], daemons[1], TIMEOUT, - &do_publish, NULL); } +/** + * Actual main function for the test. + * + * @param cls closure + * @param num_peers number of peers in 'peers' + * @param peers handle to peers run in the testbed + */ static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) +run (void *cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers) { - GNUNET_FS_TEST_daemons_start ("fs_test_lib_data.conf", TIMEOUT, NUM_DAEMONS, - daemons, &do_connect, NULL); + unsigned int i; + + GNUNET_assert (NUM_DAEMONS == num_peers); + for (i=0;i<num_peers;i++) + the_peers[i] = peers[i]; + GNUNET_TESTBED_overlay_connect (NULL, + &do_publish, + NULL, + peers[0], + peers[1]); } +/** + * Main function that initializes the testbed. + * + * @param argc ignored + * @param argv ignored + * @return 0 on success + */ int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-test-lib", - "-c", - "fs_test_lib_data.conf", - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); - GNUNET_log_setup ("test_fs_test_lib", - "WARNING", - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-test-lib", "nohelp", options, &run, NULL); + (void) GNUNET_TESTBED_test_run ("test_fs_test_lib", + "fs_test_lib_data.conf", + NUM_DAEMONS, + 0, NULL, NULL, + &run, NULL); GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); return ret; } diff --git a/src/fs/test_fs_unindex.c b/src/fs/test_fs_unindex.c index ee76bf9..6b89dca 100644 --- a/src/fs/test_fs_unindex.c +++ b/src/fs/test_fs_unindex.c @@ -23,15 +23,11 @@ * @brief simple testcase for simple publish + unindex operation * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" #include "gnunet_fs_service.h" +#include "gnunet_testing_lib.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES /** * File-size we use for testing. @@ -48,15 +44,6 @@ */ #define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; - -static struct PeerContext p1; static struct GNUNET_TIME_Absolute start; @@ -95,14 +82,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) switch (event->status) { case GNUNET_FS_STATUS_PUBLISH_PROGRESS: -#if VERBOSE - printf ("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); -#endif + 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: printf ("Publishing complete, %llu kbps.\n", @@ -125,14 +111,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) break; case GNUNET_FS_STATUS_UNINDEX_PROGRESS: GNUNET_assert (unindex == event->value.unindex.uc); -#if VERBOSE - printf ("Unindex is progressing (%llu/%llu at level %u off %llu)...\n", - (unsigned long long) event->value.unindex.completed, - (unsigned long long) event->value.unindex.size, - event->value.unindex.specifics.progress.depth, - (unsigned long long) event->value.unindex.specifics. - progress.offset); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Unindex is progressing (%llu/%llu at level %u off %llu)...\n", + (unsigned long long) event->value.unindex.completed, + (unsigned long long) event->value.unindex.size, + event->value.unindex.specifics.progress.depth, + (unsigned long long) event->value.unindex.specifics. + progress.offset); break; case GNUNET_FS_STATUS_PUBLISH_ERROR: FPRINTF (stderr, "Error publishing file: %s\n", @@ -182,45 +167,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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", -#if VERBOSE - "-L", "DEBUG", -#endif - "-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) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", @@ -233,7 +182,6 @@ run (void *cls, char *const *args, const char *cfgfile, size_t i; struct GNUNET_FS_BlockOptions bo; - setup_peer (&p1, "test_fs_unindex_data.conf"); fn = GNUNET_DISK_mktemp ("gnunet-unindex-test-dst"); fs = GNUNET_FS_start (cfg, "test-fs-unindex", &progress_cb, NULL, GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END); @@ -269,35 +217,10 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-unindex", - "-c", - "test_fs_unindex_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_log_setup ("test_fs_unindex", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-unindex", "nohelp", options, &run, NULL); - stop_arm (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-unindex/"); - if (NULL != fn) - { - GNUNET_DISK_directory_remove (fn); - GNUNET_free (fn); - } + if (0 != GNUNET_TESTING_peer_run ("test-fs-unindex", + "test_fs_unindex_data.conf", + &run, NULL)) + return 1; return 0; } diff --git a/src/fs/test_fs_unindex_data.conf b/src/fs/test_fs_unindex_data.conf index 977d6e7..fa28fbb 100644 --- a/src/fs/test_fs_unindex_data.conf +++ b/src/fs/test_fs_unindex_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-unindex/ -DEFAULTCONFIG = test_fs_unindex_data.conf [transport] PLUGINS = diff --git a/src/fs/test_fs_unindex_persistence.c b/src/fs/test_fs_unindex_persistence.c index c6b1062..3e2cd98 100644 --- a/src/fs/test_fs_unindex_persistence.c +++ b/src/fs/test_fs_unindex_persistence.c @@ -25,13 +25,9 @@ */ #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_arm_service.h" +#include "gnunet_testing_lib.h" #include "gnunet_fs_service.h" -#define VERBOSE GNUNET_NO - -#define START_ARM GNUNET_YES - /** * File-size we use for testing. */ @@ -47,15 +43,6 @@ */ #define LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15) -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; - -static struct PeerContext p1; static struct GNUNET_TIME_Absolute start; @@ -69,6 +56,7 @@ static char *fn; static const struct GNUNET_CONFIGURATION_Handle *cfg; + static void abort_publish_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { @@ -136,14 +124,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) switch (event->status) { case GNUNET_FS_STATUS_PUBLISH_PROGRESS: -#if VERBOSE - printf ("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); -#endif + 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: printf ("Publishing complete, %llu kbps.\n", @@ -167,14 +154,13 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) case GNUNET_FS_STATUS_UNINDEX_PROGRESS: consider_restart (event->status); GNUNET_assert (unindex == event->value.unindex.uc); -#if VERBOSE - printf ("Unindex is progressing (%llu/%llu at level %u off %llu)...\n", - (unsigned long long) event->value.unindex.completed, - (unsigned long long) event->value.unindex.size, - event->value.unindex.specifics.progress.depth, - (unsigned long long) event->value.unindex.specifics. - progress.offset); -#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Unindex is progressing (%llu/%llu at level %u off %llu)...\n", + (unsigned long long) event->value.unindex.completed, + (unsigned long long) event->value.unindex.size, + event->value.unindex.specifics.progress.depth, + (unsigned long long) event->value.unindex.specifics. + progress.offset); break; case GNUNET_FS_STATUS_PUBLISH_SUSPEND: if (event->value.publish.pc == publish) @@ -244,45 +230,9 @@ progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event) 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", -#if VERBOSE - "-L", "DEBUG", -#endif - "-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 *c) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_TESTING_Peer *peer) { const char *keywords[] = { "down_foo", @@ -296,7 +246,6 @@ run (void *cls, char *const *args, const char *cfgfile, struct GNUNET_FS_BlockOptions bo; cfg = c; - setup_peer (&p1, "test_fs_unindex_data.conf"); fn = GNUNET_DISK_mktemp ("gnunet-unindex-test-dst"); fs = GNUNET_FS_start (cfg, "test-fs-unindex-persistence", &progress_cb, NULL, GNUNET_FS_FLAGS_PERSISTENCE, GNUNET_FS_OPTIONS_END); @@ -332,35 +281,10 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-fs-unindex", - "-c", - "test_fs_unindex_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_log_setup ("test_fs_unindex_persistence", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-fs-unindex", "nohelp", options, &run, NULL); - stop_arm (&p1); - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-unindex/"); - if (NULL != fn) - { - GNUNET_DISK_directory_remove (fn); - GNUNET_free (fn); - } + if (0 != GNUNET_TESTING_peer_run ("test-fs-unindex-persistence", + "test_fs_unindex_data.conf", + &run, NULL)) + return 1; return 0; } diff --git a/src/fs/test_fs_uri.c b/src/fs/test_fs_uri.c index b7a58ec..9d6c4ab 100644 --- a/src/fs/test_fs_uri.c +++ b/src/fs/test_fs_uri.c @@ -17,19 +17,16 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** * @file fs/test_fs_uri.c * @brief Test for fs_uri.c * @author Christian Grothoff */ - #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_fs_service.h" #include "fs_api.h" -#define ABORT() { fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); return 1; } static int testKeyword () @@ -41,26 +38,26 @@ testKeyword () if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/ksk/++", &emsg))) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } GNUNET_free (emsg); ret = GNUNET_FS_uri_parse ("gnunet://fs/ksk/foo+bar", &emsg); if (ret == NULL) { GNUNET_free (emsg); - ABORT (); + GNUNET_assert (0); } if (!GNUNET_FS_uri_test_ksk (ret)) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } if ((2 != ret->data.ksk.keywordCount) || (0 != strcmp (" foo", ret->data.ksk.keywords[0])) || (0 != strcmp (" bar", ret->data.ksk.keywords[1]))) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } uri = GNUNET_FS_uri_to_string (ret); @@ -68,13 +65,14 @@ testKeyword () { GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); return 0; } + static int testLocation () { @@ -157,6 +155,7 @@ testLocation () return 0; } + static int testNamespace (int i) { @@ -170,7 +169,7 @@ testNamespace (int i) &emsg))) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } GNUNET_free (emsg); if (NULL != @@ -179,13 +178,13 @@ testNamespace (int i) ("gnunet://fs/sks/D1KJS9H2A82Q65VKQ0ML3RFU6U1D3V/test", &emsg))) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } GNUNET_free (emsg); if (NULL != (ret = GNUNET_FS_uri_parse ("gnunet://fs/sks/test", &emsg))) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } GNUNET_free (emsg); ret = @@ -195,17 +194,17 @@ testNamespace (int i) if (ret == NULL) { GNUNET_free (emsg); - ABORT (); + GNUNET_assert (0); } if (GNUNET_FS_uri_test_ksk (ret)) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } if (!GNUNET_FS_uri_test_sks (ret)) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } uri = GNUNET_FS_uri_to_string (ret); @@ -215,7 +214,7 @@ testNamespace (int i) { GNUNET_FS_uri_destroy (ret); GNUNET_free (uri); - ABORT (); + GNUNET_assert (0); } GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); @@ -236,7 +235,7 @@ testFile (int i) &emsg))) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } GNUNET_free (emsg); if (NULL != @@ -246,7 +245,7 @@ testFile (int i) &emsg))) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } GNUNET_free (emsg); if (NULL != @@ -256,7 +255,7 @@ testFile (int i) &emsg))) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } GNUNET_free (emsg); ret = @@ -266,22 +265,22 @@ testFile (int i) if (ret == NULL) { GNUNET_free (emsg); - ABORT (); + GNUNET_assert (0); } if (GNUNET_FS_uri_test_ksk (ret)) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } if (GNUNET_FS_uri_test_sks (ret)) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } if (GNUNET_ntohll (ret->data.chk.file_length) != 42) { GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } uri = GNUNET_FS_uri_to_string (ret); @@ -291,13 +290,14 @@ testFile (int i) { GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); - ABORT (); + GNUNET_assert (0); } GNUNET_free (uri); GNUNET_FS_uri_destroy (ret); return 0; } + int main (int argc, char *argv[]) { @@ -305,11 +305,7 @@ main (int argc, char *argv[]) int i; GNUNET_log_setup ("test_fs_uri", -#if VERBOSE - "DEBUG", -#else "WARNING", -#endif NULL); GNUNET_CRYPTO_random_disable_entropy_gathering (); failureCount += testKeyword (); diff --git a/src/fs/test_gnunet_fs_idx.py.in b/src/fs/test_gnunet_fs_idx.py.in index 6bb7d0d..c7858d9 100644..100755 --- a/src/fs/test_gnunet_fs_idx.py.in +++ b/src/fs/test_gnunet_fs_idx.py.in @@ -52,16 +52,17 @@ arm.communicate () try: pub = pexpect () - pub.spawn (None, [publish, '-c', 'test_gnunet_fs_idx_data.conf', '-m', "description:The GNU Public License", '-k', 'gpl', '../../COPYING'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - pub.expect ("stdout", re.compile (r"URI is `gnunet://fs/chk/PC0M19QMQC0BPSHR6BGA228PP6INER1D610MGEMOMEM87222FN8HVUO7PQGO0O9HD2GVLHF2N5IDHEQUNK6LKE428FPO96SKQEA486O\.PG7K85JGQ6N599MD5HEP3CHEVFPKQD9JB6NPSLVA3T1SKDS66CFI499VS6MGQ88B0QUAVT1282TCRD4GGFVUKDLGI8F0SPIANA3J2LG\.35147'\.\r?\n")) + + pub.spawn (None, [publish, '-c', 'test_gnunet_fs_idx_data.conf', '-m', "description:Test archive", '-k', 'tst', 'test_gnunet_fs_rec_data.tgz'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + pub.expect ("stdout", re.compile (r"URI is `gnunet://fs/chk/2VKHJMR74CB6GB1GFJNOO95BTINA2PEO25FL48GAS7SPBMA0GDEK5U74R1VIHK0LA6919QRS376BHQFDOE3OUP0JOU92K1NIRJMHFCO\.FPEBEAL6HCABM5LMFNNJOPPLKAF5TLUC86A11EIS1HLMIUBP8VEUTU7FT50OLF9ESKP7GTBUE7GDN392J2VKL6JKM1VT1KB4C7Q1U48\.17822'\.\r?\n")) down = pexpect () - down.spawn (None, [download, '-c', 'test_gnunet_fs_idx_data.conf', '-o', 'COPYING', 'gnunet://fs/chk/PC0M19QMQC0BPSHR6BGA228PP6INER1D610MGEMOMEM87222FN8HVUO7PQGO0O9HD2GVLHF2N5IDHEQUNK6LKE428FPO96SKQEA486O.PG7K85JGQ6N599MD5HEP3CHEVFPKQD9JB6NPSLVA3T1SKDS66CFI499VS6MGQ88B0QUAVT1282TCRD4GGFVUKDLGI8F0SPIANA3J2LG.35147'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - down.expect ("stdout", re.compile (r"Downloading `COPYING' done (.*).\r?\n")) - os.remove ("COPYING") + down.spawn (None, [download, '-c', 'test_gnunet_fs_idx_data.conf', '-o', 'test_gnunet_fs_rec_data.tar.gz', 'gnunet://fs/chk/2VKHJMR74CB6GB1GFJNOO95BTINA2PEO25FL48GAS7SPBMA0GDEK5U74R1VIHK0LA6919QRS376BHQFDOE3OUP0JOU92K1NIRJMHFCO.FPEBEAL6HCABM5LMFNNJOPPLKAF5TLUC86A11EIS1HLMIUBP8VEUTU7FT50OLF9ESKP7GTBUE7GDN392J2VKL6JKM1VT1KB4C7Q1U48.17822'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + down.expect ("stdout", re.compile (r"Downloading `test_gnunet_fs_rec_data.tar.gz' done (.*).\r?\n")) + os.remove ("test_gnunet_fs_rec_data.tar.gz") un = pexpect () - un.spawn (None, [unindex, '-c', 'test_gnunet_fs_idx_data.conf', '../../COPYING'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + un.spawn (None, [unindex, '-c', 'test_gnunet_fs_idx_data.conf', 'test_gnunet_fs_rec_data.tgz'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) un.expect ("stdout", re.compile (r'Unindexing done\.\r?\n')) finally: diff --git a/src/fs/test_gnunet_fs_idx_data.conf b/src/fs/test_gnunet_fs_idx_data.conf index f852011..4394805 100644 --- a/src/fs/test_gnunet_fs_idx_data.conf +++ b/src/fs/test_gnunet_fs_idx_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-py-idx/ -DEFAULTCONFIG = test_gnunet_fs_idx_data.conf [transport] PLUGINS = diff --git a/src/fs/test_gnunet_fs_ns.py.in b/src/fs/test_gnunet_fs_ns.py.in index ff892b4..ff892b4 100644..100755 --- 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_ns_data.conf b/src/fs/test_gnunet_fs_ns_data.conf index 5f297ab..57e3432 100644 --- a/src/fs/test_gnunet_fs_ns_data.conf +++ b/src/fs/test_gnunet_fs_ns_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-py-ns/ -DEFAULTCONFIG = test_gnunet_fs_ns_data.conf [transport] PLUGINS = diff --git a/src/fs/test_gnunet_fs_psd.py.in b/src/fs/test_gnunet_fs_psd.py.in index 9790e13..f12c6b7 100644..100755 --- a/src/fs/test_gnunet_fs_psd.py.in +++ b/src/fs/test_gnunet_fs_psd.py.in @@ -55,20 +55,20 @@ arm.communicate () # first, basic publish-search-download run try: pub = pexpect () - pub.spawn (None, [publish, '-c', 'test_gnunet_fs_psd_data.conf', '-n', '-m', "description:The GNU Public License", '-k', 'gpl', '../../COPYING'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - pub.expect ("stdout", re.compile (r"Publishing `.+[\\/]..[\\/]..[\\/]COPYING' done\.\r?\n")) - pub.expect ("stdout", re.compile (r"URI is `gnunet://fs/chk/PC0M19QMQC0BPSHR6BGA228PP6INER1D610MGEMOMEM87222FN8HVUO7PQGO0O9HD2GVLHF2N5IDHEQUNK6LKE428FPO96SKQEA486O\.PG7K85JGQ6N599MD5HEP3CHEVFPKQD9JB6NPSLVA3T1SKDS66CFI499VS6MGQ88B0QUAVT1282TCRD4GGFVUKDLGI8F0SPIANA3J2LG\.35147'\.\r?\n")) + pub.spawn (None, [publish, '-c', 'test_gnunet_fs_psd_data.conf', '-n', '-m', "description:Test archive", '-k', 'tst', 'test_gnunet_fs_rec_data.tgz'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + pub.expect ("stdout", re.compile (r"Publishing `.+test_gnunet_fs_rec_data.tgz' done\.\r?\n")) + pub.expect ("stdout", re.compile (r"URI is `gnunet://fs/chk/2VKHJMR74CB6GB1GFJNOO95BTINA2PEO25FL48GAS7SPBMA0GDEK5U74R1VIHK0LA6919QRS376BHQFDOE3OUP0JOU92K1NIRJMHFCO\.FPEBEAL6HCABM5LMFNNJOPPLKAF5TLUC86A11EIS1HLMIUBP8VEUTU7FT50OLF9ESKP7GTBUE7GDN392J2VKL6JKM1VT1KB4C7Q1U48\.17822'\.\r?\n")) s = pexpect () - s.spawn (None, [search, '-V', '-t', '1000', '-N', '1', '-c', 'test_gnunet_fs_psd_data.conf', 'gpl'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + s.spawn (None, [search, '-V', '-t', '1000', '-N', '1', '-c', 'test_gnunet_fs_psd_data.conf', 'tst'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) s.expect ("stdout", re.compile (r'#0:\r?\n')) - s.expect ("stdout", re.compile (r'gnunet-download -o "COPYING" gnunet://fs/chk/PC0M19QMQC0BPSHR6BGA228PP6INER1D610MGEMOMEM87222FN8HVUO7PQGO0O9HD2GVLHF2N5IDHEQUNK6LKE428FPO96SKQEA486O\.PG7K85JGQ6N599MD5HEP3CHEVFPKQD9JB6NPSLVA3T1SKDS66CFI499VS6MGQ88B0QUAVT1282TCRD4GGFVUKDLGI8F0SPIANA3J2LG\.35147\r?\n')) - s.expect ("stdout", re.compile (r"\s*description: The GNU Public License\r?\n")) + s.expect ("stdout", re.compile (r'gnunet-download -o "test_gnunet_fs_rec_data.tgz" gnunet://fs/chk/2VKHJMR74CB6GB1GFJNOO95BTINA2PEO25FL48GAS7SPBMA0GDEK5U74R1VIHK0LA6919QRS376BHQFDOE3OUP0JOU92K1NIRJMHFCO\.FPEBEAL6HCABM5LMFNNJOPPLKAF5TLUC86A11EIS1HLMIUBP8VEUTU7FT50OLF9ESKP7GTBUE7GDN392J2VKL6JKM1VT1KB4C7Q1U48\.17822\r?\n')) + s.expect ("stdout", re.compile (r"\s*description: Test archive\r?\n")) down = pexpect () - down.spawn (None, [download, '-c', 'test_gnunet_fs_psd_data.conf', '-o', 'COPYING', 'gnunet://fs/chk/PC0M19QMQC0BPSHR6BGA228PP6INER1D610MGEMOMEM87222FN8HVUO7PQGO0O9HD2GVLHF2N5IDHEQUNK6LKE428FPO96SKQEA486O.PG7K85JGQ6N599MD5HEP3CHEVFPKQD9JB6NPSLVA3T1SKDS66CFI499VS6MGQ88B0QUAVT1282TCRD4GGFVUKDLGI8F0SPIANA3J2LG.35147'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - down.expect ("stdout", re.compile (r"Downloading `COPYING' done (.*).\r?\n")) - os.remove ("COPYING") + down.spawn (None, [download, '-c', 'test_gnunet_fs_psd_data.conf', '-o', 'test_gnunet_fs_rec_data.tar.gz', 'gnunet://fs/chk/2VKHJMR74CB6GB1GFJNOO95BTINA2PEO25FL48GAS7SPBMA0GDEK5U74R1VIHK0LA6919QRS376BHQFDOE3OUP0JOU92K1NIRJMHFCO.FPEBEAL6HCABM5LMFNNJOPPLKAF5TLUC86A11EIS1HLMIUBP8VEUTU7FT50OLF9ESKP7GTBUE7GDN392J2VKL6JKM1VT1KB4C7Q1U48.17822'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + down.expect ("stdout", re.compile (r"Downloading `test_gnunet_fs_rec_data.tar.gz' done (.*).\r?\n")) + os.remove ("test_gnunet_fs_rec_data.tar.gz") finally: arm = subprocess.Popen ([gnunetarm, '-eq', '-c', 'test_gnunet_fs_psd_data.conf']) diff --git a/src/fs/test_gnunet_fs_psd_data.conf b/src/fs/test_gnunet_fs_psd_data.conf index b68c6b5..e41f6bf 100644 --- a/src/fs/test_gnunet_fs_psd_data.conf +++ b/src/fs/test_gnunet_fs_psd_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-py-psd/ -DEFAULTCONFIG = test_gnunet_fs_psd_data.conf [transport] PLUGINS = diff --git a/src/fs/test_gnunet_fs_rec.py.in b/src/fs/test_gnunet_fs_rec.py.in index e86bb0a..4f955b4 100644..100755 --- a/src/fs/test_gnunet_fs_rec.py.in +++ b/src/fs/test_gnunet_fs_rec.py.in @@ -23,6 +23,8 @@ import os import subprocess import re import shutil +import tarfile +import filecmp srcdir = "../.." gnunet_pyexpect_dir = os.path.join (srcdir, "contrib") @@ -30,6 +32,7 @@ if gnunet_pyexpect_dir not in sys.path: sys.path.append (gnunet_pyexpect_dir) from gnunet_pyexpect import pexpect +from pydiffer import dcdiff if os.name == 'posix': download = 'gnunet-download' @@ -55,7 +58,8 @@ arm = subprocess.Popen ([gnunetarm, '-sq', '-c', 'test_gnunet_fs_rec_data.conf'] arm.communicate () # pray that `tar' is in PATH -os.system ('tar xfz test_gnunet_fs_rec_data.tgz') +tar = tarfile.open ('test_gnunet_fs_rec_data.tgz') +tar.extractall () # first, basic publish-search-download run try: pub = pexpect () @@ -93,8 +97,9 @@ try: os.remove ("rdir/b.gnd") os.remove ("rdir/a.gnd") - if 0 != os.system ("diff -r dir rdir"): - raise Exception ("Unexpected difference between source directory and downloaded result") + diff = dcdiff ('dir', 'rdir') + if len (diff) != 0: + raise Exception ("Unexpected difference between source directory and downloaded result:\n{}".format (diff)) finally: diff --git a/src/fs/test_gnunet_fs_rec_data.conf b/src/fs/test_gnunet_fs_rec_data.conf index dae8b19..fcdcda9 100644 --- a/src/fs/test_gnunet_fs_rec_data.conf +++ b/src/fs/test_gnunet_fs_rec_data.conf @@ -1,7 +1,6 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/gnunet-test-fs-py-rec/ -DEFAULTCONFIG = test_gnunet_fs_rec_data.conf [transport] PLUGINS = diff --git a/src/fs/test_gnunet_service_fs_migration.c b/src/fs/test_gnunet_service_fs_migration.c index 00aab4f..2bc5354 100644 --- a/src/fs/test_gnunet_service_fs_migration.c +++ b/src/fs/test_gnunet_service_fs_migration.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010 Christian Grothoff (and other contributing authors) + (C) 2010, 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 @@ -25,7 +25,7 @@ */ #include "platform.h" #include "fs_test_lib.h" -#include "gnunet_testing_lib.h" +#include "gnunet_testbed_service.h" #define VERBOSE GNUNET_NO @@ -46,13 +46,22 @@ #define SEED 42 -static struct GNUNET_FS_TestDaemon *daemons[2]; +static struct GNUNET_TESTBED_Peer *daemons[2]; static int ok; static struct GNUNET_TIME_Absolute start_time; -static struct GNUNET_FS_TEST_ConnectContext *cc; +static struct GNUNET_TESTBED_Operation *op; + + +struct DownloadContext +{ + char *fn; + + struct GNUNET_FS_Uri *uri; +}; + static void do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) @@ -60,12 +69,7 @@ do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_TIME_Relative del; char *fancy; - if (NULL != cc) - { - GNUNET_FS_TEST_daemons_connect_cancel (cc); - cc = NULL; - } - GNUNET_FS_TEST_daemons_stop (2, daemons); + GNUNET_SCHEDULER_shutdown (); if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { del = GNUNET_TIME_absolute_get_duration (start_time); @@ -89,13 +93,23 @@ do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void -do_download (void *cls, const char *emsg) +do_download (void *cls, + const char *emsg) { - struct GNUNET_FS_Uri *uri = cls; + struct DownloadContext *dc = cls; + struct GNUNET_FS_Uri *uri = dc->uri; - if (emsg != NULL) + GNUNET_TESTBED_operation_done (op); + op = NULL; + if (NULL != dc->fn) + { + GNUNET_DISK_directory_remove (dc->fn); + GNUNET_free (dc->fn); + } + GNUNET_free (dc); + if (NULL != emsg) { - GNUNET_FS_TEST_daemons_stop (2, daemons); + GNUNET_SCHEDULER_shutdown (); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to stop source daemon: %s\n", emsg); GNUNET_FS_uri_destroy (uri); @@ -114,46 +128,47 @@ do_download (void *cls, const char *emsg) static void stop_source_peer (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_FS_Uri *uri = cls; - struct GNUNET_TESTING_PeerGroup *pg; + struct DownloadContext *dc = cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping source peer\n"); - pg = GNUNET_FS_TEST_get_group (daemons); - GNUNET_TESTING_daemons_vary (pg, 1, GNUNET_NO, TIMEOUT, &do_download, uri); + op = GNUNET_TESTBED_peer_stop (daemons[1], &do_download, dc); + GNUNET_assert (NULL != op); } static void -do_wait (void *cls, const struct GNUNET_FS_Uri *uri) +do_wait (void *cls, const struct GNUNET_FS_Uri *uri, + const char *fn) { - struct GNUNET_FS_Uri *d; + struct DownloadContext *dc; if (NULL == uri) { - GNUNET_FS_TEST_daemons_stop (2, daemons); + GNUNET_SCHEDULER_shutdown (); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout during upload attempt, shutting down with error\n"); ok = 1; return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Waiting to allow content to migrate\n"); - d = GNUNET_FS_uri_dup (uri); - (void) GNUNET_SCHEDULER_add_delayed (MIGRATION_DELAY, &stop_source_peer, d); + dc = GNUNET_malloc (sizeof (struct DownloadContext)); + dc->uri = GNUNET_FS_uri_dup (uri); + if (NULL != fn) + dc->fn = GNUNET_strdup (fn); + (void) GNUNET_SCHEDULER_add_delayed (MIGRATION_DELAY, &stop_source_peer, dc); } static void -do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +do_publish (void *cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers) { - cc = NULL; - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) - { - GNUNET_FS_TEST_daemons_stop (2, daemons); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Timeout during connect attempt, shutting down with error\n"); - ok = 1; - return; - } + unsigned int i; + + GNUNET_assert (2 == num_peers); + for (i=0;i<num_peers;i++) + daemons[i] = peers[i]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing %llu bytes\n", (unsigned long long) FILESIZE); GNUNET_FS_TEST_publish (daemons[1], TIMEOUT, 1, GNUNET_NO, FILESIZE, SEED, @@ -161,59 +176,15 @@ do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } -static void -do_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) - { - FPRINTF (stderr, "%s", "Daemons failed to start!\n"); - GNUNET_break (0); - ok = 1; - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Daemons started, will now try to connect them\n"); - cc = GNUNET_FS_TEST_daemons_connect (daemons[0], daemons[1], TIMEOUT, - &do_publish, NULL); -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - GNUNET_FS_TEST_daemons_start ("test_gnunet_service_fs_migration_data.conf", - TIMEOUT, 2, daemons, &do_connect, NULL); -} - - int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-gnunet-service-fs-migration", - "-c", - "fs_test_lib_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - GNUNET_DISK_directory_remove ("/tmp/test-gnunet-service-fs-migration/"); - GNUNET_log_setup ("test_gnunet_service_fs_migration", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-gnunet-service-fs-migration", "nohelp", options, - &run, NULL); + (void) GNUNET_TESTBED_test_run ("test-gnunet-service-fs-migration", + "fs_test_lib_data.conf", + 2, + 0, NULL, NULL, + &do_publish, + NULL); GNUNET_DISK_directory_remove ("/tmp/test-gnunet-service-fs-migration/"); return ok; } diff --git a/src/fs/test_gnunet_service_fs_migration_data.conf b/src/fs/test_gnunet_service_fs_migration_data.conf index 9c05a88..3d740e4 100644 --- a/src/fs/test_gnunet_service_fs_migration_data.conf +++ b/src/fs/test_gnunet_service_fs_migration_data.conf @@ -1,8 +1,9 @@ @INLINE@ test_fs_defaults.conf [PATHS] SERVICEHOME = /tmp/test-gnunet-service-fs-migration/ -DEFAULTCONFIG = test_gnunet_service_fs_migration_data.conf +[testbed] +OVERLAY_TOPOLOGY = CLIQUE [ats] WAN_QUOTA_IN = 3932160 diff --git a/src/fs/test_gnunet_service_fs_p2p.c b/src/fs/test_gnunet_service_fs_p2p.c index 7ca786e..d293bd6 100644 --- a/src/fs/test_gnunet_service_fs_p2p.c +++ b/src/fs/test_gnunet_service_fs_p2p.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010 Christian Grothoff (and other contributing authors) + (C) 2010, 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 @@ -42,26 +42,25 @@ #define SEED 42 -static struct GNUNET_FS_TestDaemon *daemons[NUM_DAEMONS]; +static const char *progname; + +static unsigned int anonymity_level; + +static struct GNUNET_TESTBED_Peer *daemons[NUM_DAEMONS]; static int ok; static struct GNUNET_TIME_Absolute start_time; -static struct GNUNET_FS_TEST_ConnectContext *cc; static void do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + char *fn = cls; struct GNUNET_TIME_Relative del; char *fancy; - if (NULL != cc) - { - GNUNET_FS_TEST_daemons_connect_cancel (cc); - cc = NULL; - } - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); + GNUNET_SCHEDULER_shutdown (); if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { del = GNUNET_TIME_absolute_get_duration (start_time); @@ -81,15 +80,21 @@ do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) "Timeout during download, shutting down with error\n"); ok = 1; } + if (NULL != fn) + { + GNUNET_DISK_directory_remove (fn); + GNUNET_free (fn); + } } static void -do_download (void *cls, const struct GNUNET_FS_Uri *uri) +do_download (void *cls, const struct GNUNET_FS_Uri *uri, + const char *fn) { if (NULL == uri) { - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); + GNUNET_SCHEDULER_shutdown (); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout during upload attempt, shutting down with error\n"); ok = 1; @@ -98,77 +103,53 @@ do_download (void *cls, const struct GNUNET_FS_Uri *uri) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Downloading %llu bytes\n", (unsigned long long) FILESIZE); start_time = GNUNET_TIME_absolute_get (); - GNUNET_FS_TEST_download (daemons[0], TIMEOUT, 1, SEED, uri, VERBOSE, &do_stop, - NULL); + GNUNET_FS_TEST_download (daemons[0], TIMEOUT, + anonymity_level, SEED, uri, + VERBOSE, &do_stop, + (NULL == fn) + ? NULL + : GNUNET_strdup (fn)); } static void -do_publish (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +do_publish (void *cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers) { - cc = NULL; - if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) - { - GNUNET_FS_TEST_daemons_stop (NUM_DAEMONS, daemons); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Timeout during connect attempt, shutting down with error\n"); - ok = 1; - return; - } + unsigned int i; + + if (NULL != strstr (progname, "stream")) + anonymity_level = 0; + else + anonymity_level = 1; + GNUNET_assert (NUM_DAEMONS == num_peers); + for (i=0;i<num_peers;i++) + daemons[i] = peers[i]; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing %llu bytes\n", (unsigned long long) FILESIZE); - GNUNET_FS_TEST_publish (daemons[1], TIMEOUT, 1, GNUNET_NO, FILESIZE, SEED, + GNUNET_FS_TEST_publish (daemons[1], TIMEOUT, + anonymity_level, GNUNET_NO, + FILESIZE, SEED, VERBOSE, &do_download, NULL); } -static void -do_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_assert (0 != (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Daemons started, will now try to connect them\n"); - cc = GNUNET_FS_TEST_daemons_connect (daemons[0], daemons[1], TIMEOUT, - &do_publish, NULL); -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - GNUNET_FS_TEST_daemons_start ("fs_test_lib_data.conf", TIMEOUT, NUM_DAEMONS, - daemons, &do_connect, NULL); -} - - int main (int argc, char *argv[]) { - char *const argvx[] = { - "test-gnunet-service-fs-p2p", - "-c", - "fs_test_lib_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; + const char *config; - GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); - GNUNET_log_setup ("test_gnunet_service_fs_p2p", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx, - "test-gnunet-service-fs-p2p", "nohelp", options, &run, - NULL); + progname = argv[0]; + if (NULL != strstr (progname, "stream")) + config = "test_gnunet_service_fs_p2p_stream.conf"; + else + config = "fs_test_lib_data.conf"; + (void) GNUNET_TESTBED_test_run ("test-gnunet-service-fs-p2p", + config, + NUM_DAEMONS, + 0, NULL, NULL, + &do_publish, NULL); GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-lib/"); return ok; } diff --git a/src/fs/test_gnunet_service_fs_p2p_stream.conf b/src/fs/test_gnunet_service_fs_p2p_stream.conf new file mode 100644 index 0000000..9d01208 --- /dev/null +++ b/src/fs/test_gnunet_service_fs_p2p_stream.conf @@ -0,0 +1,16 @@ +@INLINE@ fs_test_lib_data.conf + +[fs] +# FIXME: this option needs to be set for the +# testcase to truly work; however, as the code +# is not finished, not setting the option should +# allow the test to at least pass for now... +DISABLE_ANON_TRANSFER = YES + +# Do we cache content from other nodes? (may improve anonymity) +CONTENT_CACHING = NO + +# Do we send unsolicited data to other nodes if we have excess bandwidth? +# (may improve anonymity, probably not a good idea if content_caching is NO) +CONTENT_PUSHING = NO + diff --git a/src/fs/test_plugin_block_fs.c b/src/fs/test_plugin_block_fs.c new file mode 100644 index 0000000..a9f5ce3 --- /dev/null +++ b/src/fs/test_plugin_block_fs.c @@ -0,0 +1,77 @@ +/* + This file is part of GNUnet + (C) 2010, 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_plugin_block_fs.c + * @brief test for plugin_block_fs.c + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_block_lib.h" + + +static int +test_fs (struct GNUNET_BLOCK_Context *ctx) +{ + struct GNUNET_HashCode key; + char block[4]; + + memset (block, 1, sizeof (block)); + if (GNUNET_OK != + GNUNET_BLOCK_get_key (ctx, GNUNET_BLOCK_TYPE_FS_DBLOCK, block, + sizeof (block), &key)) + return 1; + if (GNUNET_BLOCK_EVALUATION_OK_LAST != + GNUNET_BLOCK_evaluate (ctx, GNUNET_BLOCK_TYPE_FS_DBLOCK, &key, NULL, 0, + NULL, 0, block, sizeof (block))) + return 2; + if (GNUNET_BLOCK_EVALUATION_REQUEST_VALID != + GNUNET_BLOCK_evaluate (ctx, GNUNET_BLOCK_TYPE_FS_DBLOCK, &key, NULL, 0, + NULL, 0, NULL, 0)) + return 4; + GNUNET_log_skip (1, GNUNET_NO); + if (GNUNET_BLOCK_EVALUATION_REQUEST_INVALID != + GNUNET_BLOCK_evaluate (ctx, GNUNET_BLOCK_TYPE_FS_DBLOCK, &key, NULL, 0, + "bogus", 5, NULL, 0)) + return 8; + GNUNET_log_skip (0, GNUNET_YES); + return 0; +} + + +int +main (int argc, char *argv[]) +{ + int ret; + struct GNUNET_BLOCK_Context *ctx; + struct GNUNET_CONFIGURATION_Handle *cfg; + + GNUNET_log_setup ("test-block", "WARNING", NULL); + cfg = GNUNET_CONFIGURATION_create (); + GNUNET_CONFIGURATION_set_value_string (cfg, "block", "PLUGINS", "fs"); + ctx = GNUNET_BLOCK_context_create (cfg); + ret = test_fs (ctx); + GNUNET_BLOCK_context_destroy (ctx); + GNUNET_CONFIGURATION_destroy (cfg); + if (ret != 0) + FPRINTF (stderr, "Tests failed: %d\n", ret); + return ret; +} + +/* end of test_plugin_block_fs.c */ |