diff options
Diffstat (limited to 'src/dht')
43 files changed, 2310 insertions, 5110 deletions
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am index b2d18d2..6bbc191 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am @@ -7,6 +7,8 @@ plugindir = $(libdir)/gnunet pkgcfgdir= $(pkgdatadir)/config.d/ +libexecdir= $(pkglibdir)/libexec/ + pkgcfg_DATA = \ dht.conf @@ -26,10 +28,11 @@ libgnunetdht_la_SOURCES = \ dht_api.c dht.h libgnunetdht_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ - $(XLIB) + $(XLIB) \ + $(LTLIBINTL) libgnunetdht_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 1:0:1 + -version-info 2:0:2 plugin_LTLIBRARIES = \ @@ -40,7 +43,8 @@ libgnunet_plugin_block_dht_la_SOURCES = \ libgnunet_plugin_block_dht_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/block/libgnunetblock.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_block_dht_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) libgnunet_plugin_block_dht_la_DEPENDENCIES = \ @@ -48,8 +52,10 @@ libgnunet_plugin_block_dht_la_DEPENDENCIES = \ -bin_PROGRAMS = \ - gnunet-service-dht \ +libexec_PROGRAMS = \ + gnunet-service-dht + +noinst_PROGRAMS = \ gnunet-dht-monitor \ gnunet-dht-get \ gnunet-dht-put @@ -103,83 +109,66 @@ gnunet_dht_monitor_DEPENDENCIES = \ libgnunetdht.la +noinst_LIBRARIES = libgnunetdhttest.a + +libgnunetdhttest_a_SOURCES = \ + dht_test_lib.c dht_test_lib.h +libgnunetdhttest_a_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/dht/libgnunetdht.la +libgnunetdhttest_a_DEPENDENCIES = \ + libgnunetdht.la + check_PROGRAMS = \ test_dht_api \ test_dht_twopeer \ - test_dht_twopeer_put_get \ - test_dht_twopeer_get_put \ - test_dht_twopeer_path_tracking \ test_dht_multipeer \ test_dht_line \ test_dht_2dtorus \ test_dht_monitor +if HAVE_EXPERIMENTAL +# These tests still do not work as testbed does +# not support the respective topology op + NEW_TESTS = test_dht_2dtorus test_dht_multipeer +endif + if ENABLE_TEST_RUN TESTS = test_dht_api $(check_SCRIPTS) \ test_dht_twopeer \ - test_dht_twopeer_put_get \ - test_dht_twopeer_get_put \ - test_dht_twopeer_path_tracking \ - test_dht_multipeer \ test_dht_line \ - test_dht_2dtorus \ - test_dht_monitor + test_dht_monitor \ + $(NEW_TESTS) endif test_dht_api_SOURCES = \ test_dht_api.c test_dht_api_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/dht/libgnunetdht.la test_dht_api_DEPENDENCIES = \ libgnunetdht.la test_dht_twopeer_SOURCES = \ - test_dht_twopeer.c + test_dht_topo.c test_dht_twopeer_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/dht/libgnunetdht.la test_dht_twopeer_DEPENDENCIES = \ libgnunetdht.la -test_dht_twopeer_put_get_SOURCES = \ - test_dht_twopeer_put_get.c -test_dht_twopeer_put_get_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la - -test_dht_twopeer_get_put_SOURCES = \ - test_dht_twopeer_get_put.c -test_dht_twopeer_get_put_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la - -test_dht_twopeer_path_tracking_SOURCES = \ - test_dht_twopeer_path_tracking.c -test_dht_twopeer_path_tracking_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la - -test_dht_multipeer_SOURCES = \ - test_dht_multipeer.c -test_dht_multipeer_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la -test_dht_multipeer_DEPENDENCIES = \ - libgnunetdht.la - test_dht_2dtorus_SOURCES = \ test_dht_topo.c test_dht_2dtorus_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/dht/libgnunetdht.la test_dht_2dtorus_DEPENDENCIES = \ libgnunetdht.la @@ -187,16 +176,30 @@ test_dht_2dtorus_DEPENDENCIES = \ test_dht_line_SOURCES = \ test_dht_topo.c test_dht_line_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/dht/libgnunetdht.la test_dht_line_DEPENDENCIES = \ libgnunetdht.la -test_dht_monitor_SOURCES = test_dht_monitor.c +test_dht_multipeer_SOURCES = \ + test_dht_topo.c +test_dht_multipeer_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/dht/libgnunetdht.la +test_dht_multipeer_DEPENDENCIES = \ + libgnunetdht.la + +test_dht_monitor_SOURCES = \ + test_dht_monitor.c test_dht_monitor_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/dht/libgnunetdht.la test_dht_monitor_DEPENDENCIES = \ libgnunetdht.la @@ -205,11 +208,22 @@ EXTRA_DIST = \ $(check_SCRIPTS) \ test_dht_api_data.conf \ test_dht_api_peer1.conf \ - test_dht_twopeer_data.conf \ - test_dht_multipeer_data.conf \ + test_dht_monitor.conf \ + test_dht_multipeer.conf \ test_dht_2dtorus.conf \ test_dht_line.conf \ - multipeer_topo.dat + test_dht_tools.py.in \ + test_dht_multipeer_topology.dat check_SCRIPTS = \ - test_dht_tools.sh + test_dht_tools.py + +do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' + +%.py: %.py.in Makefile + $(do_subst) < $(srcdir)/$< > $@ + chmod +x $@ + +test_dht_tools.py: test_dht_tools.py.in Makefile + $(do_subst) < $(srcdir)/test_dht_tools.py.in > test_dht_tools.py + chmod +x test_dht_tools.py diff --git a/src/dht/Makefile.in b/src/dht/Makefile.in index 12ce558..fbac460 100644 --- a/src/dht/Makefile.in +++ b/src/dht/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. @@ -17,7 +17,25 @@ + 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@ @@ -37,37 +55,32 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -bin_PROGRAMS = gnunet-service-dht$(EXEEXT) gnunet-dht-monitor$(EXEEXT) \ - gnunet-dht-get$(EXEEXT) gnunet-dht-put$(EXEEXT) +libexec_PROGRAMS = gnunet-service-dht$(EXEEXT) +noinst_PROGRAMS = gnunet-dht-monitor$(EXEEXT) gnunet-dht-get$(EXEEXT) \ + gnunet-dht-put$(EXEEXT) check_PROGRAMS = test_dht_api$(EXEEXT) test_dht_twopeer$(EXEEXT) \ - test_dht_twopeer_put_get$(EXEEXT) \ - test_dht_twopeer_get_put$(EXEEXT) \ - test_dht_twopeer_path_tracking$(EXEEXT) \ test_dht_multipeer$(EXEEXT) test_dht_line$(EXEEXT) \ test_dht_2dtorus$(EXEEXT) test_dht_monitor$(EXEEXT) @ENABLE_TEST_RUN_TRUE@TESTS = test_dht_api$(EXEEXT) $(check_SCRIPTS) \ @ENABLE_TEST_RUN_TRUE@ test_dht_twopeer$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_dht_twopeer_put_get$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_dht_twopeer_get_put$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_dht_twopeer_path_tracking$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_dht_multipeer$(EXEEXT) \ @ENABLE_TEST_RUN_TRUE@ test_dht_line$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_dht_2dtorus$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_dht_monitor$(EXEEXT) +@ENABLE_TEST_RUN_TRUE@ test_dht_monitor$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ $(am__EXEEXT_1) subdir = src/dht DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/dht.conf.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) \ @@ -76,6 +89,17 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/gnunet_config.h CONFIG_CLEAN_FILES = dht.conf CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +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_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +libgnunetdhttest_a_AR = $(AR) $(ARFLAGS) +am_libgnunetdhttest_a_OBJECTS = dht_test_lib.$(OBJEXT) +libgnunetdhttest_a_OBJECTS = $(am_libgnunetdhttest_a_OBJECTS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -97,30 +121,36 @@ 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)$(pkgcfgdir)" + "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(pkgcfgdir)" LTLIBRARIES = $(lib_LTLIBRARIES) $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = am_libgnunet_plugin_block_dht_la_OBJECTS = plugin_block_dht.lo libgnunet_plugin_block_dht_la_OBJECTS = \ $(am_libgnunet_plugin_block_dht_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_dht_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) \ $(libgnunet_plugin_block_dht_la_LDFLAGS) $(LDFLAGS) -o $@ -am__DEPENDENCIES_1 = libgnunetdht_la_DEPENDENCIES = \ $(top_builddir)/src/util/libgnunetutil.la \ - $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libgnunetdht_la_OBJECTS = dht_api.lo libgnunetdht_la_OBJECTS = $(am_libgnunetdht_la_OBJECTS) libgnunetdht_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgnunetdht_la_LDFLAGS) $(LDFLAGS) \ -o $@ -PROGRAMS = $(bin_PROGRAMS) +PROGRAMS = $(libexec_PROGRAMS) $(noinst_PROGRAMS) am_gnunet_dht_get_OBJECTS = gnunet-dht-get.$(OBJEXT) gnunet_dht_get_OBJECTS = $(am_gnunet_dht_get_OBJECTS) am_gnunet_dht_monitor_OBJECTS = gnunet-dht-monitor.$(OBJEXT) @@ -154,34 +184,10 @@ am_test_dht_line_OBJECTS = test_dht_topo.$(OBJEXT) test_dht_line_OBJECTS = $(am_test_dht_line_OBJECTS) am_test_dht_monitor_OBJECTS = test_dht_monitor.$(OBJEXT) test_dht_monitor_OBJECTS = $(am_test_dht_monitor_OBJECTS) -am_test_dht_multipeer_OBJECTS = test_dht_multipeer.$(OBJEXT) +am_test_dht_multipeer_OBJECTS = test_dht_topo.$(OBJEXT) test_dht_multipeer_OBJECTS = $(am_test_dht_multipeer_OBJECTS) -am_test_dht_twopeer_OBJECTS = test_dht_twopeer.$(OBJEXT) +am_test_dht_twopeer_OBJECTS = test_dht_topo.$(OBJEXT) test_dht_twopeer_OBJECTS = $(am_test_dht_twopeer_OBJECTS) -am_test_dht_twopeer_get_put_OBJECTS = \ - test_dht_twopeer_get_put.$(OBJEXT) -test_dht_twopeer_get_put_OBJECTS = \ - $(am_test_dht_twopeer_get_put_OBJECTS) -test_dht_twopeer_get_put_DEPENDENCIES = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la -am_test_dht_twopeer_path_tracking_OBJECTS = \ - test_dht_twopeer_path_tracking.$(OBJEXT) -test_dht_twopeer_path_tracking_OBJECTS = \ - $(am_test_dht_twopeer_path_tracking_OBJECTS) -test_dht_twopeer_path_tracking_DEPENDENCIES = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la -am_test_dht_twopeer_put_get_OBJECTS = \ - test_dht_twopeer_put_get.$(OBJEXT) -test_dht_twopeer_put_get_OBJECTS = \ - $(am_test_dht_twopeer_put_get_OBJECTS) -test_dht_twopeer_put_get_DEPENDENCIES = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -192,47 +198,47 @@ 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 " $@; -AM_V_at = $(am__v_at_$(V)) -am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) -am__v_at_0 = @ 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 = $(libgnunet_plugin_block_dht_la_SOURCES) \ +SOURCES = $(libgnunetdhttest_a_SOURCES) \ + $(libgnunet_plugin_block_dht_la_SOURCES) \ $(libgnunetdht_la_SOURCES) $(gnunet_dht_get_SOURCES) \ $(gnunet_dht_monitor_SOURCES) $(gnunet_dht_put_SOURCES) \ $(gnunet_service_dht_SOURCES) $(test_dht_2dtorus_SOURCES) \ $(test_dht_api_SOURCES) $(test_dht_line_SOURCES) \ $(test_dht_monitor_SOURCES) $(test_dht_multipeer_SOURCES) \ - $(test_dht_twopeer_SOURCES) \ - $(test_dht_twopeer_get_put_SOURCES) \ - $(test_dht_twopeer_path_tracking_SOURCES) \ - $(test_dht_twopeer_put_get_SOURCES) -DIST_SOURCES = $(libgnunet_plugin_block_dht_la_SOURCES) \ + $(test_dht_twopeer_SOURCES) +DIST_SOURCES = $(libgnunetdhttest_a_SOURCES) \ + $(libgnunet_plugin_block_dht_la_SOURCES) \ $(libgnunetdht_la_SOURCES) $(gnunet_dht_get_SOURCES) \ $(gnunet_dht_monitor_SOURCES) $(gnunet_dht_put_SOURCES) \ $(gnunet_service_dht_SOURCES) $(test_dht_2dtorus_SOURCES) \ $(test_dht_api_SOURCES) $(test_dht_line_SOURCES) \ $(test_dht_monitor_SOURCES) $(test_dht_multipeer_SOURCES) \ - $(test_dht_twopeer_SOURCES) \ - $(test_dht_twopeer_get_put_SOURCES) \ - $(test_dht_twopeer_path_tracking_SOURCES) \ - $(test_dht_twopeer_put_get_SOURCES) + $(test_dht_twopeer_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 am__tty_colors = \ red=; grn=; lgn=; blu=; std= +@HAVE_EXPERIMENTAL_TRUE@am__EXEEXT_1 = test_dht_2dtorus$(EXEEXT) \ +@HAVE_EXPERIMENTAL_TRUE@ test_dht_multipeer$(EXEEXT) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -269,6 +275,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@ @@ -279,6 +289,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@ @@ -301,6 +312,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@ @@ -322,6 +335,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@ @@ -331,6 +345,7 @@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ NM = @NM@ NMEDIT = @NMEDIT@ +NSS_DIR = @NSS_DIR@ OBJC = @OBJC@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ @@ -346,6 +361,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@ @@ -377,6 +393,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@ @@ -399,6 +416,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ +gitcommand = @gitcommand@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -409,10 +427,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@ @@ -430,6 +447,7 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ +svnversioncommand = @svnversioncommand@ sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target = @target@ @@ -458,11 +476,12 @@ libgnunetdht_la_SOURCES = \ libgnunetdht_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ - $(XLIB) + $(XLIB) \ + $(LTLIBINTL) libgnunetdht_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) $(WINFLAGS) \ - -version-info 1:0:1 + -version-info 2:0:2 plugin_LTLIBRARIES = \ libgnunet_plugin_block_dht.la @@ -473,7 +492,8 @@ libgnunet_plugin_block_dht_la_SOURCES = \ libgnunet_plugin_block_dht_la_LIBADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/block/libgnunetblock.la \ - $(top_builddir)/src/util/libgnunetutil.la + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunet_plugin_block_dht_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) @@ -536,11 +556,28 @@ gnunet_dht_monitor_LDADD = \ gnunet_dht_monitor_DEPENDENCIES = \ libgnunetdht.la +noinst_LIBRARIES = libgnunetdhttest.a +libgnunetdhttest_a_SOURCES = \ + dht_test_lib.c dht_test_lib.h + +libgnunetdhttest_a_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/dht/libgnunetdht.la + +libgnunetdhttest_a_DEPENDENCIES = \ + libgnunetdht.la + + +# These tests still do not work as testbed does +# not support the respective topology op +@HAVE_EXPERIMENTAL_TRUE@NEW_TESTS = test_dht_2dtorus test_dht_multipeer test_dht_api_SOURCES = \ test_dht_api.c test_dht_api_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/dht/libgnunetdht.la @@ -548,58 +585,25 @@ test_dht_api_DEPENDENCIES = \ libgnunetdht.la test_dht_twopeer_SOURCES = \ - test_dht_twopeer.c + test_dht_topo.c test_dht_twopeer_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/dht/libgnunetdht.la test_dht_twopeer_DEPENDENCIES = \ libgnunetdht.la -test_dht_twopeer_put_get_SOURCES = \ - test_dht_twopeer_put_get.c - -test_dht_twopeer_put_get_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la - -test_dht_twopeer_get_put_SOURCES = \ - test_dht_twopeer_get_put.c - -test_dht_twopeer_get_put_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la - -test_dht_twopeer_path_tracking_SOURCES = \ - test_dht_twopeer_path_tracking.c - -test_dht_twopeer_path_tracking_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la - -test_dht_multipeer_SOURCES = \ - test_dht_multipeer.c - -test_dht_multipeer_LDADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la - -test_dht_multipeer_DEPENDENCIES = \ - libgnunetdht.la - test_dht_2dtorus_SOURCES = \ test_dht_topo.c test_dht_2dtorus_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/dht/libgnunetdht.la test_dht_2dtorus_DEPENDENCIES = \ @@ -609,17 +613,34 @@ test_dht_line_SOURCES = \ test_dht_topo.c test_dht_line_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/dht/libgnunetdht.la + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/dht/libgnunetdht.la test_dht_line_DEPENDENCIES = \ libgnunetdht.la -test_dht_monitor_SOURCES = test_dht_monitor.c +test_dht_multipeer_SOURCES = \ + test_dht_topo.c + +test_dht_multipeer_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/dht/libgnunetdht.la + +test_dht_multipeer_DEPENDENCIES = \ + libgnunetdht.la + +test_dht_monitor_SOURCES = \ + test_dht_monitor.c + test_dht_monitor_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/dht/libgnunetdht.la test_dht_monitor_DEPENDENCIES = \ @@ -629,15 +650,17 @@ EXTRA_DIST = \ $(check_SCRIPTS) \ test_dht_api_data.conf \ test_dht_api_peer1.conf \ - test_dht_twopeer_data.conf \ - test_dht_multipeer_data.conf \ + test_dht_monitor.conf \ + test_dht_multipeer.conf \ test_dht_2dtorus.conf \ test_dht_line.conf \ - multipeer_topo.dat + test_dht_tools.py.in \ + test_dht_multipeer_topology.dat check_SCRIPTS = \ - test_dht_tools.sh + test_dht_tools.py +do_subst = $(SED) -e 's,[@]PYTHON[@],$(PYTHON),g' all: all-am .SUFFIXES: @@ -674,9 +697,15 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): dht.conf: $(top_builddir)/config.status $(srcdir)/dht.conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libgnunetdhttest.a: $(libgnunetdhttest_a_OBJECTS) $(libgnunetdhttest_a_DEPENDENCIES) $(EXTRA_libgnunetdhttest_a_DEPENDENCIES) + $(AM_V_at)-rm -f libgnunetdhttest.a + $(AM_V_AR)$(libgnunetdhttest_a_AR) libgnunetdhttest.a $(libgnunetdhttest_a_OBJECTS) $(libgnunetdhttest_a_LIBADD) + $(AM_V_at)$(RANLIB) libgnunetdhttest.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 \ @@ -684,6 +713,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)"; \ } @@ -707,7 +738,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 \ @@ -715,6 +745,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)"; \ } @@ -736,14 +768,26 @@ clean-pluginLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libgnunet_plugin_block_dht.la: $(libgnunet_plugin_block_dht_la_OBJECTS) $(libgnunet_plugin_block_dht_la_DEPENDENCIES) +libgnunet_plugin_block_dht.la: $(libgnunet_plugin_block_dht_la_OBJECTS) $(libgnunet_plugin_block_dht_la_DEPENDENCIES) $(EXTRA_libgnunet_plugin_block_dht_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunet_plugin_block_dht_la_LINK) -rpath $(plugindir) $(libgnunet_plugin_block_dht_la_OBJECTS) $(libgnunet_plugin_block_dht_la_LIBADD) $(LIBS) -libgnunetdht.la: $(libgnunetdht_la_OBJECTS) $(libgnunetdht_la_DEPENDENCIES) +libgnunetdht.la: $(libgnunetdht_la_OBJECTS) $(libgnunetdht_la_DEPENDENCIES) $(EXTRA_libgnunetdht_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunetdht_la_LINK) -rpath $(libdir) $(libgnunetdht_la_OBJECTS) $(libgnunetdht_la_LIBADD) $(LIBS) -install-binPROGRAMS: $(bin_PROGRAMS) + +clean-checkPROGRAMS: + @list='$(check_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 +install-libexecPROGRAMS: $(libexec_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + @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; \ @@ -760,23 +804,23 @@ install-binPROGRAMS: $(bin_PROGRAMS) 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)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + 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-binPROGRAMS: +uninstall-libexecPROGRAMS: @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + @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)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files + echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(libexecdir)" && rm -f $$files -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ +clean-libexecPROGRAMS: + @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ @@ -784,53 +828,44 @@ clean-binPROGRAMS: echo " rm -f" $$list; \ rm -f $$list -clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ +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-dht-get$(EXEEXT): $(gnunet_dht_get_OBJECTS) $(gnunet_dht_get_DEPENDENCIES) +gnunet-dht-get$(EXEEXT): $(gnunet_dht_get_OBJECTS) $(gnunet_dht_get_DEPENDENCIES) $(EXTRA_gnunet_dht_get_DEPENDENCIES) @rm -f gnunet-dht-get$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_dht_get_OBJECTS) $(gnunet_dht_get_LDADD) $(LIBS) -gnunet-dht-monitor$(EXEEXT): $(gnunet_dht_monitor_OBJECTS) $(gnunet_dht_monitor_DEPENDENCIES) +gnunet-dht-monitor$(EXEEXT): $(gnunet_dht_monitor_OBJECTS) $(gnunet_dht_monitor_DEPENDENCIES) $(EXTRA_gnunet_dht_monitor_DEPENDENCIES) @rm -f gnunet-dht-monitor$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_dht_monitor_OBJECTS) $(gnunet_dht_monitor_LDADD) $(LIBS) -gnunet-dht-put$(EXEEXT): $(gnunet_dht_put_OBJECTS) $(gnunet_dht_put_DEPENDENCIES) +gnunet-dht-put$(EXEEXT): $(gnunet_dht_put_OBJECTS) $(gnunet_dht_put_DEPENDENCIES) $(EXTRA_gnunet_dht_put_DEPENDENCIES) @rm -f gnunet-dht-put$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_dht_put_OBJECTS) $(gnunet_dht_put_LDADD) $(LIBS) -gnunet-service-dht$(EXEEXT): $(gnunet_service_dht_OBJECTS) $(gnunet_service_dht_DEPENDENCIES) +gnunet-service-dht$(EXEEXT): $(gnunet_service_dht_OBJECTS) $(gnunet_service_dht_DEPENDENCIES) $(EXTRA_gnunet_service_dht_DEPENDENCIES) @rm -f gnunet-service-dht$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_service_dht_OBJECTS) $(gnunet_service_dht_LDADD) $(LIBS) -test_dht_2dtorus$(EXEEXT): $(test_dht_2dtorus_OBJECTS) $(test_dht_2dtorus_DEPENDENCIES) +test_dht_2dtorus$(EXEEXT): $(test_dht_2dtorus_OBJECTS) $(test_dht_2dtorus_DEPENDENCIES) $(EXTRA_test_dht_2dtorus_DEPENDENCIES) @rm -f test_dht_2dtorus$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dht_2dtorus_OBJECTS) $(test_dht_2dtorus_LDADD) $(LIBS) -test_dht_api$(EXEEXT): $(test_dht_api_OBJECTS) $(test_dht_api_DEPENDENCIES) +test_dht_api$(EXEEXT): $(test_dht_api_OBJECTS) $(test_dht_api_DEPENDENCIES) $(EXTRA_test_dht_api_DEPENDENCIES) @rm -f test_dht_api$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dht_api_OBJECTS) $(test_dht_api_LDADD) $(LIBS) -test_dht_line$(EXEEXT): $(test_dht_line_OBJECTS) $(test_dht_line_DEPENDENCIES) +test_dht_line$(EXEEXT): $(test_dht_line_OBJECTS) $(test_dht_line_DEPENDENCIES) $(EXTRA_test_dht_line_DEPENDENCIES) @rm -f test_dht_line$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dht_line_OBJECTS) $(test_dht_line_LDADD) $(LIBS) -test_dht_monitor$(EXEEXT): $(test_dht_monitor_OBJECTS) $(test_dht_monitor_DEPENDENCIES) +test_dht_monitor$(EXEEXT): $(test_dht_monitor_OBJECTS) $(test_dht_monitor_DEPENDENCIES) $(EXTRA_test_dht_monitor_DEPENDENCIES) @rm -f test_dht_monitor$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dht_monitor_OBJECTS) $(test_dht_monitor_LDADD) $(LIBS) -test_dht_multipeer$(EXEEXT): $(test_dht_multipeer_OBJECTS) $(test_dht_multipeer_DEPENDENCIES) +test_dht_multipeer$(EXEEXT): $(test_dht_multipeer_OBJECTS) $(test_dht_multipeer_DEPENDENCIES) $(EXTRA_test_dht_multipeer_DEPENDENCIES) @rm -f test_dht_multipeer$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dht_multipeer_OBJECTS) $(test_dht_multipeer_LDADD) $(LIBS) -test_dht_twopeer$(EXEEXT): $(test_dht_twopeer_OBJECTS) $(test_dht_twopeer_DEPENDENCIES) +test_dht_twopeer$(EXEEXT): $(test_dht_twopeer_OBJECTS) $(test_dht_twopeer_DEPENDENCIES) $(EXTRA_test_dht_twopeer_DEPENDENCIES) @rm -f test_dht_twopeer$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dht_twopeer_OBJECTS) $(test_dht_twopeer_LDADD) $(LIBS) -test_dht_twopeer_get_put$(EXEEXT): $(test_dht_twopeer_get_put_OBJECTS) $(test_dht_twopeer_get_put_DEPENDENCIES) - @rm -f test_dht_twopeer_get_put$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_dht_twopeer_get_put_OBJECTS) $(test_dht_twopeer_get_put_LDADD) $(LIBS) -test_dht_twopeer_path_tracking$(EXEEXT): $(test_dht_twopeer_path_tracking_OBJECTS) $(test_dht_twopeer_path_tracking_DEPENDENCIES) - @rm -f test_dht_twopeer_path_tracking$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_dht_twopeer_path_tracking_OBJECTS) $(test_dht_twopeer_path_tracking_LDADD) $(LIBS) -test_dht_twopeer_put_get$(EXEEXT): $(test_dht_twopeer_put_get_OBJECTS) $(test_dht_twopeer_put_get_DEPENDENCIES) - @rm -f test_dht_twopeer_put_get$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_dht_twopeer_put_get_OBJECTS) $(test_dht_twopeer_put_get_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -839,6 +874,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht_api.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dht_test_lib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-dht-get.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-dht-monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-dht-put.Po@am__quote@ @@ -852,36 +888,28 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_block_dht.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dht_api.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dht_monitor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dht_multipeer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dht_topo.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dht_twopeer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dht_twopeer_get_put.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dht_twopeer_path_tracking.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dht_twopeer_put_get.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 @@ -890,8 +918,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"; \ @@ -905,9 +936,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)'; \ @@ -1042,14 +1071,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 @@ -1087,11 +1117,9 @@ check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_SCRIPTS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) -install-binPROGRAMS: install-libLTLIBRARIES - +all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(PROGRAMS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(pkgcfgdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -1104,10 +1132,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: @@ -1121,9 +1154,9 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-pluginLTLIBRARIES \ - mostlyclean-am +clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libexecPROGRAMS clean-libtool clean-noinstLIBRARIES \ + clean-noinstPROGRAMS clean-pluginLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -1149,7 +1182,7 @@ install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-binPROGRAMS install-libLTLIBRARIES +install-exec-am: install-libLTLIBRARIES install-libexecPROGRAMS install-html: install-html-am @@ -1189,30 +1222,39 @@ ps: ps-am ps-am: -uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ +uninstall-am: 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-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-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 \ + clean-checkPROGRAMS clean-generic 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-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-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-libLTLIBRARIES \ + uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS \ uninstall-pkgcfgDATA uninstall-pluginLTLIBRARIES +%.py: %.py.in Makefile + $(do_subst) < $(srcdir)/$< > $@ + chmod +x $@ + +test_dht_tools.py: test_dht_tools.py.in Makefile + $(do_subst) < $(srcdir)/test_dht_tools.py.in > test_dht_tools.py + chmod +x test_dht_tools.py + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/dht/dht.conf.in b/src/dht/dht.conf.in index 59581dc..2802111 100644 --- a/src/dht/dht.conf.in +++ b/src/dht/dht.conf.in @@ -3,7 +3,6 @@ AUTOSTART = YES @JAVAPORT@PORT = 2095 HOSTNAME = localhost HOME = $SERVICEHOME -CONFIG = $DEFAULTCONFIG BINARY = gnunet-service-dht ACCEPT_FROM = 127.0.0.1; ACCEPT_FROM6 = ::1; @@ -13,7 +12,6 @@ UNIXPATH = /tmp/gnunet-service-dht.sock UNIX_MATCH_UID = YES UNIX_MATCH_GID = YES # DISABLE_SOCKET_FORWARDING = NO -# DEBUG = YES # USERNAME = # MAXBUF = # TIMEOUT = @@ -22,18 +20,15 @@ UNIX_MATCH_GID = YES # REJECT_FROM = # REJECT_FROM6 = # PREFIX = -# DO_FIND_PEER = -# STRICT_KADEMLIA = -# USE_MAX_HOPS = -# MAX_HOPS = -# REPUBLISH = YES -# REPLICATION_FREQUENCY = 60 -# STOP_ON_CLOSEST = -# STOP_FOUND = -# CONVERGE_MODIFIER = + + +# Special option to disable DHT calling 'try_connect' (for testing) +DISABLE_TRY_CONNECT = NO [dhtcache] -DATABASE = sqlite -QUOTA = 1 MB +DATABASE = heap +QUOTA = 50 MB +# Disable RC-file for Bloom filter? (for benchmarking with limited IO availability) +DISABLE_BF_RC = NO diff --git a/src/dht/dht.h b/src/dht/dht.h index 8adf49f..f736c8d 100644 --- a/src/dht/dht.h +++ b/src/dht/dht.h @@ -60,7 +60,7 @@ struct GNUNET_DHT_ClientGetStopMessage /** * Key of this request */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; }; @@ -95,7 +95,7 @@ struct GNUNET_DHT_ClientGetMessage /** * The key to search for */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /** * Unique ID identifying this request, if 0 then @@ -109,6 +109,39 @@ struct GNUNET_DHT_ClientGetMessage /** + * DHT GET RESULTS KNOWN message sent from clients to service. Indicates that a GET + * request should exclude certain results which are already known. + */ +struct GNUNET_DHT_ClientGetResultSeenMessage +{ + /** + * Type: GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN + */ + struct GNUNET_MessageHeader header; + + /** + * Reserved, always 0. + */ + uint32_t reserved GNUNET_PACKED; + + /** + * The key we are searching for (to make it easy to find the corresponding + * GET inside the service). + */ + struct GNUNET_HashCode key; + + /** + * Unique ID identifying this request. + */ + uint64_t unique_id GNUNET_PACKED; + + /* Followed by an array of the hash codes of known results */ + +}; + + + +/** * Reply to a GET send from the service to a client. */ struct GNUNET_DHT_ClientResultMessage @@ -148,7 +181,7 @@ struct GNUNET_DHT_ClientResultMessage /** * The key that was searched for */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /* put path, get path and actual data are copied to end of this dealy do */ @@ -193,7 +226,7 @@ struct GNUNET_DHT_ClientPutMessage /** * The key to store the value under. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /* DATA copied to end of this message */ @@ -268,7 +301,7 @@ struct GNUNET_DHT_MonitorPutMessage /** * The key to store the value under. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /* put path (if tracked) */ @@ -315,7 +348,7 @@ struct GNUNET_DHT_MonitorStartStopMessage /** * The key to filter messages by. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; }; @@ -325,7 +358,7 @@ struct GNUNET_DHT_MonitorStartStopMessage struct GNUNET_DHT_MonitorGetMessage { /** - * Type: GNUNET_MESSAGE_TYPE_DHT_MONITOR_PUT + * Type: GNUNET_MESSAGE_TYPE_DHT_MONITOR_GET */ struct GNUNET_MessageHeader header; @@ -358,7 +391,7 @@ struct GNUNET_DHT_MonitorGetMessage /** * The key to store the value under. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /* get path (if tracked) */ @@ -397,7 +430,7 @@ struct GNUNET_DHT_MonitorGetRespMessage /** * The key of the corresponding GET request. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /* put path (if tracked) */ diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 420eacb..96ca6ab 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c @@ -173,15 +173,42 @@ struct GNUNET_DHT_GetHandle struct PendingMessage *message; /** + * Array of hash codes over the results that we have already + * seen. + */ + struct GNUNET_HashCode *seen_results; + + /** * Key that this get request is for */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /** * Unique identifier for this request (for key collisions). */ uint64_t unique_id; + /** + * Size of the 'seen_results' array. Note that not + * all positions might be used (as we over-allocate). + */ + unsigned int seen_results_size; + + /** + * Offset into the 'seen_results' array marking the + * end of the positions that are actually used. + */ + unsigned int seen_results_end; + + /** + * Offset into the 'seen_results' array marking the + * position up to where we've send the hash codes to + * the DHT for blocking (needed as we might not be + * able to send all hash codes at once). + */ + unsigned int seen_results_transmission_offset; + + }; @@ -213,7 +240,7 @@ struct GNUNET_DHT_MonitorHandle /** * Key being looked for, NULL == all. */ - GNUNET_HashCode *key; + struct GNUNET_HashCode *key; /** * Callback for each received message of type get. @@ -353,6 +380,50 @@ try_connect (struct GNUNET_DHT_Handle *handle) /** + * Queue messages to DHT to block certain results from the result set. + * + * @param get_handle GET to generate messages for. + */ +static void +queue_filter_messages (struct GNUNET_DHT_GetHandle *get_handle) +{ + struct PendingMessage *pm; + struct GNUNET_DHT_ClientGetResultSeenMessage *msg; + uint16_t msize; + unsigned int delta; + unsigned int max; + + while (get_handle->seen_results_transmission_offset < get_handle->seen_results_end) + { + delta = get_handle->seen_results_end - get_handle->seen_results_transmission_offset; + max = (GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode); + if (delta > max) + delta = max; + msize = sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage) + delta * sizeof (struct GNUNET_HashCode); + + pm = GNUNET_malloc (sizeof (struct PendingMessage) + msize); + msg = (struct GNUNET_DHT_ClientGetResultSeenMessage *) &pm[1]; + pm->msg = &msg->header; + pm->handle = get_handle->dht_handle; + pm->unique_id = get_handle->unique_id; + pm->free_on_send = GNUNET_YES; + pm->in_pending_queue = GNUNET_YES; + msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN); + msg->header.size = htons (msize); + msg->key = get_handle->key; + msg->unique_id = get_handle->unique_id; + memcpy (&msg[1], + &get_handle->seen_results[get_handle->seen_results_transmission_offset], + sizeof (struct GNUNET_HashCode) * delta); + get_handle->seen_results_transmission_offset += delta; + GNUNET_CONTAINER_DLL_insert_tail (get_handle->dht_handle->pending_head, + get_handle->dht_handle->pending_tail, + pm); + } +} + + +/** * Add the request corresponding to the given route handle * to the pending queue (if it is not already in there). * @@ -362,19 +433,21 @@ try_connect (struct GNUNET_DHT_Handle *handle) * @return GNUNET_YES (always) */ static int -add_request_to_pending (void *cls, const GNUNET_HashCode * key, void *value) +add_request_to_pending (void *cls, const struct GNUNET_HashCode * key, void *value) { struct GNUNET_DHT_Handle *handle = cls; - struct GNUNET_DHT_GetHandle *rh = value; + struct GNUNET_DHT_GetHandle *get_handle = value; - if (GNUNET_NO == rh->message->in_pending_queue) + if (GNUNET_NO == get_handle->message->in_pending_queue) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Retransmitting request related to %s to DHT %p\n", GNUNET_h2s (key), handle); + get_handle->seen_results_transmission_offset = 0; GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, - rh->message); - rh->message->in_pending_queue = GNUNET_YES; + get_handle->message); + queue_filter_messages (get_handle); + get_handle->message->in_pending_queue = GNUNET_YES; } return GNUNET_YES; } @@ -401,13 +474,7 @@ try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_DHT_Handle *handle = cls; LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with DHT %p\n", handle); - handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; - if (handle->retry_time.rel_value < GNUNET_CONSTANTS_SERVICE_RETRY.rel_value) - handle->retry_time = GNUNET_CONSTANTS_SERVICE_RETRY; - else - handle->retry_time = GNUNET_TIME_relative_multiply (handle->retry_time, 2); - if (handle->retry_time.rel_value > GNUNET_CONSTANTS_SERVICE_TIMEOUT.rel_value) - handle->retry_time = GNUNET_CONSTANTS_SERVICE_TIMEOUT; + handle->retry_time = GNUNET_TIME_STD_BACKOFF (handle->retry_time); handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; if (GNUNET_YES != try_connect (handle)) { @@ -438,8 +505,9 @@ do_disconnect (struct GNUNET_DHT_Handle *handle) GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); handle->th = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Disconnecting from DHT service, will try to reconnect in %llu ms\n", - (unsigned long long) handle->retry_time.rel_value); + "Disconnecting from DHT service, will try to reconnect in %s\n", + GNUNET_STRINGS_relative_time_to_string (handle->retry_time, + GNUNET_YES)); GNUNET_CLIENT_disconnect (handle->client); handle->client = NULL; @@ -574,15 +642,16 @@ transmit_pending (void *cls, size_t size, void *buf) * @param key query of the request * @param value the 'struct GNUNET_DHT_RouteHandle' of a request matching the same key * @return GNUNET_YES to continue to iterate over all results, - * GNUNET_NO if the reply is malformed + * GNUNET_NO if the reply is malformed or we found a matching request */ static int -process_reply (void *cls, const GNUNET_HashCode * key, void *value) +process_reply (void *cls, const struct GNUNET_HashCode * key, void *value) { const struct GNUNET_DHT_ClientResultMessage *dht_msg = cls; struct GNUNET_DHT_GetHandle *get_handle = value; const struct GNUNET_PeerIdentity *put_path; const struct GNUNET_PeerIdentity *get_path; + struct GNUNET_HashCode hc; uint32_t put_path_length; uint32_t get_path_length; size_t data_length; @@ -619,11 +688,22 @@ process_reply (void *cls, const GNUNET_HashCode * key, void *value) put_path = (const struct GNUNET_PeerIdentity *) &dht_msg[1]; get_path = &put_path[put_path_length]; data = &get_path[get_path_length]; + /* remember that we've seen this result */ + GNUNET_CRYPTO_hash (data, data_length, &hc); + if (get_handle->seen_results_size == get_handle->seen_results_end) + GNUNET_array_grow (get_handle->seen_results, + get_handle->seen_results_size, + get_handle->seen_results_size * 2 + 1); + GNUNET_assert (get_handle->seen_results_end == get_handle->seen_results_transmission_offset); + get_handle->seen_results[get_handle->seen_results_end++] = hc; + /* no need to block it explicitly, service already knows about it! */ + get_handle->seen_results_transmission_offset++; + get_handle->iter (get_handle->iter_cls, GNUNET_TIME_absolute_ntoh (dht_msg->expiration), key, get_path, get_path_length, put_path, put_path_length, ntohl (dht_msg->type), data_length, data); - return GNUNET_YES; + return GNUNET_NO; } /** @@ -648,7 +728,7 @@ process_monitor_get_message (struct GNUNET_DHT_Handle *handle, type_ok = (GNUNET_BLOCK_TYPE_ANY == h->type) || (h->type == ntohl(msg->type)); key_ok = (NULL == h->key) || (0 == memcmp (h->key, &msg->key, - sizeof (GNUNET_HashCode))); + sizeof (struct GNUNET_HashCode))); if (type_ok && key_ok && (NULL != h->get_cb)) h->get_cb (h->cb_cls, ntohl (msg->options), @@ -699,7 +779,7 @@ process_monitor_get_resp_message (struct GNUNET_DHT_Handle *handle, type_ok = (GNUNET_BLOCK_TYPE_ANY == h->type) || (h->type == ntohl(msg->type)); key_ok = (NULL == h->key) || (0 == memcmp (h->key, &msg->key, - sizeof (GNUNET_HashCode))); + sizeof (struct GNUNET_HashCode))); if (type_ok && key_ok && (NULL != h->get_resp_cb)) h->get_resp_cb (h->cb_cls, (enum GNUNET_BLOCK_Type) ntohl(msg->type), @@ -749,7 +829,7 @@ process_monitor_put_message (struct GNUNET_DHT_Handle *handle, type_ok = (GNUNET_BLOCK_TYPE_ANY == h->type) || (h->type == ntohl(msg->type)); key_ok = (NULL == h->key) || (0 == memcmp (h->key, &msg->key, - sizeof (GNUNET_HashCode))); + sizeof (struct GNUNET_HashCode))); if (type_ok && key_ok && (NULL != h->put_cb)) h->put_cb (h->cb_cls, ntohl (msg->options), @@ -820,6 +900,8 @@ service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg) do_disconnect (handle); return; } + GNUNET_CLIENT_receive (handle->client, &service_message_handler, handle, + GNUNET_TIME_UNIT_FOREVER_REL); ret = GNUNET_SYSERR; msize = ntohs (msg->size); switch (ntohs (msg->type)) @@ -861,13 +943,15 @@ service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg) GNUNET_break (0); break; } - ret = GNUNET_OK; dht_msg = (const struct GNUNET_DHT_ClientResultMessage *) msg; - LOG (GNUNET_ERROR_TYPE_DEBUG, "Received reply for `%s' from DHT service %p\n", - GNUNET_h2s (&dht_msg->key), handle); + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Received reply for `%s' from DHT service %p\n", + GNUNET_h2s (&dht_msg->key), handle); GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests, - &dht_msg->key, &process_reply, - (void *) dht_msg); + &dht_msg->key, + &process_reply, + (void *) dht_msg); + ret = GNUNET_OK; break; case GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT_OK: if (ntohs (msg->size) != sizeof (struct GNUNET_DHT_ClientPutConfirmationMessage)) @@ -880,6 +964,9 @@ service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg) break; default: GNUNET_break(0); + LOG (GNUNET_ERROR_TYPE_WARNING, + "Unknown DHT message type: %hu (%hu) size: %hu\n", + ntohs (msg->type), msg->type, msize); break; } if (GNUNET_OK != ret) @@ -888,8 +975,6 @@ service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg) do_disconnect (handle); return; } - GNUNET_CLIENT_receive (handle->client, &service_message_handler, handle, - GNUNET_TIME_UNIT_FOREVER_REL); } @@ -912,7 +997,7 @@ GNUNET_DHT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, handle->cfg = cfg; handle->uid_gen = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); - handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len); + handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len, GNUNET_NO); if (GNUNET_NO == try_connect (handle)) { GNUNET_DHT_disconnect (handle); @@ -1040,10 +1125,10 @@ mark_put_message_gone (void *cls, * @param cont_cls closure for cont */ struct GNUNET_DHT_PutHandle * -GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const GNUNET_HashCode * key, +GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode * key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, - enum GNUNET_BLOCK_Type type, size_t size, const char *data, + enum GNUNET_BLOCK_Type type, size_t size, const void *data, struct GNUNET_TIME_Absolute exp, struct GNUNET_TIME_Relative timeout, GNUNET_DHT_PutContinuation cont, void *cont_cls) @@ -1148,7 +1233,7 @@ GNUNET_DHT_put_cancel (struct GNUNET_DHT_PutHandle *ph) */ struct GNUNET_DHT_GetHandle * GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, - enum GNUNET_BLOCK_Type type, const GNUNET_HashCode * key, + enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode * key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, const void *xquery, size_t xquery_size, GNUNET_DHT_GetIterator iter, @@ -1185,6 +1270,7 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, pending); pending->in_pending_queue = GNUNET_YES; get_handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_GetHandle)); + get_handle->dht_handle = handle; get_handle->iter = iter; get_handle->iter_cls = iter_cls; get_handle->message = pending; @@ -1196,6 +1282,38 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle, } + +/** + * Tell the DHT not to return any of the following known results + * to this client. + * + * @param get_handle get operation for which results should be filtered + * @param num_results number of results to be blocked that are + * provided in this call (size of the 'results' array) + * @param results array of hash codes over the 'data' of the results + * to be blocked + */ +void +GNUNET_DHT_get_filter_known_results (struct GNUNET_DHT_GetHandle *get_handle, + unsigned int num_results, + const struct GNUNET_HashCode *results) +{ + unsigned int needed; + + needed = get_handle->seen_results_end + num_results; + if (needed > get_handle->seen_results_size) + GNUNET_array_grow (get_handle->seen_results, + get_handle->seen_results_size, + needed); + memcpy (&get_handle->seen_results[get_handle->seen_results_end], + results, + num_results * sizeof (struct GNUNET_HashCode)); + get_handle->seen_results_end += num_results; + queue_filter_messages (get_handle); + process_pending_messages (get_handle->dht_handle); +} + + /** * Stop async DHT-get. * @@ -1244,8 +1362,10 @@ GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle) get_handle->message->in_pending_queue = GNUNET_NO; } GNUNET_free (get_handle->message); + GNUNET_array_grow (get_handle->seen_results, + get_handle->seen_results_end, + 0); GNUNET_free (get_handle); - process_pending_messages (handle); } @@ -1266,7 +1386,7 @@ GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle) struct GNUNET_DHT_MonitorHandle * GNUNET_DHT_monitor_start (struct GNUNET_DHT_Handle *handle, enum GNUNET_BLOCK_Type type, - const GNUNET_HashCode *key, + const struct GNUNET_HashCode *key, GNUNET_DHT_MonitorGetCB get_cb, GNUNET_DHT_MonitorGetRespCB get_resp_cb, GNUNET_DHT_MonitorPutCB put_cb, @@ -1287,8 +1407,8 @@ GNUNET_DHT_monitor_start (struct GNUNET_DHT_Handle *handle, h->dht_handle = handle; if (NULL != key) { - h->key = GNUNET_malloc (sizeof(GNUNET_HashCode)); - memcpy (h->key, key, sizeof(GNUNET_HashCode)); + h->key = GNUNET_malloc (sizeof(struct GNUNET_HashCode)); + memcpy (h->key, key, sizeof(struct GNUNET_HashCode)); } pending = GNUNET_malloc (sizeof (struct GNUNET_DHT_MonitorStartStopMessage) + @@ -1305,7 +1425,7 @@ GNUNET_DHT_monitor_start (struct GNUNET_DHT_Handle *handle, m->put = htons(NULL != put_cb); if (NULL != key) { m->filter_key = htons(1); - memcpy (&m->key, key, sizeof(GNUNET_HashCode)); + memcpy (&m->key, key, sizeof(struct GNUNET_HashCode)); } GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail, pending); @@ -1347,7 +1467,7 @@ GNUNET_DHT_monitor_stop (struct GNUNET_DHT_MonitorHandle *handle) m->put = htons(NULL != handle->put_cb); if (NULL != handle->key) { m->filter_key = htons(1); - memcpy (&m->key, handle->key, sizeof(GNUNET_HashCode)); + memcpy (&m->key, handle->key, sizeof(struct GNUNET_HashCode)); } GNUNET_CONTAINER_DLL_insert (handle->dht_handle->pending_head, handle->dht_handle->pending_tail, diff --git a/src/dht/dht_test_lib.c b/src/dht/dht_test_lib.c new file mode 100644 index 0000000..365804b --- /dev/null +++ b/src/dht/dht_test_lib.c @@ -0,0 +1,214 @@ +/* + 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 dht/dht_test_lib.c + * @author Christian Grothoff + * @brief library for writing DHT tests + */ +#include "platform.h" +#include "dht_test_lib.h" + +/** + * Test context for a DHT Test. + */ +struct GNUNET_DHT_TEST_Context +{ + /** + * Array of running peers. + */ + struct GNUNET_TESTBED_Peer **peers; + + /** + * Array of handles to the DHT for each peer. + */ + struct GNUNET_DHT_Handle **dhts; + + /** + * Operation associated with the connection to the DHT. + */ + struct GNUNET_TESTBED_Operation **ops; + + /** + * Main function of the test to run once all DHTs are available. + */ + GNUNET_DHT_TEST_AppMain app_main; + + /** + * Closure for 'app_main'. + */ + void *app_main_cls; + + /** + * Number of peers running, size of the arrays above. + */ + unsigned int num_peers; + +}; + + +/** + * Adapter function called to establish a connection to + * the DHT 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 * +dht_connect_adapter (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + return GNUNET_DHT_connect (cfg, 16); +} + + +/** + * Adapter function called to destroy a connection to + * the DHT service. + * + * @param cls closure + * @param op_result service handle returned from the connect adapter + */ +static void +dht_disconnect_adapter (void *cls, + void *op_result) +{ + struct GNUNET_DHT_Handle *dht = op_result; + + GNUNET_DHT_disconnect (dht); +} + + +/** + * Callback to be called when a service connect operation is completed + * + * @param cls the callback closure from functions generating an operation + * @param op the operation that has been finished + * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() + * @param emsg error message in case the operation has failed; will be NULL if + * operation has executed successfully. + */ +static void +dht_connect_cb (void *cls, + struct GNUNET_TESTBED_Operation *op, + void *ca_result, + const char *emsg) +{ + struct GNUNET_DHT_TEST_Context *ctx = cls; + unsigned int i; + + if (NULL != emsg) + { + fprintf (stderr, "Failed to connect to DHT service: %s\n", + emsg); + GNUNET_SCHEDULER_shutdown (); + return; + } + for (i=0;i<ctx->num_peers;i++) + if (op == ctx->ops[i]) + ctx->dhts[i] = ca_result; + for (i=0;i<ctx->num_peers;i++) + if (NULL == ctx->dhts[i]) + return; /* still some DHT connections missing */ + /* all DHT connections ready! */ + ctx->app_main (ctx->app_main_cls, + ctx, + ctx->num_peers, + ctx->peers, + ctx->dhts); +} + + +/** + * Clean up the testbed. + * + * @param ctx handle for the testbed + */ +void +GNUNET_DHT_TEST_cleanup (struct GNUNET_DHT_TEST_Context *ctx) +{ + unsigned int i; + + for (i=0;i<ctx->num_peers;i++) + GNUNET_TESTBED_operation_done (ctx->ops[i]); + GNUNET_free (ctx->ops); + GNUNET_free (ctx->dhts); + GNUNET_free (ctx); + GNUNET_SCHEDULER_shutdown (); +} + + +static void +dht_test_run (void *cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers) +{ + struct GNUNET_DHT_TEST_Context *ctx = cls; + unsigned int i; + + GNUNET_assert (num_peers == ctx->num_peers); + ctx->peers = peers; + for (i=0;i<num_peers;i++) + ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx, + peers[i], + "dht", + &dht_connect_cb, + ctx, + &dht_connect_adapter, + &dht_disconnect_adapter, + ctx); +} + + +/** + * Run a test using the given name, configuration file and number of + * peers. + * + * @param testname name of the test (for logging) + * @param cfgname name of the configuration file + * @param num_peers number of peers to start + * @param tmain main function to run once the testbed is ready + * @param tmain_cls closure for 'tmain' + */ +void +GNUNET_DHT_TEST_run (const char *testname, + const char *cfgname, + unsigned int num_peers, + GNUNET_DHT_TEST_AppMain tmain, + void *tmain_cls) +{ + struct GNUNET_DHT_TEST_Context *ctx; + + ctx = GNUNET_malloc (sizeof (struct GNUNET_DHT_TEST_Context)); + ctx->num_peers = num_peers; + ctx->ops = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *)); + ctx->dhts = GNUNET_malloc (num_peers * sizeof (struct GNUNET_DHT_Handle *)); + ctx->app_main = tmain; + ctx->app_main_cls = tmain_cls; + (void) GNUNET_TESTBED_test_run (testname, + cfgname, + num_peers, + 0LL, NULL, NULL, + &dht_test_run, ctx); +} + +/* end of dht_test_lib.c */ diff --git a/src/dht/dht_test_lib.h b/src/dht/dht_test_lib.h new file mode 100644 index 0000000..061794a --- /dev/null +++ b/src/dht/dht_test_lib.h @@ -0,0 +1,95 @@ +/* + 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 dht/dht_test_lib.h + * @author Christian Grothoff + * @brief library for writing DHT tests + */ +#ifndef DHT_TEST_LIB_H +#define DHT_TEST_LIB_H + +#ifdef __cplusplus +extern "C" +{ +#if 0 /* keep Emacsens' auto-indent happy */ +} +#endif +#endif + +#include "gnunet_testbed_service.h" +#include "gnunet_dht_service.h" + +/** + * Test context for a DHT Test. + */ +struct GNUNET_DHT_TEST_Context; + + +/** + * Main function of a DHT test. + * + * @param cls closure + * @param ctx argument to give to GNUNET_DHT_TEST_cleanup on test end + * @param num_peers number of peers that are running + * @param peers array of peers + * @param dhts handle to each of the DHTs of the peers + */ +typedef void (*GNUNET_DHT_TEST_AppMain) (void *cls, + struct GNUNET_DHT_TEST_Context *ctx, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, + struct GNUNET_DHT_Handle **dhts); + + +/** + * Run a test using the given name, configuration file and number of + * peers. + * + * @param testname name of the test (for logging) + * @param cfgname name of the configuration file + * @param num_peers number of peers to start + * @param tmain main function to run once the testbed is ready + * @param tmain_cls closure for 'tmain' + */ +void +GNUNET_DHT_TEST_run (const char *testname, + const char *cfgname, + unsigned int num_peers, + GNUNET_DHT_TEST_AppMain tmain, + void *tmain_cls); + + +/** + * Clean up the testbed. + * + * @param ctx handle for the testbed + */ +void +GNUNET_DHT_TEST_cleanup (struct GNUNET_DHT_TEST_Context *ctx); + +#if 0 /* keep Emacsens' auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif + +/* ifndef DHT_TEST_LIB_H */ +#endif diff --git a/src/dht/gnunet-dht-get.c b/src/dht/gnunet-dht-get.c index fb185c4..345a58a 100644 --- a/src/dht/gnunet-dht-get.c +++ b/src/dht/gnunet-dht-get.c @@ -42,19 +42,19 @@ static unsigned int replication = 5; static char *query_key; /** - * User supplied timeout value (in seconds) + * User supplied timeout value */ -static unsigned long long timeout_request = 5; +static struct GNUNET_TIME_Relative timeout_request = { 60000 }; /** - * When this request should really die + * Be verbose */ -struct GNUNET_TIME_Absolute absolute_timeout; +static int verbose; /** - * Be verbose + * Use DHT demultixplex_everywhere */ -static int verbose; +static int demultixplex_everywhere; /** * Handle to the DHT @@ -82,26 +82,25 @@ static unsigned int result_count; static int ret; -static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - if (dht_handle != NULL) - { - GNUNET_DHT_disconnect (dht_handle); - dht_handle = NULL; - } -} - - +/** + * Task run to clean up on timeout. + * + * @param cls unused + * @param tc unused + */ static void cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - if (get_handle != NULL) + if (NULL != get_handle) { GNUNET_DHT_get_stop (get_handle); get_handle = NULL; } - GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + if (NULL != dht_handle) + { + GNUNET_DHT_disconnect (dht_handle); + dht_handle = NULL; + } } @@ -122,14 +121,16 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) */ static void get_result_iterator (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, unsigned int put_path_length, enum GNUNET_BLOCK_Type type, size_t size, const void *data) { - FPRINTF (stdout, "Result %d, type %d:\n%.*s\n", result_count, type, + FPRINTF (stdout, + _("Result %d, type %d:\n%.*s\n"), + result_count, type, (unsigned int) size, (char *) data); result_count++; } @@ -147,48 +148,32 @@ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - struct GNUNET_TIME_Relative timeout; - GNUNET_HashCode key; + struct GNUNET_HashCode key; cfg = c; - - if (query_key == NULL) + if (NULL == query_key) { - if (verbose) - FPRINTF (stderr, "%s", "Must provide key for DHT GET!\n"); + FPRINTF (stderr, "%s", _("Must provide key for DHT GET!\n")); ret = 1; return; } - - dht_handle = GNUNET_DHT_connect (cfg, 1); - - if (dht_handle == NULL) + if (NULL == (dht_handle = GNUNET_DHT_connect (cfg, 1))) { - if (verbose) - FPRINTF (stderr, "%s", "Couldn't connect to DHT service!\n"); + FPRINTF (stderr, "%s", _("Failed to connect to DHT service!\n")); ret = 1; return; } - else if (verbose) - FPRINTF (stderr, "%s", "Connected to DHT service!\n"); - if (query_type == GNUNET_BLOCK_TYPE_ANY) /* Type of data not set */ query_type = GNUNET_BLOCK_TYPE_TEST; - GNUNET_CRYPTO_hash (query_key, strlen (query_key), &key); - - timeout = - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, timeout_request); - absolute_timeout = GNUNET_TIME_relative_to_absolute (timeout); - if (verbose) - FPRINTF (stderr, "Issuing GET request for %s!\n", query_key); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining - (absolute_timeout), &cleanup_task, NULL); + FPRINTF (stderr, "%s `%s' \n", _("Issueing DHT GET with key"), GNUNET_h2s_full (&key)); + GNUNET_SCHEDULER_add_delayed (timeout_request, + &cleanup_task, NULL); get_handle = GNUNET_DHT_get_start (dht_handle, query_type, &key, replication, - GNUNET_DHT_RO_NONE, NULL, 0, &get_result_iterator, - NULL); + (demultixplex_everywhere) ? GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE : GNUNET_DHT_RO_NONE, + NULL, 0, &get_result_iterator, NULL); } @@ -208,7 +193,10 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = { 1, &GNUNET_GETOPT_set_uint, &query_type}, {'T', "timeout", "TIMEOUT", gettext_noop ("how long to execute this query before giving up?"), - 1, &GNUNET_GETOPT_set_ulong, &timeout_request}, + 1, &GNUNET_GETOPT_set_relative_time, &timeout_request}, + {'x', "demultiplex", NULL, + gettext_noop ("use DHT's demultiplex everywhere option"), + 0, &GNUNET_GETOPT_set_one, &demultixplex_everywhere}, {'V', "verbose", NULL, gettext_noop ("be verbose (print progress information)"), 0, &GNUNET_GETOPT_set_one, &verbose}, @@ -226,6 +214,8 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = { int main (int argc, char *const *argv) { + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; return (GNUNET_OK == GNUNET_PROGRAM_run (argc, argv, "gnunet-dht-get", gettext_noop diff --git a/src/dht/gnunet-dht-monitor.c b/src/dht/gnunet-dht-monitor.c index 8ca3beb..b03c7c7 100644 --- a/src/dht/gnunet-dht-monitor.c +++ b/src/dht/gnunet-dht-monitor.c @@ -39,7 +39,7 @@ static char *query_key; /** * User supplied timeout value (in seconds) */ -static unsigned long long timeout_request = 5; +static struct GNUNET_TIME_Relative timeout_request = { 60000 }; /** * Be verbose @@ -73,25 +73,6 @@ static int ret; /** - * Function called on shutdown, disconnects from DHT if necessary. - * - * @param cls closure (unused) - * @param tc Task Context - */ -static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - if (verbose) - FPRINTF (stderr, "%s", "Shutting down!\n"); - if (dht_handle != NULL) - { - GNUNET_DHT_disconnect (dht_handle); - dht_handle = NULL; - } -} - - -/** * Stop monitoring request and start shutdown * * @param cls closure (unused) @@ -102,12 +83,16 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { if (verbose) FPRINTF (stderr, "%s", "Cleaning up!\n"); - if (monitor_handle != NULL) + if (NULL != monitor_handle) { GNUNET_DHT_monitor_stop (monitor_handle); monitor_handle = NULL; } - GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + if (NULL != dht_handle) + { + GNUNET_DHT_disconnect (dht_handle); + dht_handle = NULL; + } } @@ -131,16 +116,16 @@ get_callback (void *cls, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, - const GNUNET_HashCode * key) + const struct GNUNET_HashCode * key) { - FPRINTF (stdout, "Result %d, operation: %s, type %d\n Key: %s", + FPRINTF (stdout, "GET #%u: type %d, key `%s'\n", result_count, - "GET", - type, + (int) type, GNUNET_h2s_full(key)); result_count++; } + /** * Callback called on each GET reply going through the DHT. * @@ -163,20 +148,21 @@ get_resp_callback (void *cls, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, const void *data, size_t size) { - FPRINTF (stdout, "Result %d, operation: %s, type %d:\n Key: %s\n %.*s\n", + FPRINTF (stdout, + "RESPONSE #%u: type %d, key `%s', data `%.*s'\n", result_count, - "GET_RESP", - type, - GNUNET_h2s_full(key), + (int) type, + GNUNET_h2s_full (key), (unsigned int) size, (char *) data); result_count++; } + /** * Callback called on each PUT request going through the DHT. * @@ -201,20 +187,21 @@ put_callback (void *cls, unsigned int path_length, const struct GNUNET_PeerIdentity *path, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, const void *data, size_t size) { - FPRINTF (stdout, "Result %d, operation: %s, type %d:\n Key: %s\n %.*s\n", + FPRINTF (stdout, + "PUT %u: type %d, key `%s', data `%.*s'\n", result_count, - "PUT", - type, + (int) type, GNUNET_h2s_full(key), (unsigned int) size, (char *) data); result_count++; } + /** * Main function that will be run by the scheduler. * @@ -227,50 +214,36 @@ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - struct GNUNET_TIME_Relative timeout; - GNUNET_HashCode *key; + struct GNUNET_HashCode *key; + struct GNUNET_HashCode hc; cfg = c; - dht_handle = GNUNET_DHT_connect (cfg, 1); - - if (dht_handle == NULL) + if (NULL == (dht_handle = GNUNET_DHT_connect (cfg, 1))) { - if (verbose) - FPRINTF (stderr, "%s", "Couldn't connect to DHT service!\n"); + FPRINTF (stderr, "%s", + _("Failed to connect to DHT service!\n")); ret = 1; return; } - else if (verbose) - FPRINTF (stderr, "%s", "Connected to DHT service!\n"); - - if (block_type == GNUNET_BLOCK_TYPE_ANY) /* Type of data not set */ + if (GNUNET_BLOCK_TYPE_ANY == block_type) /* Type of data not set */ block_type = GNUNET_BLOCK_TYPE_TEST; - - if (query_key != NULL) { - key = GNUNET_malloc (sizeof(GNUNET_HashCode)); - GNUNET_CRYPTO_hash (query_key, strlen (query_key), key); - } - else - key = NULL; - - if (0 != timeout_request) - { - timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, - timeout_request); - if (verbose) - FPRINTF (stderr, "Monitoring for %llus\n", timeout_request); - } + if (NULL != query_key) + { + key = &hc; + if (GNUNET_OK != + GNUNET_CRYPTO_hash_from_string (query_key, key)) + GNUNET_CRYPTO_hash (query_key, strlen (query_key), key); + } else - { - timeout = GNUNET_TIME_UNIT_FOREVER_REL; - if (verbose) - FPRINTF (stderr, "%s", "Monitoring indefinitely (close with Ctrl+C)\n"); - } - - GNUNET_SCHEDULER_add_delayed (timeout, &cleanup_task, NULL); + { + key = NULL; + } if (verbose) - FPRINTF (stderr, "Issuing MONITOR request for %s!\n", query_key); + FPRINTF (stderr, + "Monitoring for %s\n", + GNUNET_STRINGS_relative_time_to_string (timeout_request, GNUNET_NO)); + GNUNET_SCHEDULER_add_delayed (timeout_request, &cleanup_task, NULL); monitor_handle = GNUNET_DHT_monitor_start (dht_handle, block_type, key, @@ -278,15 +251,11 @@ run (void *cls, char *const *args, const char *cfgfile, &get_resp_callback, &put_callback, NULL); - if (verbose) - FPRINTF (stderr, "%s", "MONITOR started!\n"); - GNUNET_free_non_null (key); - } /** - * gnunet-dht-get command line options + * gnunet-dht-monitor command line options */ static struct GNUNET_GETOPT_CommandLineOption options[] = { {'k', "key", "KEY", @@ -296,8 +265,8 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = { gettext_noop ("the type of data to look for"), 1, &GNUNET_GETOPT_set_uint, &block_type}, {'T', "timeout", "TIMEOUT", - gettext_noop ("how long to execute? 0 = forever"), - 1, &GNUNET_GETOPT_set_ulong, &timeout_request}, + gettext_noop ("how long should the monitor command run"), + 1, &GNUNET_GETOPT_set_relative_time, &timeout_request}, {'V', "verbose", NULL, gettext_noop ("be verbose (print progress information)"), 0, &GNUNET_GETOPT_set_one, &verbose}, @@ -315,8 +284,11 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = { int main (int argc, char *const *argv) { + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-dht-get", + GNUNET_PROGRAM_run (argc, argv, "gnunet-dht-monitor", gettext_noop ("Prints all packets that go through the DHT."), options, &run, NULL)) ? ret : 1; diff --git a/src/dht/gnunet-dht-put.c b/src/dht/gnunet-dht-put.c index 59acc79..67884c4 100644 --- a/src/dht/gnunet-dht-put.c +++ b/src/dht/gnunet-dht-put.c @@ -32,6 +32,11 @@ static unsigned int query_type; /** + * The key used in the DHT + */ +struct GNUNET_HashCode key; + +/** * The key for the query */ static char *query_key; @@ -57,6 +62,11 @@ static unsigned int replication = 5; static int verbose; /** + * Use DHT demultixplex_everywhere + */ +static int demultixplex_everywhere; + +/** * Handle to the DHT */ static struct GNUNET_DHT_Handle *dht_handle; @@ -105,7 +115,7 @@ message_sent_cont (void *cls, int success) switch (success) { case GNUNET_OK: - FPRINTF (stderr, "%s", _("PUT request sent!\n")); + FPRINTF (stderr, "%s `%s'!\n", _("PUT request sent with key"), GNUNET_h2s_full(&key)); break; case GNUNET_NO: FPRINTF (stderr, "%s", _("Timeout sending PUT request!\n")); @@ -135,28 +145,23 @@ run (void *cls, char *const *args, const char *cfgfile, { struct GNUNET_TIME_Relative timeout; struct GNUNET_TIME_Absolute expiration; - GNUNET_HashCode key; cfg = c; - if ((query_key == NULL) || (data == NULL)) + if ((NULL == query_key) || (NULL == data)) { FPRINTF (stderr, "%s", _("Must provide KEY and DATA for DHT put!\n")); ret = 1; return; } - dht_handle = GNUNET_DHT_connect (cfg, 1); - if (dht_handle == NULL) + if (NULL == (dht_handle = GNUNET_DHT_connect (cfg, 1))) { FPRINTF (stderr, _("Could not connect to %s service!\n"), "DHT"); ret = 1; return; } - else if (verbose) - FPRINTF (stderr, _("Connected to %s service!\n"), "DHT"); - - if (query_type == GNUNET_BLOCK_TYPE_ANY) /* Type of data not set */ + if (GNUNET_BLOCK_TYPE_ANY == query_type) /* Type of data not set */ query_type = GNUNET_BLOCK_TYPE_TEST; GNUNET_CRYPTO_hash (query_key, strlen (query_key), &key); @@ -167,11 +172,12 @@ run (void *cls, char *const *args, const char *cfgfile, GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, expiration_seconds)); - if (verbose) FPRINTF (stderr, _("Issuing put request for `%s' with data `%s'!\n"), query_key, data); - GNUNET_DHT_put (dht_handle, &key, replication, GNUNET_DHT_RO_NONE, query_type, + GNUNET_DHT_put (dht_handle, &key, replication, + (demultixplex_everywhere) ? GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE : GNUNET_DHT_RO_NONE, + query_type, strlen (data), data, expiration, timeout, &message_sent_cont, NULL); @@ -191,6 +197,9 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = { {'k', "key", "KEY", gettext_noop ("the query key"), 1, &GNUNET_GETOPT_set_string, &query_key}, + {'x', "demultiplex", NULL, + gettext_noop ("use DHT's demultiplex everywhere option"), + 0, &GNUNET_GETOPT_set_one, &demultixplex_everywhere}, {'r', "replication", "LEVEL", gettext_noop ("how many replicas to create"), 1, &GNUNET_GETOPT_set_uint, &replication}, @@ -217,6 +226,9 @@ static struct GNUNET_GETOPT_CommandLineOption options[] = { int main (int argc, char *const *argv) { + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + return (GNUNET_OK == GNUNET_PROGRAM_run (argc, argv, "gnunet-dht-put", gettext_noop diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c index 72575ac..5efa9dd 100644 --- a/src/dht/gnunet-service-dht.c +++ b/src/dht/gnunet-service-dht.c @@ -66,12 +66,16 @@ struct GNUNET_MessageHeader *GDS_my_hello; */ struct GNUNET_TRANSPORT_Handle *GDS_transport_handle; - /** * Handle to get our current HELLO. */ static struct GNUNET_TRANSPORT_GetHelloHandle *ghh; +/** + * Hello address expiration + */ +struct GNUNET_TIME_Relative hello_expiration; + /** * Receive the HELLO from transport service, free current and replace @@ -141,6 +145,11 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, const struct GNUNET_CONFIGURATION_Handle *c) { GDS_cfg = c; + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_time (c, "transport", "HELLO_EXPIRATION", &hello_expiration)) + { + hello_expiration = GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION; + } GDS_block_context = GNUNET_BLOCK_context_create (GDS_cfg); GDS_stats = GNUNET_STATISTICS_create ("dht", GDS_cfg); GDS_ROUTING_init (); diff --git a/src/dht/gnunet-service-dht_clients.c b/src/dht/gnunet-service-dht_clients.c index d897d1f..3d9d5be 100644 --- a/src/dht/gnunet-service-dht_clients.c +++ b/src/dht/gnunet-service-dht_clients.c @@ -37,6 +37,12 @@ /** + * Should routing details be logged to stderr (for debugging)? + */ +#define LOG_ROUTE_DETAILS_STDERR GNUNET_NO + + +/** * Linked list of messages to send to clients. */ struct PendingMessage @@ -111,7 +117,7 @@ struct ClientQueryRecord /** * The key this request was about */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /** * Client responsible for the request. @@ -126,7 +132,7 @@ struct ClientQueryRecord /** * Replies we have already seen for this request. */ - GNUNET_HashCode *seen_replies; + struct GNUNET_HashCode *seen_replies; /** * Pointer to this nodes heap location in the retry-heap (for fast removal) @@ -201,7 +207,7 @@ struct ClientMonitorRecord /** * Key of data of interest, NULL for all. */ - GNUNET_HashCode *key; + struct GNUNET_HashCode *key; /** * Flag whether to notify about GET messages. @@ -322,7 +328,7 @@ find_active_client (struct GNUNET_SERVER_Client *client) * @return GNUNET_YES (we should continue to iterate) */ static int -remove_client_records (void *cls, const GNUNET_HashCode * key, void *value) +remove_client_records (void *cls, const struct GNUNET_HashCode * key, void *value) { struct ClientList *client = cls; struct ClientQueryRecord *record = value; @@ -423,10 +429,7 @@ transmit_request (struct ClientQueryRecord *cqr) GNUNET_CONTAINER_bloomfilter_free (peer_bf); /* exponential back-off for retries, max 1h */ - cqr->retry_frequency = - GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_HOURS, - GNUNET_TIME_relative_multiply - (cqr->retry_frequency, 2)); + cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency); cqr->retry_time = GNUNET_TIME_relative_to_absolute (cqr->retry_frequency); } @@ -551,9 +554,7 @@ handle_dht_local_put (void *cls, struct GNUNET_SERVER_Client *client, /** - * Handler for any generic DHT messages, calls the appropriate handler - * depending on message type, sends confirmation if responses aren't otherwise - * expected. + * Handler for DHT GET messages from the client. * * @param cls closure for the service * @param client the client we received this message from @@ -586,19 +587,30 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received request for %s from local client %p\n", GNUNET_h2s (&get->key), client); + + if (LOG_ROUTE_DETAILS_STDERR) + { + fprintf (stderr, + "XDHT CLIENT-GET %s @ %u\n", + GNUNET_h2s (&get->key), + getpid ()); + } + + cqr = GNUNET_malloc (sizeof (struct ClientQueryRecord) + xquery_size); cqr->key = get->key; cqr->client = find_active_client (client); cqr->xquery = (void *) &cqr[1]; memcpy (&cqr[1], xquery, xquery_size); cqr->hnode = GNUNET_CONTAINER_heap_insert (retry_heap, cqr, 0); - cqr->retry_frequency = GNUNET_TIME_UNIT_MILLISECONDS; + cqr->retry_frequency = GNUNET_TIME_UNIT_SECONDS; cqr->retry_time = GNUNET_TIME_absolute_get (); cqr->unique_id = get->unique_id; cqr->xquery_size = xquery_size; cqr->replication = ntohl (get->desired_replication_level); cqr->msg_options = ntohl (get->options); cqr->type = ntohl (get->type); + // FIXME use cqr->key, set multihashmap create to GNUNET_YES GNUNET_CONTAINER_multihashmap_put (forward_map, &get->key, cqr, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); GDS_CLIENTS_process_get (ntohl (get->options), @@ -620,6 +632,103 @@ handle_dht_local_get (void *cls, struct GNUNET_SERVER_Client *client, /** + * Closure for 'find_by_unique_id'. + */ +struct FindByUniqueIdContext +{ + /** + * Where to store the result, if found. + */ + struct ClientQueryRecord *cqr; + + uint64_t unique_id; +}; + + +/** + * Function called for each existing DHT record for the given + * query. Checks if it matches the UID given in the closure + * and if so returns the entry as a result. + * + * @param cls the search context + * @param key query for the lookup (not used) + * @param value the 'struct ClientQueryRecord' + * @return GNUNET_YES to continue iteration (result not yet found) + */ +static int +find_by_unique_id (void *cls, + const struct GNUNET_HashCode *key, + void *value) +{ + struct FindByUniqueIdContext *fui_ctx = cls; + struct ClientQueryRecord *cqr = value; + + if (cqr->unique_id != fui_ctx->unique_id) + return GNUNET_YES; + fui_ctx->cqr = cqr; + return GNUNET_NO; +} + + +/** + * Handler for "GET result seen" messages from the client. + * + * @param cls closure for the service + * @param client the client we received this message from + * @param message the actual message received + */ +static void +handle_dht_local_get_result_seen (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct GNUNET_DHT_ClientGetResultSeenMessage *seen; + uint16_t size; + unsigned int hash_count; + unsigned int old_count; + const struct GNUNET_HashCode *hc; + struct FindByUniqueIdContext fui_ctx; + struct ClientQueryRecord *cqr; + + size = ntohs (message->size); + if (size < sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + seen = (const struct GNUNET_DHT_ClientGetResultSeenMessage *) message; + hash_count = (size - sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage)) / sizeof (struct GNUNET_HashCode); + if (size != sizeof (struct GNUNET_DHT_ClientGetResultSeenMessage) + hash_count * sizeof (struct GNUNET_HashCode)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + hc = (const struct GNUNET_HashCode*) &seen[1]; + fui_ctx.unique_id = seen->unique_id; + fui_ctx.cqr = NULL; + GNUNET_CONTAINER_multihashmap_get_multiple (forward_map, + &seen->key, + &find_by_unique_id, + &fui_ctx); + if (NULL == (cqr = fui_ctx.cqr)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + /* finally, update 'seen' list */ + old_count = cqr->seen_replies_count; + GNUNET_array_grow (cqr->seen_replies, + cqr->seen_replies_count, + cqr->seen_replies_count + hash_count); + memcpy (&cqr->seen_replies[old_count], + hc, + sizeof (struct GNUNET_HashCode) * hash_count); +} + + +/** * Closure for 'remove_by_unique_id'. */ struct RemoveByUniqueIdContext @@ -646,7 +755,7 @@ struct RemoveByUniqueIdContext * @return GNUNET_YES (we should continue to iterate) */ static int -remove_by_unique_id (void *cls, const GNUNET_HashCode * key, void *value) +remove_by_unique_id (void *cls, const struct GNUNET_HashCode * key, void *value) { const struct RemoveByUniqueIdContext *ctx = cls; struct ClientQueryRecord *record = value; @@ -718,8 +827,8 @@ handle_dht_local_monitor (void *cls, struct GNUNET_SERVER_Client *client, r->key = NULL; else { - r->key = GNUNET_malloc (sizeof (GNUNET_HashCode)); - memcpy (r->key, &msg->key, sizeof (GNUNET_HashCode)); + r->key = GNUNET_malloc (sizeof (struct GNUNET_HashCode)); + memcpy (r->key, &msg->key, sizeof (struct GNUNET_HashCode)); } GNUNET_CONTAINER_DLL_insert (monitor_head, monitor_tail, r); GNUNET_SERVER_receive_done (client, GNUNET_OK); @@ -751,7 +860,7 @@ handle_dht_local_monitor_stop (void *cls, struct GNUNET_SERVER_Client *client, else { keys_match = (0 != ntohs(msg->filter_key) - && !memcmp(r->key, &msg->key, sizeof(GNUNET_HashCode))); + && !memcmp(r->key, &msg->key, sizeof(struct GNUNET_HashCode))); } if (find_active_client(client) == r->client && ntohl(msg->type) == r->type @@ -898,7 +1007,7 @@ struct ForwardReplyContext * if the result is mal-formed, GNUNET_NO */ static int -forward_reply (void *cls, const GNUNET_HashCode * key, void *value) +forward_reply (void *cls, const struct GNUNET_HashCode * key, void *value) { struct ForwardReplyContext *frc = cls; struct ClientQueryRecord *record = value; @@ -906,9 +1015,16 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value) struct GNUNET_DHT_ClientResultMessage *reply; enum GNUNET_BLOCK_EvaluationResult eval; int do_free; - GNUNET_HashCode ch; + struct GNUNET_HashCode ch; unsigned int i; + if (LOG_ROUTE_DETAILS_STDERR) + { + fprintf (stderr, + "XDHT CLIENT-RESULT %s @ %u\n", + GNUNET_h2s (key), + getpid ()); + } if ((record->type != GNUNET_BLOCK_TYPE_ANY) && (record->type != frc->type)) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -922,7 +1038,7 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value) } GNUNET_CRYPTO_hash (frc->data, frc->data_size, &ch); for (i = 0; i < record->seen_replies_count; i++) - if (0 == memcmp (&record->seen_replies[i], &ch, sizeof (GNUNET_HashCode))) + if (0 == memcmp (&record->seen_replies[i], &ch, sizeof (struct GNUNET_HashCode))) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Duplicate reply, not passing request for key %s to local client\n", @@ -962,6 +1078,8 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value) case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: GNUNET_break (0); return GNUNET_NO; + case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: + return GNUNET_YES; case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Unsupported block type (%u) in request!\n"), record->type); @@ -984,6 +1102,7 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value) memcpy (pm, frc->pm, sizeof (struct PendingMessage) + ntohs (frc->pm->msg->size)); pm->next = pm->prev = NULL; + pm->msg = (struct GNUNET_MessageHeader *) &pm[1]; } GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# RESULTS queued for clients"), 1, @@ -1017,7 +1136,7 @@ forward_reply (void *cls, const GNUNET_HashCode * key, void *value) */ void GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode *key, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length, @@ -1048,8 +1167,7 @@ GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, _("Could not pass reply to client, message too big!\n")); return; } - pm = (struct PendingMessage *) GNUNET_malloc (msize + - sizeof (struct PendingMessage)); + pm = GNUNET_malloc (msize + sizeof (struct PendingMessage)); reply = (struct GNUNET_DHT_ClientResultMessage *) &pm[1]; pm->msg = &reply->header; reply->header.size = htons ((uint16_t) msize); @@ -1104,7 +1222,7 @@ GDS_CLIENTS_process_get (uint32_t options, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, - const GNUNET_HashCode * key) + const struct GNUNET_HashCode * key) { struct ClientMonitorRecord *m; struct ClientList **cl; @@ -1116,7 +1234,7 @@ GDS_CLIENTS_process_get (uint32_t options, { if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && (NULL == m->key || - memcmp (key, m->key, sizeof(GNUNET_HashCode)) == 0)) + memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0)) { struct PendingMessage *pm; struct GNUNET_DHT_MonitorGetMessage *mmsg; @@ -1135,7 +1253,7 @@ GDS_CLIENTS_process_get (uint32_t options, msize = path_length * sizeof (struct GNUNET_PeerIdentity); msize += sizeof (struct GNUNET_DHT_MonitorGetMessage); msize += sizeof (struct PendingMessage); - pm = (struct PendingMessage *) GNUNET_malloc (msize); + pm = GNUNET_malloc (msize); mmsg = (struct GNUNET_DHT_MonitorGetMessage *) &pm[1]; pm->msg = &mmsg->header; mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); @@ -1145,7 +1263,7 @@ GDS_CLIENTS_process_get (uint32_t options, mmsg->hop_count = htonl(hop_count); mmsg->desired_replication_level = htonl(desired_replication_level); mmsg->get_path_length = htonl(path_length); - memcpy (&mmsg->key, key, sizeof (GNUNET_HashCode)); + memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode)); msg_path = (struct GNUNET_PeerIdentity *) &mmsg[1]; if (path_length > 0) memcpy (msg_path, path, @@ -1178,7 +1296,7 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, const void *data, size_t size) { @@ -1192,7 +1310,7 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, { if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && (NULL == m->key || - memcmp (key, m->key, sizeof(GNUNET_HashCode)) == 0)) + memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0)) { struct PendingMessage *pm; struct GNUNET_DHT_MonitorGetRespMessage *mmsg; @@ -1213,7 +1331,7 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, * sizeof (struct GNUNET_PeerIdentity); msize += sizeof (struct GNUNET_DHT_MonitorGetRespMessage); msize += sizeof (struct PendingMessage); - pm = (struct PendingMessage *) GNUNET_malloc (msize); + pm = GNUNET_malloc (msize); mmsg = (struct GNUNET_DHT_MonitorGetRespMessage *) &pm[1]; pm->msg = (struct GNUNET_MessageHeader *) mmsg; mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); @@ -1232,7 +1350,7 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, memcpy (path, get_path, get_path_length * sizeof (struct GNUNET_PeerIdentity)); mmsg->expiration_time = GNUNET_TIME_absolute_hton(exp); - memcpy (&mmsg->key, key, sizeof (GNUNET_HashCode)); + memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode)); if (size > 0) memcpy (&path[get_path_length], data, size); add_pending_message (m->client, pm); @@ -1265,7 +1383,7 @@ GDS_CLIENTS_process_put (uint32_t options, unsigned int path_length, const struct GNUNET_PeerIdentity *path, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, const void *data, size_t size) { @@ -1279,7 +1397,7 @@ GDS_CLIENTS_process_put (uint32_t options, { if ((GNUNET_BLOCK_TYPE_ANY == m->type || m->type == type) && (NULL == m->key || - memcmp (key, m->key, sizeof(GNUNET_HashCode)) == 0)) + memcmp (key, m->key, sizeof(struct GNUNET_HashCode)) == 0)) { struct PendingMessage *pm; struct GNUNET_DHT_MonitorPutMessage *mmsg; @@ -1299,7 +1417,7 @@ GDS_CLIENTS_process_put (uint32_t options, msize += path_length * sizeof (struct GNUNET_PeerIdentity); msize += sizeof (struct GNUNET_DHT_MonitorPutMessage); msize += sizeof (struct PendingMessage); - pm = (struct PendingMessage *) GNUNET_malloc (msize); + pm = GNUNET_malloc (msize); mmsg = (struct GNUNET_DHT_MonitorPutMessage *) &pm[1]; pm->msg = (struct GNUNET_MessageHeader *) mmsg; mmsg->header.size = htons (msize - sizeof (struct PendingMessage)); @@ -1316,7 +1434,7 @@ GDS_CLIENTS_process_put (uint32_t options, path_length * sizeof (struct GNUNET_PeerIdentity)); } mmsg->expiration_time = GNUNET_TIME_absolute_hton(exp); - memcpy (&mmsg->key, key, sizeof (GNUNET_HashCode)); + memcpy (&mmsg->key, key, sizeof (struct GNUNET_HashCode)); if (size > 0) memcpy (&msg_path[path_length], data, size); add_pending_message (m->client, pm); @@ -1348,9 +1466,11 @@ GDS_CLIENTS_init (struct GNUNET_SERVER_Handle *server) {&handle_dht_local_monitor_stop, NULL, GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP, sizeof (struct GNUNET_DHT_MonitorStartStopMessage)}, + {&handle_dht_local_get_result_seen, NULL, + GNUNET_MESSAGE_TYPE_DHT_CLIENT_GET_RESULTS_KNOWN, 0}, {NULL, NULL, 0, 0} }; - forward_map = GNUNET_CONTAINER_multihashmap_create (1024); + forward_map = GNUNET_CONTAINER_multihashmap_create (1024, GNUNET_NO); retry_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); GNUNET_SERVER_add_handlers (server, plugin_handlers); GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); diff --git a/src/dht/gnunet-service-dht_clients.h b/src/dht/gnunet-service-dht_clients.h index 9f3d2dd..f6d4253 100644 --- a/src/dht/gnunet-service-dht_clients.h +++ b/src/dht/gnunet-service-dht_clients.h @@ -47,7 +47,7 @@ */ void GDS_CLIENTS_handle_reply (struct GNUNET_TIME_Absolute expiration, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, unsigned int put_path_length, @@ -75,7 +75,7 @@ GDS_CLIENTS_process_get (uint32_t options, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, - const GNUNET_HashCode * key); + const struct GNUNET_HashCode * key); /** * Check if some client is monitoring GET RESP messages and notify @@ -98,7 +98,7 @@ GDS_CLIENTS_process_get_resp (enum GNUNET_BLOCK_Type type, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, const void *data, size_t size); @@ -125,7 +125,7 @@ GDS_CLIENTS_process_put (uint32_t options, unsigned int path_length, const struct GNUNET_PeerIdentity *path, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, const void *data, size_t size); diff --git a/src/dht/gnunet-service-dht_datacache.c b/src/dht/gnunet-service-dht_datacache.c index 4d1dd6f..87c93f5 100644 --- a/src/dht/gnunet-service-dht_datacache.c +++ b/src/dht/gnunet-service-dht_datacache.c @@ -39,28 +39,6 @@ static struct GNUNET_DATACACHE_Handle *datacache; /** - * Entry for inserting data into datacache from the DHT. - */ -struct DHTPutEntry -{ - /** - * Size of data. - */ - uint16_t data_size; - - /** - * Length of recorded path. - */ - uint16_t path_length; - - /* PATH ENTRIES */ - - /* PUT DATA */ - -}; - - -/** * Handle a datum we've received from another peer. Cache if * possible. * @@ -74,20 +52,13 @@ struct DHTPutEntry */ void GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, const void *data) { - size_t plen = - data_size + put_path_length * sizeof (struct GNUNET_PeerIdentity) + - sizeof (struct DHTPutEntry); - char buf[plen]; - struct DHTPutEntry *pe; - struct GNUNET_PeerIdentity *pp; - - if (datacache == NULL) + if (NULL == datacache) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("%s request received, but have no datacache!\n"), "PUT"); @@ -102,14 +73,9 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# ITEMS stored in datacache"), 1, GNUNET_NO); - pe = (struct DHTPutEntry *) buf; - pe->data_size = htons (data_size); - pe->path_length = htons ((uint16_t) put_path_length); - pp = (struct GNUNET_PeerIdentity *) &pe[1]; - memcpy (pp, put_path, put_path_length * sizeof (struct GNUNET_PeerIdentity)); - memcpy (&pp[put_path_length], data, data_size); - (void) GNUNET_DATACACHE_put (datacache, key, plen, (const char *) pe, type, - expiration); + (void) GNUNET_DATACACHE_put (datacache, key, + data_size, data, type, + expiration, put_path_length, put_path); } @@ -131,7 +97,7 @@ struct GetRequestContext /** * The key this request was about */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /** * Number of bytes in xquery. @@ -159,40 +125,26 @@ struct GetRequestContext * @param size the size of the data identified by key * @param data the actual data * @param type the type of the data - * + * @param put_path_length number of peers in 'put_path' + * @param put_path path the reply took on put * @return GNUNET_OK to continue iteration, anything else * to stop iteration. */ static int -datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, size_t size, - const char *data, enum GNUNET_BLOCK_Type type) +datacache_get_iterator (void *cls, + const struct GNUNET_HashCode * key, size_t size, + const char *data, enum GNUNET_BLOCK_Type type, + struct GNUNET_TIME_Absolute exp, + unsigned int put_path_length, + const struct GNUNET_PeerIdentity *put_path) { struct GetRequestContext *ctx = cls; - const struct DHTPutEntry *pe; - const struct GNUNET_PeerIdentity *pp; - const char *rdata; - size_t rdata_size; - uint16_t put_path_length; enum GNUNET_BLOCK_EvaluationResult eval; - pe = (const struct DHTPutEntry *) data; - put_path_length = ntohs (pe->path_length); - rdata_size = ntohs (pe->data_size); - - if (size != - sizeof (struct DHTPutEntry) + rdata_size + - (put_path_length * sizeof (struct GNUNET_PeerIdentity))) - { - GNUNET_break (0); - return GNUNET_OK; - } - pp = (const struct GNUNET_PeerIdentity *) &pe[1]; - rdata = (const char *) &pp[put_path_length]; eval = GNUNET_BLOCK_evaluate (GDS_block_context, type, key, ctx->reply_bf, ctx->reply_bf_mutator, ctx->xquery, - ctx->xquery_size, rdata, rdata_size); + ctx->xquery_size, data, size); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found reply for query %s in datacache, evaluation result is %d\n", GNUNET_h2s (key), (int) eval); @@ -206,11 +158,11 @@ datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, gettext_noop ("# Good RESULTS found in datacache"), 1, GNUNET_NO); - GDS_CLIENTS_handle_reply (exp, key, 0, NULL, put_path_length, pp, type, - rdata_size, rdata); + GDS_CLIENTS_handle_reply (exp, key, 0, NULL, put_path_length, put_path, type, + size, data); /* forward to other peers */ - GDS_ROUTING_process (type, exp, key, put_path_length, pp, 0, NULL, rdata, - rdata_size); + GDS_ROUTING_process (type, exp, key, put_path_length, put_path, 0, NULL, data, + size); break; case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: GNUNET_STATISTICS_update (GDS_stats, @@ -224,6 +176,12 @@ datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, ("# Invalid RESULTS found in datacache"), 1, GNUNET_NO); break; + case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: + GNUNET_STATISTICS_update (GDS_stats, + gettext_noop + ("# Irrelevant RESULTS found in datacache"), 1, + GNUNET_NO); + break; case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: GNUNET_break (0); break; @@ -255,7 +213,7 @@ datacache_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, * @return evaluation result for the local replies */ enum GNUNET_BLOCK_EvaluationResult -GDS_DATACACHE_handle_get (const GNUNET_HashCode * key, +GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key, enum GNUNET_BLOCK_Type type, const void *xquery, size_t xquery_size, struct GNUNET_CONTAINER_BloomFilter **reply_bf, diff --git a/src/dht/gnunet-service-dht_datacache.h b/src/dht/gnunet-service-dht_datacache.h index 926ad53..3889883 100644 --- a/src/dht/gnunet-service-dht_datacache.h +++ b/src/dht/gnunet-service-dht_datacache.h @@ -44,7 +44,7 @@ */ void GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, enum GNUNET_BLOCK_Type type, size_t data_size, @@ -63,7 +63,7 @@ GDS_DATACACHE_handle_put (struct GNUNET_TIME_Absolute expiration, * @return evaluation result for the local replies */ enum GNUNET_BLOCK_EvaluationResult -GDS_DATACACHE_handle_get (const GNUNET_HashCode * key, +GDS_DATACACHE_handle_get (const struct GNUNET_HashCode * key, enum GNUNET_BLOCK_Type type, const void *xquery, size_t xquery_size, struct GNUNET_CONTAINER_BloomFilter **reply_bf, diff --git a/src/dht/gnunet-service-dht_hello.c b/src/dht/gnunet-service-dht_hello.c index b9cc450..19da79e 100644 --- a/src/dht/gnunet-service-dht_hello.c +++ b/src/dht/gnunet-service-dht_hello.c @@ -99,7 +99,7 @@ void GDS_HELLO_init () { pnc = GNUNET_PEERINFO_notify (GDS_cfg, &process_hello, NULL); - peer_to_hello = GNUNET_CONTAINER_multihashmap_create (256); + peer_to_hello = GNUNET_CONTAINER_multihashmap_create (256, GNUNET_NO); } @@ -107,7 +107,7 @@ GDS_HELLO_init () * Free memory occopied by the HELLO. */ static int -free_hello (void *cls, const GNUNET_HashCode * key, void *hello) +free_hello (void *cls, const struct GNUNET_HashCode * key, void *hello) { GNUNET_free (hello); return GNUNET_OK; diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index 083b499..4872b58 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c @@ -52,7 +52,7 @@ /** * How many buckets will we allow total. */ -#define MAX_BUCKETS sizeof (GNUNET_HashCode) * 8 +#define MAX_BUCKETS sizeof (struct GNUNET_HashCode) * 8 /** * What is the maximum number of peers in a given bucket. @@ -70,6 +70,11 @@ #define MAXIMUM_REPLICATION_LEVEL 16 /** + * Maximum allowed number of pending messages per peer. + */ +#define MAXIMUM_PENDING_PER_PEER 64 + +/** * How often to update our preference levels for peers in our routing tables. */ #define DHT_DEFAULT_PREFERENCE_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) @@ -89,6 +94,17 @@ */ #define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2) +/** + * Should routing details be logged to stderr (for debugging)? + */ +#define LOG_ROUTE_DETAILS_STDERR GNUNET_NO + + +/** + * Hello address expiration + */ +extern struct GNUNET_TIME_Relative hello_expiration; + GNUNET_NETWORK_STRUCT_BEGIN @@ -140,7 +156,7 @@ struct PeerPutMessage /** * The key we are storing under. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /* put path (if tracked) */ @@ -182,7 +198,7 @@ struct PeerResultMessage /** * The key of the corresponding GET request. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /* put path (if tracked) */ @@ -241,7 +257,7 @@ struct PeerGetMessage /** * The key we are looking for. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /* xquery */ @@ -301,8 +317,7 @@ struct PeerInfo struct PeerInfo *prev; /** - * Count of outstanding messages for peer. FIXME: NEEDED? - * FIXME: bound queue size!? + * Count of outstanding messages for peer. */ unsigned int pending_count; @@ -380,6 +395,11 @@ static unsigned int closest_bucket; static unsigned int newly_found_peers; /** + * Option for testing that disables the 'connect' function of the DHT. + */ +static int disable_try_connect; + +/** * The buckets. Array of size MAX_BUCKET_SIZE. Offset 0 means 0 bits matching. */ static struct PeerBucket k_buckets[MAX_BUCKETS]; @@ -424,7 +444,7 @@ static struct GNUNET_ATS_PerformanceHandle *atsAPI; * on error (same hashcode) */ static int -find_bucket (const GNUNET_HashCode * hc) +find_bucket (const struct GNUNET_HashCode * hc) { unsigned int bits; @@ -518,10 +538,10 @@ struct BloomConstructorContext * @return GNUNET_YES (we should continue to iterate) */ static int -add_known_to_bloom (void *cls, const GNUNET_HashCode * key, void *value) +add_known_to_bloom (void *cls, const struct GNUNET_HashCode * key, void *value) { struct BloomConstructorContext *ctx = cls; - GNUNET_HashCode mh; + struct GNUNET_HashCode mh; GNUNET_BLOCK_mingle_hash (key, ctx->bf_mutator, &mh); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -807,7 +827,7 @@ process_peer_queue (struct PeerInfo *peer) return; GNUNET_STATISTICS_update (GDS_stats, gettext_noop - ("# Bytes of bandwdith requested from core"), + ("# Bytes of bandwidth requested from core"), ntohs (pending->msg->size), GNUNET_NO); peer->th = GNUNET_CORE_notify_transmit_ready (coreAPI, GNUNET_YES, @@ -874,7 +894,7 @@ get_forward_count (uint32_t hop_count, uint32_t target_replication) * the two hash codes increases */ static unsigned int -get_distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have) +get_distance (const struct GNUNET_HashCode * target, const struct GNUNET_HashCode * have) { unsigned int bucket; unsigned int msb; @@ -911,7 +931,7 @@ get_distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have) * mismatching bit at 'bucket' */ lsb = 0; for (i = bucket + 1; - (i < sizeof (GNUNET_HashCode) * 8) && (i < bucket + 1 + 32 - 9); i++) + (i < sizeof (struct GNUNET_HashCode) * 8) && (i < bucket + 1 + 32 - 9); i++) { if (GNUNET_CRYPTO_hash_get_bit (target, i) != GNUNET_CRYPTO_hash_get_bit (have, i)) @@ -934,7 +954,7 @@ get_distance (const GNUNET_HashCode * target, const GNUNET_HashCode * have) * GNUNET_NO otherwise. */ static int -am_closest_peer (const GNUNET_HashCode * key, +am_closest_peer (const struct GNUNET_HashCode * key, const struct GNUNET_CONTAINER_BloomFilter *bloom) { int bits; @@ -943,7 +963,7 @@ am_closest_peer (const GNUNET_HashCode * key, int count; struct PeerInfo *pos; - if (0 == memcmp (&my_identity.hashPubKey, key, sizeof (GNUNET_HashCode))) + if (0 == memcmp (&my_identity.hashPubKey, key, sizeof (struct GNUNET_HashCode))) return GNUNET_YES; bucket_num = find_bucket (key); GNUNET_assert (bucket_num >= 0); @@ -989,7 +1009,7 @@ am_closest_peer (const GNUNET_HashCode * key, * @return Peer to route to, or NULL on error */ static struct PeerInfo * -select_peer (const GNUNET_HashCode * key, +select_peer (const struct GNUNET_HashCode * key, const struct GNUNET_CONTAINER_BloomFilter *bloom, uint32_t hops) { unsigned int bc; @@ -1081,19 +1101,16 @@ select_peer (const GNUNET_HashCode * key, count = 0; for (bc = 0; bc <= closest_bucket; bc++) { - pos = k_buckets[bc].head; - while ((pos != NULL) && (count < bucket_size)) + for (pos = k_buckets[bc].head; ((pos != NULL) && (count < bucket_size)); pos = pos->next) { if ((bloom != NULL) && (GNUNET_YES == GNUNET_CONTAINER_bloomfilter_test (bloom, &pos->id.hashPubKey))) { - pos = pos->next; continue; /* Ignore bloomfiltered peers */ } if (0 == selected--) return pos; - pos = pos->next; } } GNUNET_break (0); @@ -1115,7 +1132,7 @@ select_peer (const GNUNET_HashCode * key, * @return number of peers returned in 'targets'. */ static unsigned int -get_target_peers (const GNUNET_HashCode * key, +get_target_peers (const struct GNUNET_HashCode *key, struct GNUNET_CONTAINER_BloomFilter *bloom, uint32_t hop_count, uint32_t target_replication, struct PeerInfo ***targets) @@ -1126,7 +1143,7 @@ get_target_peers (const GNUNET_HashCode * key, struct PeerInfo *nxt; GNUNET_assert (NULL != bloom); - ret = get_forward_count (hop_count, target_replication); + ret = get_forward_count (hop_count, target_replication); if (ret == 0) { *targets = NULL; @@ -1155,6 +1172,11 @@ get_target_peers (const GNUNET_HashCode * key, return 0; } *targets = rtargets; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Forwarding query `%s' to %u peers (goal was %u peers)\n", + GNUNET_h2s (key), + off, + ret); return off; } @@ -1185,7 +1207,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, uint32_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, unsigned int put_path_length, struct GNUNET_PeerIdentity *put_path, const void *data, size_t data_size) @@ -1238,6 +1260,12 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, for (i = 0; i < target_count; i++) { target = targets[i]; + if (target->pending_count >= MAXIMUM_PENDING_PER_PEER) + { + GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), + 1, GNUNET_NO); + continue; /* skip */ + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing PUT for %s after %u hops to %s\n", GNUNET_h2s (key), (unsigned int) hop_count, GNUNET_i2s (&target->id)); @@ -1295,7 +1323,7 @@ void GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, - uint32_t hop_count, const GNUNET_HashCode * key, + uint32_t hop_count, const struct GNUNET_HashCode * key, const void *xquery, size_t xquery_size, const struct GNUNET_CONTAINER_BloomFilter *reply_bf, uint32_t reply_bf_mutator, @@ -1345,6 +1373,12 @@ GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, for (i = 0; i < target_count; i++) { target = targets[i]; + if (target->pending_count >= MAXIMUM_PENDING_PER_PEER) + { + GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), + 1, GNUNET_NO); + continue; /* skip */ + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Routing GET for %s after %u hops to %s\n", GNUNET_h2s (key), (unsigned int) hop_count, GNUNET_i2s (&target->id)); @@ -1405,7 +1439,7 @@ void GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, @@ -1438,6 +1472,14 @@ GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, /* peer disconnected in the meantime, drop reply */ return; } + if (pi->pending_count >= MAXIMUM_PENDING_PER_PEER) + { + /* skip */ + GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# P2P messages dropped due to full queue"), + 1, GNUNET_NO); + return; + } + GNUNET_STATISTICS_update (GDS_stats, gettext_noop ("# RESULT messages queued for transmission"), 1, @@ -1508,7 +1550,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, size_t payload_size; enum GNUNET_DHT_RouteOption options; struct GNUNET_CONTAINER_BloomFilter *bf; - GNUNET_HashCode test_key; + struct GNUNET_HashCode test_key; msize = ntohs (message->size); if (msize < sizeof (struct PeerPutMessage)) @@ -1541,7 +1583,7 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, &test_key)) { case GNUNET_YES: - if (0 != memcmp (&test_key, &put->key, sizeof (GNUNET_HashCode))) + if (0 != memcmp (&test_key, &put->key, sizeof (struct GNUNET_HashCode))) { GNUNET_break_op (0); return GNUNET_YES; @@ -1556,6 +1598,19 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PUT for `%s' from %s\n", GNUNET_h2s (&put->key), GNUNET_i2s (peer)); + + if (LOG_ROUTE_DETAILS_STDERR) + { + char *tmp; + + tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); + fprintf (stderr, "XDHT PUT %s: %s(%u)<-%s\n", + GNUNET_h2s (&put->key), tmp, getpid (), + GNUNET_i2s (peer)); + GNUNET_free (tmp); + } + + bf = GNUNET_CONTAINER_bloomfilter_init (put->bloomfilter, DHT_BLOOM_SIZE, GNUNET_CONSTANTS_BLOOMFILTER_K); GNUNET_break_op (GNUNET_YES == @@ -1615,14 +1670,14 @@ handle_dht_p2p_put (void *cls, const struct GNUNET_PeerIdentity *peer, */ static void handle_find_peer (const struct GNUNET_PeerIdentity *sender, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, struct GNUNET_CONTAINER_BloomFilter *bf, uint32_t bf_mutator) { int bucket_idx; struct PeerBucket *bucket; struct PeerInfo *peer; unsigned int choice; - GNUNET_HashCode mhash; + struct GNUNET_HashCode mhash; const struct GNUNET_HELLO_Message *hello; /* first, check about our own HELLO */ @@ -1634,7 +1689,7 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, { GDS_NEIGHBOURS_handle_reply (sender, GNUNET_BLOCK_TYPE_DHT_HELLO, GNUNET_TIME_relative_to_absolute - (GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION), + (hello_expiration), key, 0, NULL, 0, NULL, GDS_my_hello, GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *) @@ -1657,7 +1712,7 @@ handle_find_peer (const struct GNUNET_PeerIdentity *sender, } /* then, also consider sending a random HELLO from the closest bucket */ - if (0 == memcmp (&my_identity.hashPubKey, key, sizeof (GNUNET_HashCode))) + if (0 == memcmp (&my_identity.hashPubKey, key, sizeof (struct GNUNET_HashCode))) bucket_idx = closest_bucket; else bucket_idx = GNUNET_MIN (closest_bucket, find_bucket (key)); @@ -1803,6 +1858,19 @@ handle_dht_p2p_get (void *cls, const struct GNUNET_PeerIdentity *peer, 1, GNUNET_NO); } + if (LOG_ROUTE_DETAILS_STDERR) + { + char *tmp; + + tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); + fprintf (stderr, "XDHT GET %s: %s(%u)<-%s\n", + GNUNET_h2s (&get->key), tmp, getpid(), + GNUNET_i2s (peer)); + GNUNET_free (tmp); + } + + + /* FIXME Path */ GDS_CLIENTS_process_get (options, type, @@ -1917,12 +1985,27 @@ handle_dht_p2p_result (void *cls, const struct GNUNET_PeerIdentity *peer, if (NULL != GDS_transport_handle) { GNUNET_TRANSPORT_offer_hello (GDS_transport_handle, h, NULL, NULL); - GNUNET_TRANSPORT_try_connect (GDS_transport_handle, &pid); + if (GNUNET_YES != + disable_try_connect) + GNUNET_TRANSPORT_try_connect (GDS_transport_handle, &pid, NULL, NULL); /*FIXME TRY_CONNECT change */ } } } } + + if (LOG_ROUTE_DETAILS_STDERR) + { + char *tmp; + + tmp = GNUNET_strdup (GNUNET_i2s (&my_identity)); + fprintf (stderr, + "XDHT RESULT %s: %s(%u)<-%s\n", + GNUNET_h2s (&prm->key), tmp, + getpid(), GNUNET_i2s (peer)); + GNUNET_free (tmp); + } + /* append 'peer' to 'get_path' */ { struct GNUNET_PeerIdentity xget_path[get_path_length + 1]; @@ -1974,18 +2057,20 @@ GDS_NEIGHBOURS_init () }; unsigned long long temp_config_num; + disable_try_connect + = GNUNET_CONFIGURATION_get_value_yesno (GDS_cfg, "DHT", "DISABLE_TRY_CONNECT"); if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (GDS_cfg, "DHT", "bucket_size", &temp_config_num)) bucket_size = (unsigned int) temp_config_num; atsAPI = GNUNET_ATS_performance_init (GDS_cfg, NULL, NULL); coreAPI = - GNUNET_CORE_connect (GDS_cfg, 1, NULL, &core_init, &handle_core_connect, + GNUNET_CORE_connect (GDS_cfg, NULL, &core_init, &handle_core_connect, &handle_core_disconnect, NULL, GNUNET_NO, NULL, GNUNET_NO, core_handlers); if (coreAPI == NULL) return GNUNET_SYSERR; - all_known_peers = GNUNET_CONTAINER_multihashmap_create (256); + all_known_peers = GNUNET_CONTAINER_multihashmap_create (256, GNUNET_NO); return GNUNET_OK; } diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h index 3297638..b3b33e3 100644 --- a/src/dht/gnunet-service-dht_neighbours.h +++ b/src/dht/gnunet-service-dht_neighbours.h @@ -57,7 +57,7 @@ GDS_NEIGHBOURS_handle_put (enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, uint32_t hop_count, struct GNUNET_CONTAINER_BloomFilter *bf, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, unsigned int put_path_length, struct GNUNET_PeerIdentity *put_path, const void *data, size_t data_size); @@ -84,7 +84,7 @@ void GDS_NEIGHBOURS_handle_get (enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, uint32_t desired_replication_level, - uint32_t hop_count, const GNUNET_HashCode * key, + uint32_t hop_count, const struct GNUNET_HashCode * key, const void *xquery, size_t xquery_size, const struct GNUNET_CONTAINER_BloomFilter *reply_bf, uint32_t reply_bf_mutator, @@ -111,7 +111,7 @@ void GDS_NEIGHBOURS_handle_reply (const struct GNUNET_PeerIdentity *target, enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, diff --git a/src/dht/gnunet-service-dht_nse.c b/src/dht/gnunet-service-dht_nse.c index 7779989..11c02e1 100644 --- a/src/dht/gnunet-service-dht_nse.c +++ b/src/dht/gnunet-service-dht_nse.c @@ -81,6 +81,21 @@ GDS_NSE_get () void GDS_NSE_init () { + unsigned long long hops; + + if ( (GNUNET_YES == + GNUNET_CONFIGURATION_have_value (GDS_cfg, + "dht", + "FORCE_NSE")) && + (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_number (GDS_cfg, + "dht", + "FORCE_NSE", + &hops)) ) + { + log_of_network_size_estimate = (double) hops; + return; + } nse = GNUNET_NSE_connect (GDS_cfg, &update_network_size_estimate, NULL); } diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c index 013d856..2d0d778 100644 --- a/src/dht/gnunet-service-dht_routing.c +++ b/src/dht/gnunet-service-dht_routing.c @@ -50,7 +50,7 @@ struct RecentRequest /** * Key of this request. */ - GNUNET_HashCode key; + struct GNUNET_HashCode key; /** * Position of this node in the min heap. @@ -160,15 +160,15 @@ struct ProcessContext * GNUNET_SYSERR if the result is malformed or type unsupported */ static int -process (void *cls, const GNUNET_HashCode * key, void *value) +process (void *cls, const struct GNUNET_HashCode * key, void *value) { struct ProcessContext *pc = cls; struct RecentRequest *rr = value; enum GNUNET_BLOCK_EvaluationResult eval; unsigned int gpl; unsigned int ppl; - GNUNET_HashCode hc; - const GNUNET_HashCode *eval_key; + struct GNUNET_HashCode hc; + const struct GNUNET_HashCode *eval_key; if ((rr->type != GNUNET_BLOCK_TYPE_ANY) && (rr->type != pc->type)) return GNUNET_OK; /* type missmatch */ @@ -226,6 +226,12 @@ process (void *cls, const GNUNET_HashCode * key, void *value) ("# Invalid REPLIES matched against routing table"), 1, GNUNET_NO); return GNUNET_SYSERR; + case GNUNET_BLOCK_EVALUATION_RESULT_IRRELEVANT: + GNUNET_STATISTICS_update (GDS_stats, + gettext_noop + ("# Irrelevant REPLIES matched against routing table"), + 1, GNUNET_NO); + return GNUNET_OK; case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: GNUNET_break (0); return GNUNET_OK; @@ -266,7 +272,7 @@ process (void *cls, const GNUNET_HashCode * key, void *value) void GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, - const GNUNET_HashCode * key, unsigned int put_path_length, + const struct GNUNET_HashCode * key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, @@ -322,6 +328,48 @@ expire_oldest_entry () } +/** + * Try to combine multiple recent requests for the same value + * (if they come from the same peer). + * + * @param cls the new 'struct RecentRequest' (to discard upon successful combination) + * @param key the query + * @param value the existing 'struct RecentRequest' (to update upon successful combination) + * @return GNUNET_OK (continue to iterate), + * GNUNET_SYSERR if the request was successfully combined + */ +static int +try_combine_recent (void *cls, const struct GNUNET_HashCode * key, void *value) +{ + struct RecentRequest *in = cls; + struct RecentRequest *rr = value; + + if ( (0 != memcmp (&in->peer, + &rr->peer, + sizeof (struct GNUNET_PeerIdentity))) || + (in->type != rr->type) || + (in->xquery_size != rr->xquery_size) || + (0 != memcmp (in->xquery, + rr->xquery, + in->xquery_size)) ) + return GNUNET_OK; + if (in->reply_bf_mutator != rr->reply_bf_mutator) + { + rr->reply_bf_mutator = in->reply_bf_mutator; + GNUNET_CONTAINER_bloomfilter_free (rr->reply_bf); + rr->reply_bf = in->reply_bf; + } + else + { + GNUNET_CONTAINER_bloomfilter_or2 (rr->reply_bf, + in->reply_bf, + GNUNET_CONTAINER_bloomfilter_get_size (in->reply_bf)); + GNUNET_CONTAINER_bloomfilter_free (in->reply_bf); + } + GNUNET_free (in); + return GNUNET_SYSERR; +} + /** * Add a new entry to our routing table. @@ -339,7 +387,7 @@ void GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, - const GNUNET_HashCode * key, const void *xquery, + const struct GNUNET_HashCode * key, const void *xquery, size_t xquery_size, const struct GNUNET_CONTAINER_BloomFilter *reply_bf, uint32_t reply_bf_mutator) @@ -354,15 +402,26 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, recent_req = GNUNET_malloc (sizeof (struct RecentRequest) + xquery_size); recent_req->peer = *sender; recent_req->key = *key; - recent_req->heap_node = - GNUNET_CONTAINER_heap_insert (recent_heap, recent_req, - GNUNET_TIME_absolute_get ().abs_value); recent_req->reply_bf = GNUNET_CONTAINER_bloomfilter_copy (reply_bf); recent_req->type = type; recent_req->options = options; recent_req->xquery = &recent_req[1]; + memcpy (&recent_req[1], xquery, xquery_size); recent_req->xquery_size = xquery_size; recent_req->reply_bf_mutator = reply_bf_mutator; + if (GNUNET_SYSERR == + GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, key, + &try_combine_recent, recent_req)) + { + GNUNET_STATISTICS_update (GDS_stats, + gettext_noop + ("# DHT requests combined"), + 1, GNUNET_NO); + return; + } + recent_req->heap_node = + GNUNET_CONTAINER_heap_insert (recent_heap, recent_req, + GNUNET_TIME_absolute_get ().abs_value); GNUNET_CONTAINER_multihashmap_put (recent_map, key, recent_req, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); @@ -377,7 +436,7 @@ void GDS_ROUTING_init () { recent_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); - recent_map = GNUNET_CONTAINER_multihashmap_create (DHT_MAX_RECENT * 4 / 3); + recent_map = GNUNET_CONTAINER_multihashmap_create (DHT_MAX_RECENT * 4 / 3, GNUNET_NO); } diff --git a/src/dht/gnunet-service-dht_routing.h b/src/dht/gnunet-service-dht_routing.h index 9b12c71..56326aa 100644 --- a/src/dht/gnunet-service-dht_routing.h +++ b/src/dht/gnunet-service-dht_routing.h @@ -51,7 +51,7 @@ void GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, struct GNUNET_TIME_Absolute expiration_time, - const GNUNET_HashCode * key, unsigned int put_path_length, + const struct GNUNET_HashCode * key, unsigned int put_path_length, const struct GNUNET_PeerIdentity *put_path, unsigned int get_path_length, const struct GNUNET_PeerIdentity *get_path, @@ -74,7 +74,7 @@ void GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, enum GNUNET_BLOCK_Type type, enum GNUNET_DHT_RouteOption options, - const GNUNET_HashCode * key, const void *xquery, + const struct GNUNET_HashCode * key, const void *xquery, size_t xquery_size, const struct GNUNET_CONTAINER_BloomFilter *reply_bf, uint32_t reply_bf_mutator); diff --git a/src/dht/multipeer_topo.dat b/src/dht/multipeer_topo.dat deleted file mode 100644 index 1233e6b..0000000 --- a/src/dht/multipeer_topo.dat +++ /dev/null @@ -1,31 +0,0 @@ -10 -1:2 -2:3 -3:4 -4:5 -5:6 -6:7 -7:8 -8:9 -9:10 -10:1 -4:2 -5:3 -6:4 -7:5 -8:6 -9:7 -10:8 -1:9 -2:10 -3:1 -6:2 -7:3 -8:4 -9:5 -10:6 -1:7 -2:8 -3:9 -4:10 -5:1 diff --git a/src/dht/plugin_block_dht.c b/src/dht/plugin_block_dht.c index 3c016ae..ac4732c 100644 --- a/src/dht/plugin_block_dht.c +++ b/src/dht/plugin_block_dht.c @@ -51,13 +51,13 @@ */ static enum GNUNET_BLOCK_EvaluationResult block_plugin_dht_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) { - GNUNET_HashCode mhash; + struct GNUNET_HashCode mhash; const struct GNUNET_HELLO_Message *hello; struct GNUNET_PeerIdentity pid; const struct GNUNET_MessageHeader *msg; @@ -122,7 +122,7 @@ block_plugin_dht_evaluate (void *cls, enum GNUNET_BLOCK_Type type, static int block_plugin_dht_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 GNUNET_MessageHeader *msg; const struct GNUNET_HELLO_Message *hello; diff --git a/src/dht/test_dht_2dtorus.conf b/src/dht/test_dht_2dtorus.conf index d7a3d8a..29188cb 100644 --- a/src/dht/test_dht_2dtorus.conf +++ b/src/dht/test_dht_2dtorus.conf @@ -1,35 +1,15 @@ [PATHS] -SERVICEHOME = /tmp/test_dht_topo/ -DEFAULTCONFIG = test_dht_2dtours.conf +SERVICEHOME = /tmp/test_dht_2dtorus/ [arm] -PORT = 10010 DEFAULTSERVICES = core dht -#DEBUG = YES - -[statistics] -AUTOSTART = YES -PORT = 10000 - -[dht] -DEBUG = NO -AUTOSTART = YES -ACCEPT_FROM6 = ::1; -ACCEPT_FROM = 127.0.0.1; -HOSTNAME = localhost -PORT = 10001 [dns] AUTOSTART = NO -PORT = 10011 - -[transport] -PORT = 10002 -AUTOSTART = YES [nat] DISABLEV6 = YES -BINDTO = 127.0.0.1 +RETURN_LOCAL_ADDRESSES = YES ENABLE_UPNP = NO BEHIND_NAT = NO ALLOW_NAT = NO @@ -40,48 +20,18 @@ EXTERNAL_ADDRESS = 127.0.0.1 WAN_QUOTA_IN = 1 GB WAN_QUOTA_OUT = 1 GB -[core] -AUTOSTART = YES -PORT = 10003 - -[peerinfo] -AUTOSTART = YES -PORT = 10004 - [testing] -NUM_PEERS = 16 WEAKRANDOM = YES -TOPOLOGY = NONE -CONNECT_TOPOLOGY = 2D_TORUS -BLACKLIST_TOPOLOGY = 2D_TORUS -#TOPOLOGY_FILE = small.dat -#CONNECT_TOPOLOGY = ERDOS_RENYI -#CONNECT_TOPOLOGY_OPTION = CONNECT_MINIMUM -#CONNECT_TOPOLOGY_OPTION_MODIFIER = 25 -#PERCENTAGE = 3 -#PROBABILITY = .1 -F2F = NO -CONNECT_TIMEOUT = 60 s -CONNECT_ATTEMPTS = 3 -DEBUG = YES -HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat -MAX_CONCURRENT_SSH = 20 -USE_PROGRESSBARS = YES -PEERGROUP_TIMEOUT = 2400 s -TOPOLOGY_OUTPUT_FILE = 2dtorus_topo_initial -MAX_OUTSTANDING_CONNECTIONS = 75 -#SINGLE_PEERINFO_PER_HOST = YES -#NUM_PEERINFO_PER_HOST = 10 -#SINGLE_STATISTICS_PER_HOST = YES -#NUM_STATISTICS_PER_HOST = 10 -DELETE_FILES = YES - -[test_dht_topo] -CONNECTION_LIMIT = 20 -#DATA_OUTPUT_FILE=data_output +[testbed] +OVERLAY_TOPOLOGY = 2D_TORUS [nse] WORKDELAY = 500 ms INTERVAL = 60 s WORKBITS = 0 + +[vpn] +AUTOSTART = NO + + diff --git a/src/dht/test_dht_api.c b/src/dht/test_dht_api.c index 000ad33..b1c39e8 100644 --- a/src/dht/test_dht_api.c +++ b/src/dht/test_dht_api.c @@ -25,20 +25,11 @@ * */ #include "platform.h" -#include "gnunet_common.h" +#include "gnunet_util_lib.h" #include "gnunet_hello_lib.h" -#include "gnunet_getopt_lib.h" -#include "gnunet_os_lib.h" -#include "gnunet_program_lib.h" -#include "gnunet_scheduler_lib.h" +#include "gnunet_testing_lib.h" #include "gnunet_dht_service.h" -#include "gnunet_hello_lib.h" - -#define VERBOSE GNUNET_NO - -#define VERBOSE_ARM GNUNET_NO -#define START_ARM GNUNET_YES /** * How long until we really give up on a particular testcase portion? @@ -52,6 +43,7 @@ #define MTYPE 12345 + struct RetryContext { /** @@ -65,37 +57,24 @@ struct RetryContext struct GNUNET_TIME_Relative next_timeout; /** - * The context of the peer we are dealing with. - */ - struct PeerContext *peer_ctx; - - /** * The task identifier of the retry task, so it can be cancelled. */ GNUNET_SCHEDULER_TaskIdentifier retry_task; }; -struct PeerContext -{ - struct GNUNET_CONFIGURATION_Handle *cfg; - struct GNUNET_DHT_Handle *dht_handle; - struct GNUNET_PeerIdentity id; - struct GNUNET_DHT_GetHandle *get_handle; -#if START_ARM - struct GNUNET_OS_Process *arm_proc; -#endif -}; -static struct PeerContext p1; +static struct GNUNET_DHT_Handle *dht_handle; -struct RetryContext retry_context; +static struct GNUNET_DHT_GetHandle *get_handle; +struct RetryContext retry_context; -static int ok; +static int ok = 1; static GNUNET_SCHEDULER_TaskIdentifier die_task; + #if VERBOSE #define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0) #else @@ -108,43 +87,28 @@ end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_SCHEDULER_cancel (die_task); die_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_DHT_disconnect (p1.dht_handle); + GNUNET_DHT_disconnect (dht_handle); + dht_handle = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DHT disconnected, returning success!\n"); ok = 0; } -static void -stop_arm (struct PeerContext *p) -{ -#if START_ARM - if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); - GNUNET_OS_process_wait (p->arm_proc); - GNUNET_OS_process_destroy (p->arm_proc); - p->arm_proc = NULL; -#endif - GNUNET_CONFIGURATION_destroy (p->cfg); -} - static void end_badly () { /* do work here */ -#if VERBOSE FPRINTF (stderr, "%s", "Ending on an unhappy note.\n"); -#endif - - if ((retry_context.peer_ctx != NULL) && - (retry_context.peer_ctx->get_handle != NULL)) + if (get_handle != NULL) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping get request!\n"); - GNUNET_DHT_get_stop (retry_context.peer_ctx->get_handle); + GNUNET_DHT_get_stop (get_handle); } if (retry_context.retry_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (retry_context.retry_task); - GNUNET_DHT_disconnect (p1.dht_handle); + GNUNET_DHT_disconnect (dht_handle); + dht_handle = NULL; ok = 1; } @@ -158,8 +122,6 @@ end_badly () static void test_get_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct PeerContext *peer = cls; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get_stop!\n"); if ((tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT) != 0) { @@ -168,16 +130,16 @@ test_get_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); return; } - GNUNET_assert (peer->dht_handle != NULL); - GNUNET_DHT_get_stop (peer->get_handle); - peer->get_handle = NULL; - GNUNET_SCHEDULER_add_now (&end, &p1); + GNUNET_assert (dht_handle != NULL); + GNUNET_DHT_get_stop (get_handle); + get_handle = NULL; + GNUNET_SCHEDULER_add_now (&end, NULL); } static void test_get_iterator (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, @@ -186,11 +148,11 @@ test_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_get_iterator called (we got a result), stopping get request!\n"); - - GNUNET_SCHEDULER_add_continuation (&test_get_stop, &p1, + GNUNET_SCHEDULER_add_continuation (&test_get_stop, NULL, GNUNET_SCHEDULER_REASON_PREREQ_DONE); } + /** * Signature of the main function of a task. * @@ -200,140 +162,69 @@ test_get_iterator (void *cls, struct GNUNET_TIME_Absolute exp, static void test_get (void *cls, int success) { - struct PeerContext *peer = cls; - GNUNET_HashCode hash; + struct GNUNET_HashCode hash; - memset (&hash, 42, sizeof (GNUNET_HashCode)); + memset (&hash, 42, sizeof (struct GNUNET_HashCode)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_get!\n"); - - GNUNET_assert (peer->dht_handle != NULL); + GNUNET_assert (dht_handle != NULL); retry_context.real_timeout = GNUNET_TIME_relative_to_absolute (TOTAL_TIMEOUT); retry_context.next_timeout = BASE_TIMEOUT; - peer->get_handle = - GNUNET_DHT_get_start (peer->dht_handle, + get_handle = + GNUNET_DHT_get_start (dht_handle, GNUNET_BLOCK_TYPE_TEST, &hash, 1, GNUNET_DHT_RO_NONE, NULL, 0, &test_get_iterator, NULL); - if (peer->get_handle == NULL) + if (get_handle == NULL) { GNUNET_break (0); GNUNET_SCHEDULER_cancel (die_task); - die_task = GNUNET_SCHEDULER_add_now (&end_badly, &p1); + die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); return; } - - retry_context.peer_ctx = peer; } -/** - * Signature of the main function of a task. - * - * @param cls closure - * @param tc context information (why was this task triggered now) - */ + static void -test_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { - struct PeerContext *peer = cls; - GNUNET_HashCode hash; + struct GNUNET_HashCode hash; char *data; size_t data_size = 42; - memset (&hash, 42, sizeof (GNUNET_HashCode)); - data = GNUNET_malloc (data_size); - memset (data, 43, data_size); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_put!\n"); - peer->dht_handle = GNUNET_DHT_connect (peer->cfg, 100); - - GNUNET_assert (peer->dht_handle != NULL); - - GNUNET_DHT_put (peer->dht_handle, &hash, 1, GNUNET_DHT_RO_NONE, - GNUNET_BLOCK_TYPE_TEST, data_size, data, - GNUNET_TIME_relative_to_absolute (TOTAL_TIMEOUT), - TOTAL_TIMEOUT, &test_get, &p1); - GNUNET_free (data); -} - -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_ARM - "-L", "DEBUG", -#endif - "-c", cfgname, NULL); -#endif - GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); - -} - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ GNUNET_assert (ok == 1); OKPP; - die_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1), &end_badly, NULL); - setup_peer (&p1, "test_dht_api_peer1.conf"); - - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 1), &test_put, &p1); -} - -static int -check () -{ - - char *const argv[] = { "test-dht-api", - "-c", - "test_dht_api_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - - ok = 1; - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-dht-api", "nohelp", options, &run, &ok); - stop_arm (&p1); - return ok; + memset (&hash, 42, sizeof (struct GNUNET_HashCode)); + data = GNUNET_malloc (data_size); + memset (data, 43, data_size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called test_put!\n"); + dht_handle = GNUNET_DHT_connect (cfg, 100); + GNUNET_assert (dht_handle != NULL); + GNUNET_DHT_put (dht_handle, &hash, 1, GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_TEST, data_size, data, + GNUNET_TIME_relative_to_absolute (TOTAL_TIMEOUT), + TOTAL_TIMEOUT, &test_get, NULL); + GNUNET_free (data); } int main (int argc, char *argv[]) { - int ret; - - GNUNET_log_setup ("test-dht-api", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); - - GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-dht-peer-1"); - - return ret; + if (0 != GNUNET_TESTING_peer_run ("test-dht-api", + "test_dht_api_data.conf", + &run, NULL)) + return 1; + return ok; } /* end of test_dht_api.c */ diff --git a/src/dht/test_dht_api_data.conf b/src/dht/test_dht_api_data.conf index 032416c..58e509c 100644 --- a/src/dht/test_dht_api_data.conf +++ b/src/dht/test_dht_api_data.conf @@ -1,6 +1,5 @@ [PATHS] SERVICEHOME = /tmp/test-dht-api/ -DEFAULTCONFIG = test_dht_api_data.conf [fs] AUTOSTART = NO @@ -28,7 +27,6 @@ WAN_QUOTA_OUT = 1 GB PORT = 2092 [dht] -DEBUG = NO PORT = 12370 [block] @@ -36,7 +34,6 @@ plugins = dht test [transport] plugins = tcp -DEBUG = NO NEIGHBOUR_LIMIT = 50 PORT = 2091 @@ -59,7 +56,9 @@ PORT = 2094 [TESTING] WEAKRANDOM = NO -HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat + +[testing_old] +HOSTKEYSFILE = ${DATADIR}/testing_hostkeys.dat [gnunetd] HOSTKEY = $SERVICEHOME/.hostkey @@ -84,3 +83,7 @@ AUTOSTART = NO AUTOSTART = NO +[vpn] +AUTOSTART=NO + + diff --git a/src/dht/test_dht_api_peer1.conf b/src/dht/test_dht_api_peer1.conf index d9db7c4..fd2ee80 100644 --- a/src/dht/test_dht_api_peer1.conf +++ b/src/dht/test_dht_api_peer1.conf @@ -5,7 +5,6 @@ AUTOSTART = NO AUTOSTART = NO [dht] -DEBUG = NO AUTOSTART = YES ACCEPT_FROM6 = ::1; ACCEPT_FROM = 127.0.0.1; @@ -22,7 +21,6 @@ DATABASE = sqlite [transport] PLUGINS = tcp -DEBUG = NO ACCEPT_FROM6 = ::1; ACCEPT_FROM = 127.0.0.1; NEIGHBOUR_LIMIT = 50 @@ -38,7 +36,6 @@ PORT = 12092 [arm] DEFAULTSERVICES = core PORT = 12366 -DEBUG = NO [transport-tcp] TIMEOUT = 300 s @@ -52,7 +49,6 @@ WEAKRANDOM = YES HOSTKEY = $SERVICEHOME/.hostkey [PATHS] -DEFAULTCONFIG = test_dht_api_peer1.conf SERVICEHOME = /tmp/test-gnunetd-dht-peer-1/ @@ -74,3 +70,7 @@ AUTOSTART = NO AUTOSTART = NO +[vpn] +AUTOSTART=NO + + diff --git a/src/dht/test_dht_line.conf b/src/dht/test_dht_line.conf index 6be3559..0c790aa 100644 --- a/src/dht/test_dht_line.conf +++ b/src/dht/test_dht_line.conf @@ -1,35 +1,16 @@ [PATHS] -SERVICEHOME = /tmp/test_dht_topo/ -DEFAULTCONFIG = test_dht_line.conf +SERVICEHOME = /tmp/test_dht_line/ [arm] -PORT = 10010 DEFAULTSERVICES = core dht -#DEBUG = YES - -[statistics] -AUTOSTART = YES -PORT = 10000 - -[dht] -DEBUG = NO -AUTOSTART = YES -ACCEPT_FROM6 = ::1; -ACCEPT_FROM = 127.0.0.1; -HOSTNAME = localhost -PORT = 10001 [dns] AUTOSTART = NO -PORT = 10011 - -[transport] -PORT = 10002 -AUTOSTART = YES [nat] DISABLEV6 = YES -BINDTO = 127.0.0.1 +RETURN_LOCAL_ADDRESSES = YES +USE_LOCALADDR = YES ENABLE_UPNP = NO BEHIND_NAT = NO ALLOW_NAT = NO @@ -40,45 +21,11 @@ EXTERNAL_ADDRESS = 127.0.0.1 WAN_QUOTA_IN = 1 GB WAN_QUOTA_OUT = 1 GB -[core] -AUTOSTART = YES -PORT = 10003 - -[peerinfo] -AUTOSTART = YES -PORT = 10004 - [testing] -NUM_PEERS = 5 WEAKRANDOM = YES -TOPOLOGY = NONE -CONNECT_TOPOLOGY = LINE -BLACKLIST_TOPOLOGY = LINE -#TOPOLOGY_FILE = small.dat -#CONNECT_TOPOLOGY = ERDOS_RENYI -#CONNECT_TOPOLOGY_OPTION = CONNECT_MINIMUM -#CONNECT_TOPOLOGY_OPTION_MODIFIER = 25 -#PERCENTAGE = 3 -#PROBABILITY = .1 -F2F = NO -CONNECT_TIMEOUT = 60 s -CONNECT_ATTEMPTS = 3 -DEBUG = YES -HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat -MAX_CONCURRENT_SSH = 10 -USE_PROGRESSBARS = YES -PEERGROUP_TIMEOUT = 2400 s -TOPOLOGY_OUTPUT_FILE = line_topo_initial -MAX_OUTSTANDING_CONNECTIONS = 75 -#SINGLE_PEERINFO_PER_HOST = YES -#NUM_PEERINFO_PER_HOST = 10 -#SINGLE_STATISTICS_PER_HOST = YES -#NUM_STATISTICS_PER_HOST = 10 -DELETE_FILES = YES -[test_dht_topo] -CONNECTION_LIMIT = 5 -#DATA_OUTPUT_FILE=data_output +[testbed] +OVERLAY_TOPOLOGY = LINE [namestore] AUTOSTART = NO @@ -87,3 +34,8 @@ AUTOSTART = NO WORKDELAY = 500 ms INTERVAL = 60 s WORKBITS = 0 + +[vpn] +AUTOSTART = NO + + diff --git a/src/dht/test_dht_monitor.c b/src/dht/test_dht_monitor.c index ca6704a..74024ed 100644 --- a/src/dht/test_dht_monitor.c +++ b/src/dht/test_dht_monitor.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2011 Christian Grothoff (and other contributing authors) + (C) 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,280 +19,215 @@ */ /** * @file dht/test_dht_monitor.c - * - * @brief Test for the dht service: store, retrieve and monitor in a line. - * TODO: update this description - * Each peer stores it own ID in the DHT and then a different peer tries to - * retrieve that key from it. The GET starts after a first round of PUTS has - * been made. Periodically, each peer stores its ID into the DHT. If after - * a timeout no result has been returned, the test fails. + * @brief Test for the dht monitoring API; checks that we receive "some" monitor events + * @author Christian Grothoff */ #include "platform.h" -#include "gnunet_testing_lib.h" +#include "gnunet_testbed_service.h" #include "gnunet_dht_service.h" - -#define REMOVE_DIR GNUNET_YES +#include "dht_test_lib.h" /** - * How long until we give up on connecting the peers? + * How long do we run the test at most? */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500) - -#define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) +/** + * How often do we run the PUTs? + */ #define PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) -static int ok; /** - * Be verbose + * Information we keep for each GET operation. */ -static int verbose; +struct GetOperation +{ + /** + * DLL. + */ + struct GetOperation *next; -/** - * Total number of peers in the test. - */ -static unsigned long long num_peers; + /** + * DLL. + */ + struct GetOperation *prev; -/** - * Global configuration file - */ -static struct GNUNET_CONFIGURATION_Handle *testing_cfg; + /** + * Handle for the operation. + */ + struct GNUNET_DHT_GetHandle *get; + +}; -/** - * Total number of currently running peers. - */ -static unsigned long long peers_running; /** - * Total number of connections in the whole network. + * Return value from 'main'. */ -static unsigned int total_connections; +static int ok; /** - * The currently running peer group. + * Head of list of active GET operations. */ -static struct GNUNET_TESTING_PeerGroup *pg; +static struct GetOperation *get_head; /** - * File to report results to. + * Tail of list of active GET operations. */ -static struct GNUNET_DISK_FileHandle *output_file; +static struct GetOperation *get_tail; /** - * File to log connection info, statistics to. - */ -static struct GNUNET_DISK_FileHandle *data_file; + * Array of the testbed's peers. + */ +static struct GNUNET_TESTBED_Peer **my_peers; /** - * Task called to disconnect peers. + * Number of peers to run. */ -static GNUNET_SCHEDULER_TaskIdentifier disconnect_task; +static unsigned int NUM_PEERS = 3; /** - * Task To perform tests + * Task called to disconnect peers. */ -static GNUNET_SCHEDULER_TaskIdentifier test_task; +static GNUNET_SCHEDULER_TaskIdentifier timeout_task; /** * Task to do DHT_puts */ static GNUNET_SCHEDULER_TaskIdentifier put_task; -/** - * Task called to shutdown test. - */ -static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle; - -static char *topology_file; - -struct GNUNET_TESTING_Daemon *d1; - -struct GNUNET_TESTING_Daemon *d2; - -struct GNUNET_DHT_Handle **hs; - -struct GNUNET_DHT_MonitorHandle **mhs; - -struct GNUNET_DHT_GetHandle *get_h_far; +static struct GNUNET_DHT_MonitorHandle **monitors; -const char *id_origin = "FC74"; -const char *id_far = "2UVH"; +static unsigned int monitor_counter; -struct GNUNET_TESTING_Daemon *d_far; -struct GNUNET_TESTING_Daemon *o; - -unsigned int monitor_counter; - -int in_test; /** - * Check whether peers successfully shut down. - */ -static void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: Shutdown of peers failed: %s\n", - emsg); - ok++; - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "test: All peers successfully shut down!\n"); - } - GNUNET_CONFIGURATION_destroy (testing_cfg); -} - - -static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Ending test.\n"); - if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_NO_TASK; - } - if (data_file != NULL) - GNUNET_DISK_file_close (data_file); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); -} - - + * Task run on success or timeout to clean up. + * Terminates active get operations and shuts down + * the testbed. + * + * @param cls the 'struct GNUNET_DHT_TestContext' + * @param tc scheduler context + */ static void -disconnect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { + struct GNUNET_DHT_TEST_Context *ctx = cls; unsigned int i; + struct GetOperation *get_op; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: disconnecting peers\n"); - disconnect_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_SCHEDULER_cancel (put_task); - if (NULL != get_h_far) - GNUNET_DHT_get_stop (get_h_far); - for (i = 0; i < num_peers; i++) + ok = (monitor_counter > NUM_PEERS) ? 0 : 2; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Received %u monitor events\n", + monitor_counter); + while (NULL != (get_op = get_tail)) { - GNUNET_DHT_monitor_stop(mhs[i]); - GNUNET_DHT_disconnect (hs[i]); + GNUNET_DHT_get_stop (get_op->get); + GNUNET_CONTAINER_DLL_remove (get_head, + get_tail, + get_op); + GNUNET_free (get_op); } - GNUNET_SCHEDULER_cancel (shutdown_handle); - shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + for (i=0;i<NUM_PEERS;i++) + GNUNET_DHT_monitor_stop (monitors[i]); + GNUNET_free (monitors); + GNUNET_SCHEDULER_cancel (put_task); + GNUNET_DHT_TEST_cleanup (ctx); } -static void -dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_length, enum GNUNET_BLOCK_Type type, - size_t size, const void *data) -{ - int i; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "test: ************* FOUND!!! ***********\n"); - if (sizeof (GNUNET_HashCode) == size) - { - const GNUNET_HashCode *h = data; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Contents: %s\n", - GNUNET_h2s_full (h)); - - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: PATH: (get %u, put %u)\n", - get_path_length, put_path_length); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: LOCAL\n"); - for (i = get_path_length - 1; i >= 0; i--) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: %s\n", - GNUNET_i2s (&get_path[i])); - } - for (i = put_path_length - 1; i >= 0; i--) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: %s\n", - GNUNET_i2s (&put_path[i])); - } - if (monitor_counter >= get_path_length + put_path_length) - { - ok = 0; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "expected at least %u hops, got %u\n", - get_path_length + put_path_length, monitor_counter); - } - else - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "expected at least %u hops, got %u\n", - get_path_length + put_path_length, monitor_counter); - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); -} /** - * Start test: start GET request from the first node in the line looking for - * the ID of the last node in the line. - * - * @param cls Closure (not used). - * @param tc Task context. + * Iterator called on each result obtained for a DHT + * operation that expects a reply + * + * @param cls closure with our 'struct GetOperation' + * @param exp when will this value expire + * @param key key of the result + * @param get_path peers on reply path (or NULL if not recorded) + * @param get_path_length number of entries in get_path + * @param put_path peers on the PUT path (or NULL if not recorded) + * @param put_path_length number of entries in get_path + * @param type type of the result + * @param size number of bytes in data + * @param data pointer to the result data */ static void -do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp, + const struct GNUNET_HashCode * key, + const struct GNUNET_PeerIdentity *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int put_path_length, enum GNUNET_BLOCK_Type type, + size_t size, const void *data) { - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) + struct GetOperation *get_op = cls; + struct GNUNET_HashCode want; + struct GNUNET_DHT_TestContext *ctx; + + if (sizeof (struct GNUNET_HashCode) != size) + { + GNUNET_break (0); + return; + } + GNUNET_CRYPTO_hash (key, sizeof (*key), &want); + if (0 != memcmp (&want, data, sizeof (want))) { + GNUNET_break (0); return; } - - in_test = GNUNET_YES; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: test_task\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: looking for %s\n", - GNUNET_h2s_full (&d_far->id.hashPubKey)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: from %s\n", - GNUNET_h2s_full (&o->id.hashPubKey)); - get_h_far = GNUNET_DHT_get_start (hs[0], - GNUNET_BLOCK_TYPE_TEST, /* type */ - &d_far->id.hashPubKey, /*key to search */ - 4U, /* replication level */ - GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, NULL, /* xquery */ - 0, /* xquery bits */ - &dht_get_id_handler, NULL); - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &disconnect_peers, NULL); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Get successful\n"); + GNUNET_DHT_get_stop (get_op->get); + GNUNET_CONTAINER_DLL_remove (get_head, + get_tail, + get_op); + GNUNET_free (get_op); + if (NULL != get_head) + return; + /* all DHT GET operations successful; terminate! */ + ok = 0; + ctx = GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = GNUNET_SCHEDULER_add_now (&shutdown_task, ctx); } /** - * Periodic function used to put the ID of the far peer in the DHT. + * Task to put the id of each peer into the DHT. * - * @param cls Closure (not used). - * @param tc Task context. + * @param cls array with NUM_PEERS DHT handles + * @param tc Task context */ static void -put_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +do_puts (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_TESTING_Daemon *d; + struct GNUNET_DHT_Handle **hs = cls; + struct GNUNET_HashCode key; + struct GNUNET_HashCode value; + unsigned int i; - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Putting values into DHT\n"); + for (i = 0; i < NUM_PEERS; i++) { - put_task = GNUNET_SCHEDULER_NO_TASK; - return; + GNUNET_CRYPTO_hash (&i, sizeof (i), &key); + GNUNET_CRYPTO_hash (&key, sizeof (key), &value); + GNUNET_DHT_put (hs[i], &key, 10U, + GNUNET_DHT_RO_RECORD_ROUTE | + GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, + GNUNET_BLOCK_TYPE_TEST, + sizeof (value), &value, + GNUNET_TIME_UNIT_FOREVER_ABS, + GNUNET_TIME_UNIT_FOREVER_REL, + NULL, NULL); } - - d = GNUNET_TESTING_daemon_get (pg, 4); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: putting into DHT: %s\n", - GNUNET_h2s_full (&d->id.hashPubKey)); - GNUNET_DHT_put (hs[4], &d->id.hashPubKey, 10U, - GNUNET_DHT_RO_RECORD_ROUTE | - GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, - GNUNET_BLOCK_TYPE_TEST, sizeof (struct GNUNET_PeerIdentity), - (const char *) &d->id, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_TIME_UNIT_FOREVER_REL, NULL, NULL); - - put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY, &put_id, NULL); + put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY, + &do_puts, hs); } + /** * Callback called on each GET request going through the DHT. * Prints the info about the intercepted packet and increments a counter. @@ -306,7 +241,7 @@ put_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param desired_replication_level Desired replication level. * @param key Key of the requested data. */ -void +static void monitor_get_cb (void *cls, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, @@ -314,19 +249,16 @@ monitor_get_cb (void *cls, uint32_t desired_replication_level, unsigned int path_length, const struct GNUNET_PeerIdentity *path, - const GNUNET_HashCode * key) + const struct GNUNET_HashCode * key) { - const char *s_key; unsigned int i; i = (unsigned int) (long) cls; - s_key = GNUNET_h2s(key); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%u got a GET message for key %s\n", - i, s_key); - - if (strncmp (s_key, id_far, 4) == 0 && in_test == GNUNET_YES) - monitor_counter++; + i, + GNUNET_h2s (key)); + monitor_counter++; } @@ -346,7 +278,7 @@ monitor_get_cb (void *cls, * @param data Pointer to the data carried. * @param size Number of bytes in data. */ -void +static void monitor_put_cb (void *cls, enum GNUNET_DHT_RouteOption options, enum GNUNET_BLOCK_Type type, @@ -355,22 +287,18 @@ monitor_put_cb (void *cls, unsigned int path_length, const struct GNUNET_PeerIdentity *path, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, const void *data, size_t size) { - const char *s_key; unsigned int i; i = (unsigned int) (long) cls; - s_key = GNUNET_h2s(key); - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%u got a PUT message for key %s with %u bytes\n", - i, s_key, size); - - if (strncmp (s_key, id_far, 4) == 0 && in_test == GNUNET_YES) - monitor_counter++; + i, + GNUNET_h2s (key), size); + monitor_counter++; } @@ -389,7 +317,7 @@ monitor_put_cb (void *cls, * @param data Pointer to the result data. * @param size Number of bytes in data. */ -void +static void monitor_res_cb (void *cls, enum GNUNET_BLOCK_Type type, const struct GNUNET_PeerIdentity *get_path, @@ -397,267 +325,92 @@ monitor_res_cb (void *cls, const struct GNUNET_PeerIdentity *put_path, unsigned int put_path_length, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, + const struct GNUNET_HashCode * key, const void *data, size_t size) { - const char *s_key; unsigned int i; i = (unsigned int) (long) cls; - s_key = GNUNET_h2s(key); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%u got a REPLY message for key %s with %u bytes\n", - i, s_key, size); - - if (strncmp (s_key, id_far, 4) == 0 && in_test == GNUNET_YES) - monitor_counter++; + i, + GNUNET_h2s (key), size); + monitor_counter++; } /** - * peergroup_ready: start test when all peers are connected + * Main function of the test. * - * @param cls closure - * @param emsg error message + * @param cls closure (NULL) + * @param ctx argument to give to GNUNET_DHT_TEST_cleanup on test end + * @param num_peers number of peers that are running + * @param peers array of peers + * @param dhts handle to each of the DHTs of the peers */ static void -peergroup_ready (void *cls, const char *emsg) +run (void *cls, + struct GNUNET_DHT_TEST_Context *ctx, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, + struct GNUNET_DHT_Handle **dhts) { - struct GNUNET_TESTING_Daemon *d; - char *buf; - int buf_len; unsigned int i; + unsigned int j; + struct GNUNET_HashCode key; + struct GetOperation *get_op; - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "test: Peergroup callback called with error, aborting test!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Error from testing: `%s'\n", - emsg); - ok++; - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "test: Peer Group started successfully with %u connections\n", - total_connections); - if (data_file != NULL) - { - buf = NULL; - buf_len = GNUNET_asprintf (&buf, "CONNECTIONS_0: %u\n", total_connections); - if (buf_len > 0) - GNUNET_DISK_file_write (data_file, buf, buf_len); - GNUNET_free (buf); - } - peers_running = GNUNET_TESTING_daemons_running (pg); - - GNUNET_assert (peers_running == num_peers); - hs = GNUNET_malloc (num_peers * sizeof (struct GNUNET_DHT_Handle *)); - mhs = GNUNET_malloc (num_peers * sizeof (struct GNUNET_DHT_MonitorHandle *)); - d_far = o = NULL; - o = GNUNET_TESTING_daemon_get (pg, 0); - d_far = GNUNET_TESTING_daemon_get (pg, 4); - + GNUNET_assert (NUM_PEERS == num_peers); + my_peers = peers; + monitors = GNUNET_malloc (num_peers * sizeof (struct GNUNET_DHT_MonitorHandle *)); for (i = 0; i < num_peers; i++) + monitors[i] = GNUNET_DHT_monitor_start (dhts[i], + GNUNET_BLOCK_TYPE_ANY, + NULL, + &monitor_get_cb, + &monitor_res_cb, + &monitor_put_cb, + (void *)(long)i); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peers setup, starting test\n"); + put_task = GNUNET_SCHEDULER_add_now (&do_puts, dhts); + for (i=0;i<num_peers;i++) { - d = GNUNET_TESTING_daemon_get (pg, i); - hs[i] = GNUNET_DHT_connect (d->cfg, 32); - mhs[i] = GNUNET_DHT_monitor_start(hs[i], - GNUNET_BLOCK_TYPE_ANY, - NULL, - &monitor_get_cb, - &monitor_res_cb, - &monitor_put_cb, - (void *)(long)i); - } - - if ((NULL == o) || (NULL == d_far)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "test: Error getting daemons from pg\n"); - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); - return; - } - monitor_counter = 0; - put_task = GNUNET_SCHEDULER_add_now (&put_id, NULL); - test_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 2), &do_test, - NULL); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &disconnect_peers, NULL); - -} - - -/** - * Function that will be called whenever two daemons are connected by - * the testing library. - * - * @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) - */ -static void -connect_cb (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) -{ - - if (emsg == NULL) - { - total_connections++; - GNUNET_PEER_intern (first); - GNUNET_PEER_intern (second); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "test: Problem with new connection (%s)\n", emsg); - } - -} - - -/** - * run: load configuration options and schedule test to run (start peergroup) - * @param cls closure - * @param args argv - * @param cfgfile configuration file name (can be NULL) - * @param cfg configuration handle - */ -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - char *temp_str; - struct GNUNET_TESTING_Host *hosts; - char *data_filename; - - ok = 1; - testing_cfg = GNUNET_CONFIGURATION_dup (cfg); - - GNUNET_log_setup ("test_dht_monitor", - "WARNING", - NULL); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Starting daemons.\n"); - GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing", - "use_progressbars", "YES"); - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing", - "num_peers", &num_peers)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Option TESTING:NUM_PEERS is required!\n"); - return; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (testing_cfg, "testing", - "topology_output_file", - &topology_file)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Option test_dht_monitor:topology_output_file is required!\n"); - return; - } - - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (testing_cfg, "test_dht_topo", - "data_output_file", - &data_filename)) - { - data_file = - GNUNET_DISK_file_open (data_filename, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - if (data_file == NULL) + GNUNET_CRYPTO_hash (&i, sizeof (i), &key); + for (j=0;j<num_peers;j++) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n", - data_filename); - GNUNET_free (data_filename); + get_op = GNUNET_malloc (sizeof (struct GetOperation)); + GNUNET_CONTAINER_DLL_insert (get_head, + get_tail, + get_op); + get_op->get = GNUNET_DHT_get_start (dhts[j], + GNUNET_BLOCK_TYPE_TEST, /* type */ + &key, /*key to search */ + 4U, /* replication level */ + GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, + NULL, /* xquery */ + 0, /* xquery bits */ + &dht_get_handler, get_op); } } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "test_dht_topo", - "output_file", &temp_str)) - { - output_file = - GNUNET_DISK_file_open (temp_str, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - if (output_file == NULL) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n", - temp_str); - } - GNUNET_free_non_null (temp_str); - - hosts = GNUNET_TESTING_hosts_load (testing_cfg); - - pg = GNUNET_TESTING_peergroup_start (testing_cfg, num_peers, TIMEOUT, - &connect_cb, &peergroup_ready, NULL, - hosts); - GNUNET_assert (pg != NULL); - shutdown_handle = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &shutdown_task, NULL); + timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, + &shutdown_task, ctx); } - -/** - * test_dht_monitor command line options - */ -static struct GNUNET_GETOPT_CommandLineOption options[] = { - {'V', "verbose", NULL, - gettext_noop ("be verbose (print progress information)"), - 0, &GNUNET_GETOPT_set_one, &verbose}, - GNUNET_GETOPT_OPTION_END -}; - - /** * Main: start test */ int main (int xargc, char *xargv[]) { - char *const argv[] = { "test-dht-monitor", - "-c", - "test_dht_line.conf", - NULL - }; - - in_test = GNUNET_NO; - GNUNET_PROGRAM_run (sizeof (argv) / sizeof (char *) - 1, argv, - "test_dht_monitor", - gettext_noop ("Test dht monitoring in a line."), - options, &run, NULL); -#if REMOVE_DIR - GNUNET_DISK_directory_remove ("/tmp/test_dht_monitor"); -#endif - if (0 != ok) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test: FAILED!\n"); - } + GNUNET_DHT_TEST_run ("test-dht-monitor", + "test_dht_monitor.conf", + NUM_PEERS, + &run, NULL); return ok; } + /* end of test_dht_monitor.c */ diff --git a/src/dht/test_dht_monitor.conf b/src/dht/test_dht_monitor.conf new file mode 100644 index 0000000..ebefcca --- /dev/null +++ b/src/dht/test_dht_monitor.conf @@ -0,0 +1,57 @@ +[fs] +AUTOSTART = NO + +[resolver] +AUTOSTART = NO + +[block] +plugins = test dht + +[dhtcache] +QUOTA = 1 MB +DATABASE = sqlite + +[transport] +PLUGINS = tcp + +[ats] +WAN_QUOTA_IN = 1 GB +WAN_QUOTA_OUT = 1 GB + +[arm] +DEFAULTSERVICES = dht core + +[TESTING] +WEAKRANDOM = YES + +[testbed] +OVERLAY_TOPOLOGY = LINE + +[gnunetd] +HOSTKEY = $SERVICEHOME/.hostkey + +[PATHS] +SERVICEHOME = /tmp/test-dht-multipeer/ + +[nat] +DISABLEV6 = YES +ENABLE_UPNP = NO +BEHIND_NAT = NO +ALLOW_NAT = NO +INTERNAL_ADDRESS = 127.0.0.1 +EXTERNAL_ADDRESS = 127.0.0.1 +USE_LOCALADDR = YES +RETURN_LOCAL_ADDRESSES = YES + +[dns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[nse] +AUTOSTART = NO + +[vpn] +AUTOSTART=NO + diff --git a/src/dht/test_dht_multipeer.c b/src/dht/test_dht_multipeer.c deleted file mode 100644 index ab7d90e..0000000 --- a/src/dht/test_dht_multipeer.c +++ /dev/null @@ -1,859 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2009 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - 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 dht/test_dht_multipeer.c - * @brief testcase for testing DHT service with - * multiple peers. - */ -#include "platform.h" -#include "gnunet_testing_lib.h" -#include "gnunet_core_service.h" -#include "gnunet_dht_service.h" - -/* Timeout for entire testcase */ -#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 30) - -/* Timeout for waiting for replies to get requests */ -#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 300) - -/* */ -#define START_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30) - -/* Timeout for waiting for gets to complete */ -#define GET_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 50) - -/* Timeout for waiting for puts to complete */ -#define PUT_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 50) - -/* If number of peers not in config file, use this number */ -#define DEFAULT_NUM_PEERS 10 - -#define TEST_DATA_SIZE 8 - -#define MAX_OUTSTANDING_PUTS 100 - -#define MAX_OUTSTANDING_GETS 100 - -#define PATH_TRACKING GNUNET_NO - - - -struct TestPutContext -{ - /** - * This is a linked list - */ - struct TestPutContext *next; - - /** - * This is a linked list - */ - struct TestPutContext *prev; - - /** - * Handle to the first peers DHT service (via the API) - */ - struct GNUNET_DHT_Handle *dht_handle; - - /** - * Handle to the PUT peer daemon - */ - struct GNUNET_TESTING_Daemon *daemon; - - /** - * Identifier for this PUT - */ - uint32_t uid; - - /** - * Task handle for processing of the put. - */ - GNUNET_SCHEDULER_TaskIdentifier task; -}; - - -struct TestGetContext -{ - /** - * This is a linked list - */ - struct TestGetContext *next; - - /** - * This is a linked list - */ - struct TestGetContext *prev; - - /** - * Handle to the first peers DHT service (via the API) - */ - struct GNUNET_DHT_Handle *dht_handle; - - /** - * Handle for the DHT get request - */ - struct GNUNET_DHT_GetHandle *get_handle; - - /** - * Handle to the GET peer daemon - */ - struct GNUNET_TESTING_Daemon *daemon; - - /** - * Identifier for this GET - */ - uint32_t uid; - - /** - * Task for disconnecting DHT handles (and stopping GET) - */ - GNUNET_SCHEDULER_TaskIdentifier task; - - /** - * Whether or not this request has been fulfilled already. - */ - int succeeded; -}; - - -/** - * List of GETS to perform - */ -static struct TestGetContext *all_gets_head; - -/** - * List of GETS to perform - */ -static struct TestGetContext *all_gets_tail; - -/** - * List of PUTS to perform - */ -static struct TestPutContext *all_puts_head; - -/** - * List of PUTS to perform - */ -static struct TestPutContext *all_puts_tail; - -/** - * Handle to the set of all peers run for this test. - */ -static struct GNUNET_TESTING_PeerGroup *pg; - -/** - * Total number of peers to run, set based on config file. - */ -static unsigned long long num_peers; - -/** - * How many puts do we currently have in flight? - */ -static unsigned long long outstanding_puts; - -/** - * How many puts are done? - */ -static unsigned long long puts_completed; - -/** - * How many puts do we currently have in flight? - */ -static unsigned long long outstanding_gets; - -/** - * How many gets are done? - */ -static unsigned long long gets_completed; - -/** - * How many gets failed? - */ -static unsigned long long gets_failed; - -/** - * Directory to remove on shutdown. - */ -static char *test_directory; - -/** - * Option to use when routing. - */ -static enum GNUNET_DHT_RouteOption route_option; - -/** - * Task handle to use to schedule test failure / success. - */ -static GNUNET_SCHEDULER_TaskIdentifier die_task; - -/** - * Task handle to use to schedule test shutdown - */ -GNUNET_SCHEDULER_TaskIdentifier shutdown_task; - -/** - * Global return value (0 for success, anything else for failure) - */ -static int ok; - - -/** - * Check whether peers successfully shut down. - */ -static void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - FPRINTF (stderr, "Failed to shutdown testing topology: %s\n", emsg); - if (ok == 0) - ok = 2; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown callback completed.\n"); -} - -static void -do_stop (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) == 0) - { - if (GNUNET_SCHEDULER_NO_TASK != shutdown_task) - { - GNUNET_SCHEDULER_cancel(shutdown_task); - shutdown_task = GNUNET_SCHEDULER_NO_TASK; - } - } - else - { - shutdown_task = GNUNET_SCHEDULER_NO_TASK ; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown requested.\n"); - if (NULL != pg) - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - pg = NULL; -} - - -/** - * Master context for 'stat_run'. - */ -struct StatMaster -{ - struct GNUNET_STATISTICS_Handle *stat; - unsigned int daemon; - unsigned int value; -}; - -struct StatValues -{ - const char *subsystem; - const char *name; - unsigned long long total; -}; - -/** - * Statistics we print out. - */ -static struct StatValues stats[] = { - {"core", "# bytes decrypted", 0}, - {"core", "# bytes encrypted", 0}, - {"core", "# type maps received", 0}, - {"core", "# session keys confirmed via PONG", 0}, - {"core", "# peers connected", 0}, - {"core", "# key exchanges initiated", 0}, - {"core", "# send requests dropped (disconnected)", 0}, - {"core", "# transmissions delayed due to corking", 0}, - {"core", "# messages discarded (expired prior to transmission)", 0}, - {"core", "# messages discarded (disconnected)", 0}, - {"core", "# discarded CORE_SEND requests", 0}, - {"core", "# discarded lower priority CORE_SEND requests", 0}, - {"transport", "# bytes received via TCP", 0}, - {"transport", "# bytes transmitted via TCP", 0}, - {"dht", "# PUT messages queued for transmission", 0}, - {"dht", "# P2P PUT requests received", 0}, - {"dht", "# GET messages queued for transmission", 0}, - {"dht", "# P2P GET requests received", 0}, - {"dht", "# RESULT messages queued for transmission", 0}, - {"dht", "# P2P RESULTS received", 0}, - {"dht", "# Queued messages discarded (peer disconnected)", 0}, - {"dht", "# Peers excluded from routing due to Bloomfilter", 0}, - {"dht", "# Peer selection failed", 0}, - {"dht", "# FIND PEER requests ignored due to Bloomfilter", 0}, - {"dht", "# FIND PEER requests ignored due to lack of HELLO", 0}, - {"dht", "# P2P FIND PEER requests processed", 0}, - {"dht", "# P2P GET requests ONLY routed", 0}, - {"dht", "# Preference updates given to core", 0}, - {"dht", "# REPLIES ignored for CLIENTS (no match)", 0}, - {"dht", "# GET requests from clients injected", 0}, - {"dht", "# GET requests received from clients", 0}, - {"dht", "# GET STOP requests received from clients", 0}, - {"dht", "# ITEMS stored in datacache", 0}, - {"dht", "# Good RESULTS found in datacache", 0}, - {"dht", "# GET requests given to datacache", 0}, - {NULL, NULL, 0} -}; - - -/** - * Callback function to process statistic values. - * - * @param cls closure - * @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 -print_stat (void *cls, const char *subsystem, const char *name, uint64_t value, - int is_persistent) -{ - struct StatMaster *sm = cls; - - stats[sm->value].total += value; - FPRINTF (stderr, "Peer %2u: %12s/%50s = %12llu\n", sm->daemon, subsystem, - name, (unsigned long long) value); - return GNUNET_OK; -} - - -/** - * Function that gathers stats from all daemons. - */ -static void -stat_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - - -/** - * Function called when GET operation on stats is done. - */ -static void -get_done (void *cls, int success) -{ - struct StatMaster *sm = cls; - - GNUNET_break (GNUNET_OK == success); - sm->value++; - GNUNET_SCHEDULER_add_now (&stat_run, sm); -} - - -/** - * Function that gathers stats from all daemons. - */ -static void -stat_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct StatMaster *sm = cls; - unsigned int i; - - die_task = GNUNET_SCHEDULER_NO_TASK; - if (stats[sm->value].name != NULL) - { - GNUNET_STATISTICS_get (sm->stat, -#if 0 - NULL, NULL, -#else - stats[sm->value].subsystem, stats[sm->value].name, -#endif - GNUNET_TIME_UNIT_FOREVER_REL, &get_done, &print_stat, - sm); - return; - } - GNUNET_STATISTICS_destroy (sm->stat, GNUNET_NO); - sm->value = 0; - sm->daemon++; - if (sm->daemon == num_peers) - { - GNUNET_free (sm); - i = 0; - while (stats[i].name != NULL) - { - FPRINTF (stderr, "Total : %12s/%50s = %12llu\n", stats[i].subsystem, - stats[i].name, (unsigned long long) stats[i].total); - i++; - } - die_task = GNUNET_SCHEDULER_add_now (&do_stop, NULL); - return; - } - sm->stat = - GNUNET_STATISTICS_create ("<driver>", - GNUNET_TESTING_daemon_get (pg, - sm->daemon)->cfg); - die_task = GNUNET_SCHEDULER_add_now (&stat_run, sm); -} - - -/** - * Function scheduled to be run on the successful completion of this - * testcase. - */ -static void -finish_testing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct TestPutContext *test_put; - struct TestGetContext *test_get; - struct StatMaster *sm; - - die_task = GNUNET_SCHEDULER_NO_TASK; - while (NULL != (test_put = all_puts_head)) - { - if (test_put->task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (test_put->task); - if (test_put->dht_handle != NULL) - GNUNET_DHT_disconnect (test_put->dht_handle); - GNUNET_CONTAINER_DLL_remove (all_puts_head, all_puts_tail, test_put); - GNUNET_free (test_put); - } - - while (NULL != (test_get = all_gets_head)) - { - if (test_get->task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (test_get->task); - if (test_get->get_handle != NULL) - GNUNET_DHT_get_stop (test_get->get_handle); - if (test_get->dht_handle != NULL) - GNUNET_DHT_disconnect (test_get->dht_handle); - GNUNET_CONTAINER_DLL_remove (all_gets_head, all_gets_tail, test_get); - GNUNET_free (test_get); - } - sm = GNUNET_malloc (sizeof (struct StatMaster)); - sm->stat = - GNUNET_STATISTICS_create ("<driver>", - GNUNET_TESTING_daemon_get (pg, - sm->daemon)->cfg); - die_task = GNUNET_SCHEDULER_add_now (&stat_run, sm); -} - - -/** - * Check if the get_handle is being used, if so stop the request. Either - * way, schedule the end_badly_cont function which actually shuts down the - * test. - */ -static void -end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - const char *emsg = cls; - struct TestPutContext *test_put; - struct TestGetContext *test_get; - - die_task = GNUNET_SCHEDULER_NO_TASK; - FPRINTF (stderr, "Failing test with error: `%s'!\n", emsg); - while (NULL != (test_put = all_puts_head)) - { - if (test_put->task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (test_put->task); - if (test_put->dht_handle != NULL) - GNUNET_DHT_disconnect (test_put->dht_handle); - GNUNET_CONTAINER_DLL_remove (all_puts_head, all_puts_tail, test_put); - GNUNET_free (test_put); - } - - while (NULL != (test_get = all_gets_head)) - { - if (test_get->task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (test_get->task); - if (test_get->get_handle != NULL) - GNUNET_DHT_get_stop (test_get->get_handle); - if (test_get->dht_handle != NULL) - GNUNET_DHT_disconnect (test_get->dht_handle); - GNUNET_CONTAINER_DLL_remove (all_gets_head, all_gets_tail, test_get); - GNUNET_free (test_get); - } - ok = 1; - /* testing_peergroup will do that in its own end_badly() handler */ - /*GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); */ - pg = NULL; -} - - -/** - * Task to release get handle. - */ -static void -get_stop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct TestGetContext *test_get = cls; - GNUNET_HashCode search_key; /* Key stored under */ - char original_data[TEST_DATA_SIZE]; /* Made up data to store */ - - test_get->task = GNUNET_SCHEDULER_NO_TASK; - memset (original_data, test_get->uid, sizeof (original_data)); - GNUNET_CRYPTO_hash (original_data, TEST_DATA_SIZE, &search_key); - if (test_get->succeeded != GNUNET_YES) - { - gets_failed++; - FPRINTF (stderr, "Get from peer %s for key %s failed!\n", - GNUNET_i2s (&test_get->daemon->id), GNUNET_h2s (&search_key)); - } - GNUNET_assert (test_get->get_handle != NULL); - GNUNET_DHT_get_stop (test_get->get_handle); - test_get->get_handle = NULL; - - outstanding_gets--; /* GET is really finished */ - GNUNET_DHT_disconnect (test_get->dht_handle); - test_get->dht_handle = NULL; - - GNUNET_CONTAINER_DLL_remove (all_gets_head, all_gets_tail, test_get); - GNUNET_free (test_get); - if ((gets_failed > 10) && (outstanding_gets == 0)) - { - /* Had more than 10% failures */ - FPRINTF (stderr, "%llu gets succeeded, %llu gets failed!\n", gets_completed, - gets_failed); - GNUNET_SCHEDULER_cancel (die_task); - ok = 1; - die_task = - GNUNET_SCHEDULER_add_now (&finish_testing, "not all gets succeeded"); - return; - } - if ((gets_completed + gets_failed == num_peers * num_peers) && (outstanding_gets == 0)) /* All gets successful */ - { - FPRINTF (stderr, "%llu gets succeeded, %llu gets failed!\n", gets_completed, - gets_failed); - GNUNET_SCHEDULER_cancel (die_task); - ok = 0; - die_task = GNUNET_SCHEDULER_add_now (&finish_testing, NULL); - } -} - - -/** - * Iterator called if the GET request initiated returns a response. - * - * @param cls closure - * @param exp when will this value expire - * @param key key of the result - * @param type type of the result - * @param size number of bytes in data - * @param data pointer to the result data - */ -static void -get_result_iterator (void *cls, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_length, enum GNUNET_BLOCK_Type type, - size_t size, const void *data) -{ - struct TestGetContext *test_get = cls; - GNUNET_HashCode search_key; /* Key stored under */ - char original_data[TEST_DATA_SIZE]; /* Made up data to store */ - - memset (original_data, test_get->uid, sizeof (original_data)); - GNUNET_CRYPTO_hash (original_data, TEST_DATA_SIZE, &search_key); - if (test_get->succeeded == GNUNET_YES) - return; /* Get has already been successful, probably ending now */ - -#if PATH_TRACKING - if (put_path != NULL) - { - unsigned int i; - - FPRINTF (stderr, "PUT (%u) Path: ", test_get->uid); - for (i = 0; i < put_path_length; i++) - FPRINTF (stderr, "%s%s", i == 0 ? "" : "->", GNUNET_i2s (&put_path[i])); - FPRINTF (stderr, "%s", "\n"); - } - if (get_path != NULL) - { - unsigned int i; - - FPRINTF (stderr, "GET (%u) Path: ", test_get->uid); - for (i = 0; i < get_path_length; i++) - FPRINTF (stderr, "%s%s", i == 0 ? "" : "->", GNUNET_i2s (&get_path[i])); - FPRINTF (stderr, "%s%s\n", get_path_length > 0 ? "->" : "", - GNUNET_i2s (&test_get->daemon->id)); - } -#endif - - if ((0 != memcmp (&search_key, key, sizeof (GNUNET_HashCode))) || - (0 != memcmp (original_data, data, sizeof (original_data)))) - { - FPRINTF (stderr, "%s", "Key or data is not the same as was inserted!\n"); - return; - } - gets_completed++; - test_get->succeeded = GNUNET_YES; - GNUNET_SCHEDULER_cancel (test_get->task); - test_get->task = GNUNET_SCHEDULER_add_now (&get_stop_task, test_get); -} - - -/** - * Set up some data, and call API PUT function - */ -static void -do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct TestGetContext *test_get = cls; - GNUNET_HashCode key; /* Made up key to store data under */ - char data[TEST_DATA_SIZE]; /* Made up data to store */ - - if (outstanding_gets > MAX_OUTSTANDING_GETS) - { - test_get->task = - GNUNET_SCHEDULER_add_delayed (GET_DELAY, &do_get, test_get); - return; - } - memset (data, test_get->uid, sizeof (data)); - GNUNET_CRYPTO_hash (data, TEST_DATA_SIZE, &key); - test_get->dht_handle = GNUNET_DHT_connect (test_get->daemon->cfg, 10); - GNUNET_assert (test_get->dht_handle != NULL); - outstanding_gets++; - test_get->get_handle = - GNUNET_DHT_get_start (test_get->dht_handle, - GNUNET_BLOCK_TYPE_TEST, &key, 1, route_option, NULL, - 0, &get_result_iterator, test_get); - test_get->task = - GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &get_stop_task, test_get); -} - - -/** - * Task to release DHT handles for PUT - */ -static void -put_disconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct TestPutContext *test_put = cls; - - test_put->task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_DHT_disconnect (test_put->dht_handle); - test_put->dht_handle = NULL; - GNUNET_CONTAINER_DLL_remove (all_puts_head, all_puts_tail, test_put); - GNUNET_free (test_put); -} - - -/** - * Schedule the GET requests - */ -static void -start_gets (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - unsigned long long i; - unsigned long long j; - struct TestGetContext *test_get; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Issuing %llu GETs\n", - (unsigned long long) (num_peers * num_peers)); - for (i = 0; i < num_peers; i++) - for (j = 0; j < num_peers; j++) - { - test_get = GNUNET_malloc (sizeof (struct TestGetContext)); - test_get->uid = i + j * num_peers; - test_get->daemon = GNUNET_TESTING_daemon_get (pg, j); - GNUNET_CONTAINER_DLL_insert (all_gets_head, all_gets_tail, test_get); - test_get->task = GNUNET_SCHEDULER_add_now (&do_get, test_get); - } -} - - -/** - * Called when the PUT request has been transmitted to the DHT service. - */ -static void -put_finished (void *cls, int success) -{ - struct TestPutContext *test_put = cls; - - outstanding_puts--; - puts_completed++; - if (GNUNET_SCHEDULER_NO_TASK != test_put->task) - { - GNUNET_SCHEDULER_cancel (test_put->task); - } - test_put->task = GNUNET_SCHEDULER_add_now (&put_disconnect_task, test_put); - if (puts_completed != num_peers * num_peers) - return; - - GNUNET_assert (outstanding_puts == 0); - GNUNET_SCHEDULER_add_delayed (START_DELAY, &start_gets, NULL); -} - - -/** - * Set up some data, and call API PUT function - */ -static void -do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct TestPutContext *test_put = cls; - GNUNET_HashCode key; /* Made up key to store data under */ - char data[TEST_DATA_SIZE]; /* Made up data to store */ - - test_put->task = GNUNET_SCHEDULER_NO_TASK; - if (outstanding_puts > MAX_OUTSTANDING_PUTS) - { - test_put->task = - GNUNET_SCHEDULER_add_delayed (PUT_DELAY, &do_put, test_put); - return; - } - memset (data, test_put->uid, sizeof (data)); - GNUNET_CRYPTO_hash (data, TEST_DATA_SIZE, &key); - test_put->dht_handle = GNUNET_DHT_connect (test_put->daemon->cfg, 10); - GNUNET_assert (test_put->dht_handle != NULL); - outstanding_puts++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "PUT %u at `%s'\n", test_put->uid, - GNUNET_i2s (&test_put->daemon->id)); - GNUNET_DHT_put (test_put->dht_handle, &key, 1, route_option, - GNUNET_BLOCK_TYPE_TEST, sizeof (data), data, - GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TIME_UNIT_FOREVER_REL, - &put_finished, test_put); - test_put->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &put_disconnect_task, test_put); -} - - -static void -run_dht_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - unsigned long long i; - struct TestPutContext *test_put; - - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) - { - ok = 1; - return; - } -#if PATH_TRACKING - route_option = - GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE; -#else - route_option = GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE; -#endif - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "from setup puts/gets"); - FPRINTF (stderr, "Issuing %llu PUTs (one per peer)\n", - (unsigned long long) (num_peers * num_peers)); - for (i = 0; i < num_peers * num_peers; i++) - { - test_put = GNUNET_malloc (sizeof (struct TestPutContext)); - test_put->uid = i; - test_put->daemon = GNUNET_TESTING_daemon_get (pg, i % num_peers); - test_put->task = GNUNET_SCHEDULER_add_now (&do_put, test_put); - GNUNET_CONTAINER_DLL_insert (all_puts_head, all_puts_tail, test_put); - } -} - - -/** - * This function is called once testing has finished setting up the topology. - * - * @param cls unused - * @param emsg variable is NULL on success (peers connected), and non-NULL on - * failure (peers failed to connect). - */ -static void -startup_done (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - FPRINTF (stderr, "Failed to setup topology: %s\n", emsg); - die_task = GNUNET_SCHEDULER_add_now (&end_badly, "topology setup failed"); - return; - } - die_task = - GNUNET_SCHEDULER_add_delayed (START_DELAY, &run_dht_test, - "from setup puts/gets"); -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - /* Get path from configuration file */ - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", - &test_directory)) - { - GNUNET_break (0); - ok = 404; - return; - } - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", - &num_peers)) - num_peers = DEFAULT_NUM_PEERS; - pg = GNUNET_TESTING_peergroup_start (cfg, num_peers, TIMEOUT, NULL, - &startup_done, NULL, NULL); - GNUNET_assert (NULL != pg); - shutdown_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_FOREVER_REL, - &do_stop, NULL); -} - - -static int -check () -{ - int ret; - - /* Arguments for GNUNET_PROGRAM_run */ - char *const argv[] = { "test-dht-multipeer", /* Name to give running binary */ - "-c", - "test_dht_multipeer_data.conf", /* Config file to use */ - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - /* Run the run function as a new program */ - ret = - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-dht-multipeer", "nohelp", options, &run, &ok); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "`test-dht-multipeer': Failed with error code %d\n", ret); - } - return ok; -} - - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-dht-multipeer", - "WARNING", - NULL); - ret = check (); - /** - * Need to remove base directory, subdirectories taken care - * of by the testing framework. - */ - if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to remove testing directory %s\n", test_directory); - } - return ret; -} - -/* end of test_dht_multipeer.c */ diff --git a/src/dht/test_dht_multipeer.conf b/src/dht/test_dht_multipeer.conf new file mode 100644 index 0000000..1408f05 --- /dev/null +++ b/src/dht/test_dht_multipeer.conf @@ -0,0 +1,59 @@ +[fs] +AUTOSTART = NO + +[resolver] +AUTOSTART = NO + +[block] +plugins = test dht + +[dhtcache] +QUOTA = 1 MB +DATABASE = sqlite + +[transport] +PLUGINS = tcp + +[ats] +WAN_QUOTA_IN = 1 GB +WAN_QUOTA_OUT = 1 GB + +[arm] +DEFAULTSERVICES = dht core + +[TESTING] +WEAKRANDOM = YES + +[testbed] +OVERLAY_TOPOLOGY = FROM_FILE +OVERLAY_TOPOLOGY_FILE = test_dht_multipeer_topology.dat + +[gnunetd] +HOSTKEY = $SERVICEHOME/.hostkey + +[PATHS] +SERVICEHOME = /tmp/test-dht-multipeer/ + +[nat] +DISABLEV6 = YES +RETURN_LOCAL_ADDRESSES = YES +ENABLE_UPNP = NO +BEHIND_NAT = NO +ALLOW_NAT = NO +INTERNAL_ADDRESS = 127.0.0.1 +EXTERNAL_ADDRESS = 127.0.0.1 +USE_LOCALADDR = YES + +[dns] +AUTOSTART = NO + +[namestore] +AUTOSTART = NO + +[nse] +AUTOSTART = NO + +[vpn] +AUTOSTART=NO + + diff --git a/src/dht/test_dht_multipeer_data.conf b/src/dht/test_dht_multipeer_data.conf deleted file mode 100644 index f181594..0000000 --- a/src/dht/test_dht_multipeer_data.conf +++ /dev/null @@ -1,129 +0,0 @@ -[fs] -AUTOSTART = NO - -[resolver] -AUTOSTART = NO - -[dht] -DEBUG = NO -STOP_ON_CLOSEST = YES -AUTOSTART = YES -ACCEPT_FROM6 = ::1; -ACCEPT_FROM = 127.0.0.1; -#BINARY = /home/mrwiggles/documents/research/gnunet/gnunet-ng/src/dht/.libs/gnunet-service-dht -#PREFIX = xterm -T dht -e gdb --args -#PREFIX = valgrind --log-file=dht_%p -CONFIG = $DEFAULTCONFIG -HOME = $SERVICEHOME -HOSTNAME = localhost -PORT = 12100 -STOP_FOUND = YES -USE_MAX_HOPS = YES -MAX_HOPS = 16 -CONVERGE_BINARY = YES -CONVERGE_MODIFIER = 4 - -[block] -plugins = test dht - -[dhtcache] -QUOTA = 1 MB -DATABASE = sqlite - -[transport] -PLUGINS = tcp -DEBUG = NO -ACCEPT_FROM6 = ::1; -ACCEPT_FROM = 127.0.0.1; -NEIGHBOUR_LIMIT = 50 -BINARY = gnunet-service-transport -CONFIG = $DEFAULTCONFIG -HOME = $SERVICEHOME -HOSTNAME = localhost -PORT = 12365 - -[DHTLOG] -PLUGIN = mysql_dump - -[ats] -WAN_QUOTA_IN = 1 GB -WAN_QUOTA_OUT = 1 GB - -[core] -ACCEPT_FROM6 = ::1; -ACCEPT_FROM = 127.0.0.1; -BINARY = gnunet-service-core -CONFIG = $DEFAULTCONFIG -HOME = $SERVICEHOME -HOSTNAME = localhost -PORT = 12092 -DEBUG = NO - -[arm] -DEFAULTSERVICES = dht core -ACCEPT_FROM6 = ::1; -ACCEPT_FROM = 127.0.0.1; -BINARY = gnunet-service-arm -CONFIG = $DEFAULTCONFIG -HOME = $SERVICEHOME -HOSTNAME = localhost -PORT = 12366 -DEBUG = NO - -[transport-tcp] -TIMEOUT = 300 s -PORT = 12368 -BINDTO = 127.0.0.1 - -[DHT_TESTING] -MYSQL_LOGGING_EXTENDED = NO -MYSQL_LOGGING = NO -NUM_GETS = 5 -NUM_PUTS = 5 - -[TESTING] -TOPOLOGY = FROM_FILE -# file contains a ring -CONNECT_TOPOLOGY = NONE -# None == use all allowed connections -# BLACKLIST_TOPOLOGY = X -# No additional restrictions... - -TOPOLOGY_FILE = multipeer_topo.dat -MAX_CONCURRENT_SSH = 1 -PEERGROUP_TIMEOUT = 2400 s -USE_PROGRESSBARS = YES -#CONNECT_TOPOLOGY_OPTION = CONNECT_RANDOM_SUBSET -#CONNECT_TOPOLOGY_OPTION_MODIFIER = 2 -#LOGNMODIFIER = .65 -#PERCENTAGE = .75 -WEAKRANDOM = YES -NUM_PEERS = 10 -HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat - -[gnunetd] -HOSTKEY = $SERVICEHOME/.hostkey - -[PATHS] -DEFAULTCONFIG = test_dht_multipeer_data.conf -SERVICEHOME = /tmp/test-dht-multipeer/ - -[nat] -DISABLEV6 = YES -ENABLE_UPNP = NO -BEHIND_NAT = NO -ALLOW_NAT = NO -INTERNAL_ADDRESS = 127.0.0.1 -EXTERNAL_ADDRESS = 127.0.0.1 -USE_LOCALADDR = YES - -[dns] -AUTOSTART = NO - -[namestore] -AUTOSTART = NO - -[nse] -AUTOSTART = NO - - diff --git a/src/dht/test_dht_multipeer_topology.dat b/src/dht/test_dht_multipeer_topology.dat new file mode 100644 index 0000000..2268c85 --- /dev/null +++ b/src/dht/test_dht_multipeer_topology.dat @@ -0,0 +1,11 @@ +0:1|6|8 +1:2|7|9 +2:0|3|8 +3:1|4|9 +4:0|2|5 +5:1|3|6 +6:2|4|7 +7:3|5|8 +8:4|6|9 +9:0|5|7 + diff --git a/src/dht/test_dht_tools.py b/src/dht/test_dht_tools.py new file mode 100755 index 0000000..c2e7646 --- /dev/null +++ b/src/dht/test_dht_tools.py @@ -0,0 +1,123 @@ +#!/usr/bin/python +from __future__ import print_function +import os +import sys +import shutil +import re +import subprocess +import time +import tempfile + +if os.name == "nt": + tmp = os.getenv ("TEMP") +else: + tmp = "/tmp" + +if os.name == 'nt': + pif = 'gnunet-peerinfo.exe' + get = 'gnunet-dht-get.exe' + put = 'gnunet-dht-put.exe' + arm = 'gnunet-arm.exe' +else: + pif = 'gnunet-peerinfo' + get = './gnunet-dht-get' + put = './gnunet-dht-put' + arm = 'gnunet-arm' + +tf, tempcfg = tempfile.mkstemp (prefix='test_dht_api_peer1.') +os.close (tf) + +run_pif = [pif, '-c', tempcfg, '-sq'] +run_get = [get, '-c', tempcfg] +run_put = [put, '-c', tempcfg] +run_arm = [arm, '-c', tempcfg] +debug = os.getenv ('DEBUG') +if debug: + run_arm += [debug.split (' ')] + +def cleanup (exitcode): + os.remove (tempcfg) + sys.exit (exitcode) + +def sub_run (args, want_stdo = True, want_stde = False, nofail = False): + if want_stdo: + stdo = subprocess.PIPE + else: + stdo = None + if want_stde: + stde = subprocess.PIPE + else: + stde = None + p = subprocess.Popen (args, stdout = stdo, stderr = stde) + stdo, stde = p.communicate () + if not nofail: + if p.returncode != 0: + sys.exit (p.returncode) + return (p.returncode, stdo, stde) + +def fail (result): + print (result) + r_arm (['-e'], want_stdo = False) + cleanup (1) + +def r_something (to_run, extra_args, failer = None, normal = True, **kw): + rc, stdo, stde = sub_run (to_run + extra_args, nofail = True, **kw) + if failer is not None: + failer (to_run + extra_args, rc, stdo, stde, normal) + return (rc, stdo, stde) + +def r_arm (extra_args, **kw): + return r_something (run_arm, extra_args, **kw) + +def r_pif (extra_args, **kw): + return r_something (run_pif, extra_args, **kw) + +def r_get (extra_args, **kw): + return r_something (run_get, extra_args, **kw) + +def r_put (extra_args, **kw): + return r_something (run_put, extra_args, **kw) + +def end_arm_failer (command, rc, stdo, stde, normal): + if normal: + if rc != 0: + fail ("FAIL: error running {}\nCommand output was:\n{}\n{}".format (command, stdo, stde)) + else: + if rc == 0: + fail ("FAIL: expected error while running {}\nCommand output was:\n{}\n{}".format (command, stdo, stde)) + +def print_only_failer (command, rc, stdo, stde, normal): + if normal: + if rc != 0: + print ("FAIL: error running {}\nCommand output was:\n{}\n{}".format (command, stdo, stde)) + cleanup (1) + else: + if rc == 0: + print ("FAIL: expected error while running {}\nCommand output was:\n{}\n{}".format (command, stdo, stde)) + cleanup (1) + +shutil.copyfile ('test_dht_api_peer1.conf', tempcfg) + +print ("TEST: Generating hostkey...", end='') +r_pif ([], failer = print_only_failer) +print ("PASS") + +print ("TEST: Starting ARM...", end='') +r_arm (['-s'], failer = end_arm_failer, want_stdo = False, want_stde = False) +print ("PASS") +time.sleep (1) + +print ("TEST: Testing put...", end='') +r_put (['-k', 'testkey', '-d', 'testdata', '-t', '8'], failer = end_arm_failer) +print ("PASS") +time.sleep (1) + +print ("TEST: Testing get...", end='') +rc, stdo, stde = r_get (['-k', 'testkey', '-T', '5', '-t', '8'], want_stdo = True, failer = end_arm_failer) +stdo = stdo.replace ('\r', '').splitlines () +expect = "Result 0, type 8:\ntestdata".splitlines() +if len (stdo) != 2 or len (expect) != 2 or stdo[0] != expect[0] or stdo[1] != expect[1]: + fail ("output `{}' differs from expected `{}'".format (stdo, expect)) +print ("PASS") + +r_arm (['-e', '-d'], failer = print_only_failer) diff --git a/src/dht/test_dht_tools.py.in b/src/dht/test_dht_tools.py.in new file mode 100644 index 0000000..7247836 --- /dev/null +++ b/src/dht/test_dht_tools.py.in @@ -0,0 +1,123 @@ +#!@PYTHON@ +from __future__ import print_function +import os +import sys +import shutil +import re +import subprocess +import time +import tempfile + +if os.name == "nt": + tmp = os.getenv ("TEMP") +else: + tmp = "/tmp" + +if os.name == 'nt': + pif = 'gnunet-peerinfo.exe' + get = 'gnunet-dht-get.exe' + put = 'gnunet-dht-put.exe' + arm = 'gnunet-arm.exe' +else: + pif = 'gnunet-peerinfo' + get = './gnunet-dht-get' + put = './gnunet-dht-put' + arm = 'gnunet-arm' + +tf, tempcfg = tempfile.mkstemp (prefix='test_dht_api_peer1.') +os.close (tf) + +run_pif = [pif, '-c', tempcfg, '-sq'] +run_get = [get, '-c', tempcfg] +run_put = [put, '-c', tempcfg] +run_arm = [arm, '-c', tempcfg] +debug = os.getenv ('DEBUG') +if debug: + run_arm += [debug.split (' ')] + +def cleanup (exitcode): + os.remove (tempcfg) + sys.exit (exitcode) + +def sub_run (args, want_stdo = True, want_stde = False, nofail = False): + if want_stdo: + stdo = subprocess.PIPE + else: + stdo = None + if want_stde: + stde = subprocess.PIPE + else: + stde = None + p = subprocess.Popen (args, stdout = stdo, stderr = stde) + stdo, stde = p.communicate () + if not nofail: + if p.returncode != 0: + sys.exit (p.returncode) + return (p.returncode, stdo, stde) + +def fail (result): + print (result) + r_arm (['-e'], want_stdo = False) + cleanup (1) + +def r_something (to_run, extra_args, failer = None, normal = True, **kw): + rc, stdo, stde = sub_run (to_run + extra_args, nofail = True, **kw) + if failer is not None: + failer (to_run + extra_args, rc, stdo, stde, normal) + return (rc, stdo, stde) + +def r_arm (extra_args, **kw): + return r_something (run_arm, extra_args, **kw) + +def r_pif (extra_args, **kw): + return r_something (run_pif, extra_args, **kw) + +def r_get (extra_args, **kw): + return r_something (run_get, extra_args, **kw) + +def r_put (extra_args, **kw): + return r_something (run_put, extra_args, **kw) + +def end_arm_failer (command, rc, stdo, stde, normal): + if normal: + if rc != 0: + fail ("FAIL: error running {}\nCommand output was:\n{}\n{}".format (command, stdo, stde)) + else: + if rc == 0: + fail ("FAIL: expected error while running {}\nCommand output was:\n{}\n{}".format (command, stdo, stde)) + +def print_only_failer (command, rc, stdo, stde, normal): + if normal: + if rc != 0: + print ("FAIL: error running {}\nCommand output was:\n{}\n{}".format (command, stdo, stde)) + cleanup (1) + else: + if rc == 0: + print ("FAIL: expected error while running {}\nCommand output was:\n{}\n{}".format (command, stdo, stde)) + cleanup (1) + +shutil.copyfile ('test_dht_api_peer1.conf', tempcfg) + +print ("TEST: Generating hostkey...", end='') +r_pif ([], failer = print_only_failer) +print ("PASS") + +print ("TEST: Starting ARM...", end='') +r_arm (['-s'], failer = end_arm_failer, want_stdo = False, want_stde = False) +print ("PASS") +time.sleep (1) + +print ("TEST: Testing put...", end='') +r_put (['-k', 'testkey', '-d', 'testdata', '-t', '8'], failer = end_arm_failer) +print ("PASS") +time.sleep (1) + +print ("TEST: Testing get...", end='') +rc, stdo, stde = r_get (['-k', 'testkey', '-T', '5', '-t', '8'], want_stdo = True, failer = end_arm_failer) +stdo = stdo.replace ('\r', '').splitlines () +expect = "Result 0, type 8:\ntestdata".splitlines() +if len (stdo) != 2 or len (expect) != 2 or stdo[0] != expect[0] or stdo[1] != expect[1]: + fail ("output `{}' differs from expected `{}'".format (stdo, expect)) +print ("PASS") + +r_arm (['-e', '-d'], failer = print_only_failer) diff --git a/src/dht/test_dht_tools.sh b/src/dht/test_dht_tools.sh deleted file mode 100755 index f83c26a..0000000 --- a/src/dht/test_dht_tools.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh - -out=`mktemp /tmp/test-gnunet-dht-logXXXXXXXX` -tempcfg=`mktemp /tmp/test_dht_api_peer1.XXXXXXXX` -checkout="check.out" -armexe="gnunet-arm -c $tempcfg " -putexe="gnunet-dht-put -c $tempcfg " -getexe="gnunet-dht-get -c $tempcfg " -peerinfo="gnunet-peerinfo -c $tempcfg -sq" -stop_arm() -{ - if ! $armexe $DEBUG -e -d > $out ; then - echo "FAIL: error running $armexe" - echo "Command output was:" - cat $out - rm -f $out $tempcfg - exit 1 - fi - rm -f $out $tempcfg -} - -cp test_dht_api_peer1.conf $tempcfg - -echo -n "TEST: Generating hostkey..." -if ! $peerinfo > $out ; then - echo "FAIL: error running $peerinfo" - echo "Command output was:" - cat $out - exit 1 -fi -echo "PASS" - -echo -n "TEST: Starting ARM..." -if ! $armexe $DEBUG -s > $out ; then - echo "FAIL: error running $armexe" - echo "Command output was:" - cat $out - stop_arm - exit 1 -fi -echo "PASS" -sleep 1 - -echo -n "TEST: Testing put..." -if ! $putexe -k testkey -d testdata -t 8 > $out ; then - echo "FAIL: error running $putexe" - echo "Command output was:" - cat $out - stop_arm - exit 1 -fi -echo "PASS" -sleep 1 - -echo -n "TEST: Testing get..." -echo "Result 0, type 8:" > $checkout -echo "testdata" >> $checkout - -if ! $getexe -k testkey -T 5 -t 8 > $out ; then - echo "FAIL: error running $putexe" - echo "Command output was:" - cat $out - stop_arm - exit 1 -fi - -if ! diff --strip-trailing-cr -q $out $checkout ; then - echo "FAIL: $out and $checkout differ" - stop_arm - exit 1 -fi -echo "PASS" -stop_arm diff --git a/src/dht/test_dht_topo.c b/src/dht/test_dht_topo.c index f51f3a6..c9036d2 100644 --- a/src/dht/test_dht_topo.c +++ b/src/dht/test_dht_topo.c @@ -19,535 +19,384 @@ */ /** * @file dht/test_dht_topo.c - * + * @author Christian Grothoff * @brief Test for the dht service: store and retrieve in various topologies. - * Each peer stores it own ID in the DHT and then a different peer tries to - * retrieve that key from it. The GET starts after a first round of PUTS has - * been made. Periodically, each peer stores its ID into the DHT. If after - * a timeout no result has been returned, the test fails. + * Each peer stores a value from the DHT and then each peer tries to get each + * value from each other peer. */ #include "platform.h" -#include "gnunet_testing_lib.h" +#include "gnunet_util_lib.h" #include "gnunet_dht_service.h" - -#define REMOVE_DIR GNUNET_YES +#include "dht_test_lib.h" /** - * DIFFERENT TESTS TO RUN + * How long until we give up on fetching the data? */ -#define LINE 0 -#define TORUS 1 +#define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) /** - * How long until we give up on connecting the peers? + * How frequently do we execute the PUTs? */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500) - -#define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) - #define PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) -/** - * Result of the test. - */ -static int ok; /** - * Total number of peers in the test. + * Information we keep for each GET operation. */ -static unsigned long long num_peers; +struct GetOperation +{ + /** + * DLL. + */ + struct GetOperation *next; -/** - * Global configuration file - */ -static struct GNUNET_CONFIGURATION_Handle *testing_cfg; + /** + * DLL. + */ + struct GetOperation *prev; -/** - * Total number of currently running peers. - */ -static unsigned long long peers_running; + /** + * Handle for the operation. + */ + struct GNUNET_DHT_GetHandle *get; + +}; -/** - * Total number of connections in the whole network. - */ -static unsigned int total_connections; /** - * The currently running peer group. + * Result of the test. */ -static struct GNUNET_TESTING_PeerGroup *pg; +static int ok = 1; /** - * File to report results to. + * Task to do DHT_puts */ -static struct GNUNET_DISK_FileHandle *output_file; +static GNUNET_SCHEDULER_TaskIdentifier put_task; /** - * File to log connection info, statistics to. + * Task to time out / regular shutdown. */ -static struct GNUNET_DISK_FileHandle *data_file; +static GNUNET_SCHEDULER_TaskIdentifier timeout_task; /** - * Task called to disconnect peers. + * Head of list of active GET operations. */ -static GNUNET_SCHEDULER_TaskIdentifier disconnect_task; +static struct GetOperation *get_head; /** - * Task To perform tests + * Tail of list of active GET operations. */ -static GNUNET_SCHEDULER_TaskIdentifier test_task; +static struct GetOperation *get_tail; /** - * Task to do DHT_puts - */ -static GNUNET_SCHEDULER_TaskIdentifier put_task; + * Array of the testbed's peers. + */ +static struct GNUNET_TESTBED_Peer **my_peers; /** - * Task called to shutdown test. + * Number of peers to run. */ -static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle; - -static char *topology_file; - -static struct GNUNET_DHT_Handle **hs; - -static struct GNUNET_DHT_GetHandle *get_h; - -static struct GNUNET_DHT_GetHandle *get_h_2; - -static struct GNUNET_DHT_GetHandle *get_h_far; - -static int found_1; +static unsigned int NUM_PEERS; -static int found_2; - -static int found_far; /** - * Which topology are we to run + * Statistics we print out. */ -static int test_topology; +static struct +{ + const char *subsystem; + const char *name; + unsigned long long total; +} stats[] = { + {"core", "# bytes decrypted", 0}, + {"core", "# bytes encrypted", 0}, + {"core", "# type maps received", 0}, + {"core", "# session keys confirmed via PONG", 0}, + {"core", "# peers connected", 0}, + {"core", "# key exchanges initiated", 0}, + {"core", "# send requests dropped (disconnected)", 0}, + {"core", "# transmissions delayed due to corking", 0}, + {"core", "# messages discarded (expired prior to transmission)", 0}, + {"core", "# messages discarded (disconnected)", 0}, + {"core", "# discarded CORE_SEND requests", 0}, + {"core", "# discarded lower priority CORE_SEND requests", 0}, + {"transport", "# bytes received via TCP", 0}, + {"transport", "# bytes transmitted via TCP", 0}, + {"dht", "# PUT messages queued for transmission", 0}, + {"dht", "# P2P PUT requests received", 0}, + {"dht", "# GET messages queued for transmission", 0}, + {"dht", "# P2P GET requests received", 0}, + {"dht", "# RESULT messages queued for transmission", 0}, + {"dht", "# P2P RESULTS received", 0}, + {"dht", "# Queued messages discarded (peer disconnected)", 0}, + {"dht", "# Peers excluded from routing due to Bloomfilter", 0}, + {"dht", "# Peer selection failed", 0}, + {"dht", "# FIND PEER requests ignored due to Bloomfilter", 0}, + {"dht", "# FIND PEER requests ignored due to lack of HELLO", 0}, + {"dht", "# P2P FIND PEER requests processed", 0}, + {"dht", "# P2P GET requests ONLY routed", 0}, + {"dht", "# Preference updates given to core", 0}, + {"dht", "# REPLIES ignored for CLIENTS (no match)", 0}, + {"dht", "# GET requests from clients injected", 0}, + {"dht", "# GET requests received from clients", 0}, + {"dht", "# GET STOP requests received from clients", 0}, + {"dht", "# ITEMS stored in datacache", 0}, + {"dht", "# Good RESULTS found in datacache", 0}, + {"dht", "# GET requests given to datacache", 0}, + {NULL, NULL, 0} +}; /** - * Check whether peers successfully shut down. + * Function called once we're done processing stats. + * + * @param cls the test context + * @param op the stats operation + * @param emsg error message on failure */ static void -shutdown_callback (void *cls, const char *emsg) +stats_finished (void *cls, + struct GNUNET_TESTBED_Operation *op, + const char *emsg) { - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Shutdown of peers failed!\n"); - ok++; - } - else + struct GNUNET_DHT_TEST_Context *ctx = cls; + unsigned int i; + + if (NULL != op) + GNUNET_TESTBED_operation_done (op); // needed? + if (NULL != emsg) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "All peers successfully shut down!\n"); + fprintf (stderr, _("Gathering statistics failed: %s\n"), + emsg); + GNUNET_SCHEDULER_cancel (put_task); + GNUNET_DHT_TEST_cleanup (ctx); + return; } - GNUNET_CONFIGURATION_destroy (testing_cfg); + for (i = 0; NULL != stats[i].name; i++) + FPRINTF (stderr, + "%6s/%60s = %12llu\n", + stats[i].subsystem, + stats[i].name, + stats[i].total); + GNUNET_SCHEDULER_cancel (put_task); + GNUNET_DHT_TEST_cleanup (ctx); } -static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +/** + * Function called to process statistic values from all peers. + * + * @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 +handle_stats (void *cls, + const struct GNUNET_TESTBED_Peer *peer, + const char *subsystem, + const char *name, + uint64_t value, + int is_persistent) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Ending test.\n"); - - if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_NO_TASK; - } + unsigned int i; - if (data_file != NULL) - GNUNET_DISK_file_close (data_file); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); + for (i = 0; NULL != stats[i].name; i++) + if ( (0 == strcasecmp (subsystem, + stats[i].subsystem)) && + (0 == strcasecmp (name, + stats[i].name)) ) + stats[i].total += value; + return GNUNET_OK; } +/** + * Task run on success or timeout to clean up. + * Terminates active get operations and shuts down + * the testbed. + * + * @param cls the 'struct GNUNET_DHT_TestContext' + * @param tc scheduler context + */ static void -disconnect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - unsigned int i; + struct GNUNET_DHT_TEST_Context *ctx = cls; + struct GetOperation *get_op; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "disconnecting peers\n"); - disconnect_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_SCHEDULER_cancel (put_task); - if (NULL != get_h) - GNUNET_DHT_get_stop (get_h); - if (NULL != get_h_2) - GNUNET_DHT_get_stop (get_h_2); - if (NULL != get_h_far) - GNUNET_DHT_get_stop (get_h_far); - for (i = 0; i < num_peers; i++) + while (NULL != (get_op = get_tail)) { - GNUNET_DHT_disconnect (hs[i]); + GNUNET_DHT_get_stop (get_op->get); + GNUNET_CONTAINER_DLL_remove (get_head, + get_tail, + get_op); + GNUNET_free (get_op); } - GNUNET_SCHEDULER_cancel (shutdown_handle); - shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + (void) GNUNET_TESTBED_get_statistics (NUM_PEERS, + my_peers, + &handle_stats, + &stats_finished, + ctx); } +/** + * Iterator called on each result obtained for a DHT + * operation that expects a reply + * + * @param cls closure with our 'struct GetOperation' + * @param exp when will this value expire + * @param key key of the result + * @param get_path peers on reply path (or NULL if not recorded) + * @param get_path_length number of entries in get_path + * @param put_path peers on the PUT path (or NULL if not recorded) + * @param put_path_length number of entries in get_path + * @param type type of the result + * @param size number of bytes in data + * @param data pointer to the result data + */ static void -dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_length, enum GNUNET_BLOCK_Type type, - size_t size, const void *data) +dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp, + const struct GNUNET_HashCode * key, + const struct GNUNET_PeerIdentity *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int put_path_length, enum GNUNET_BLOCK_Type type, + size_t size, const void *data) { - int i; + struct GetOperation *get_op = cls; + struct GNUNET_HashCode want; + struct GNUNET_DHT_TestContext *ctx; - if (sizeof (GNUNET_HashCode) == size) + if (sizeof (struct GNUNET_HashCode) != size) { - const GNUNET_HashCode *h = data; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Contents: %s\n", - GNUNET_h2s_full (h)); - - } - else - { - GNUNET_break(0); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH: (get %u, put %u)\n", - get_path_length, put_path_length); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " LOCAL\n"); - for (i = get_path_length - 1; i >= 0; i--) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", - GNUNET_i2s (&get_path[i])); + GNUNET_break (0); + return; } - for (i = put_path_length - 1; i >= 0; i--) + GNUNET_CRYPTO_hash (key, sizeof (*key), &want); + if (0 != memcmp (&want, data, sizeof (want))) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", - GNUNET_i2s (&put_path[i])); + GNUNET_break (0); + return; } - switch ((long)cls) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Get successful\n"); +#if 0 { - case 1: - found_1++; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "FOUND 1!\n"); - break; - case 2: - found_2++; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "FOUND 2!\n"); - break; - case 3: - found_far++; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "FOUND FAR!\n"); - break; - default: - GNUNET_break(0); + int i; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH: (get %u, put %u)\n", + get_path_length, put_path_length); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " LOCAL\n"); + for (i = get_path_length - 1; i >= 0; i--) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", + GNUNET_i2s (&get_path[i])); + for (i = put_path_length - 1; i >= 0; i--) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", + GNUNET_i2s (&put_path[i])); } - if ( (TORUS == test_topology) && - ( (found_1 == 0) || (found_2 == 0) || (found_far == 0)) ) +#endif + GNUNET_DHT_get_stop (get_op->get); + GNUNET_CONTAINER_DLL_remove (get_head, + get_tail, + get_op); + GNUNET_free (get_op); + if (NULL != get_head) return; + /* all DHT GET operations successful; terminate! */ ok = 0; - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); + ctx = GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = GNUNET_SCHEDULER_add_now (&shutdown_task, ctx); } -static void -do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_TESTING_Daemon *d; - struct GNUNET_TESTING_Daemon *d2; - struct GNUNET_TESTING_Daemon *d_far; - struct GNUNET_TESTING_Daemon *o; - struct GNUNET_TESTING_Daemon *aux; - const char *id_aux; - const char *id_origin = "FC74"; - const char *id_near = "9P6V"; - const char *id_near2 = "2GDS"; - const char *id_far = "KPST"; - unsigned int i; - - d = d2 = d_far = o = NULL; - found_1 = found_2 = found_far = 0; - if (LINE == test_topology) - { - o = GNUNET_TESTING_daemon_get (pg, 0); - d = GNUNET_TESTING_daemon_get (pg, 4); - } - else if (TORUS == test_topology) - { - for (i = 0; i < num_peers; i++) - { - aux = GNUNET_TESTING_daemon_get (pg, i); - id_aux = GNUNET_i2s (&aux->id); - if (strcmp (id_aux, id_origin) == 0) - o = aux; - if (strcmp (id_aux, id_far) == 0) - d_far = aux; - if (strcmp (id_aux, id_near) == 0) - d = aux; - if (strcmp (id_aux, id_near2) == 0) - d2 = aux; - } - if ((NULL == o) || (NULL == d) || (NULL == d2) || (NULL == d_far)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Peers not found (hostkey file changed?)\n"); - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); - return; - } - } - else - { - GNUNET_assert (0); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_task\nfrom %s\n", - GNUNET_h2s_full (&o->id.hashPubKey)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", - GNUNET_h2s_full (&d->id.hashPubKey)); - get_h = GNUNET_DHT_get_start (hs[0], - GNUNET_BLOCK_TYPE_TEST, /* type */ - &d->id.hashPubKey, /*key to search */ - 4U, /* replication level */ - GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, NULL, /* xquery */ - 0, /* xquery bits */ - &dht_get_id_handler, (void *)1); - if (TORUS == test_topology) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", - GNUNET_h2s_full (&d2->id.hashPubKey)); - get_h_2 = GNUNET_DHT_get_start (hs[0], - GNUNET_BLOCK_TYPE_TEST, /* type */ - &d2->id.hashPubKey, /*key to search */ - 4U, /* replication level */ - GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, NULL, /* xquery */ - 0, /* xquery bits */ - &dht_get_id_handler, (void *)2); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", - GNUNET_h2s_full (&d_far->id.hashPubKey)); - get_h_far = GNUNET_DHT_get_start (hs[0], - GNUNET_BLOCK_TYPE_TEST, /* type */ - &d_far->id.hashPubKey, /*key to search */ - 4U, /* replication level */ - GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, NULL, /* xquery */ - 0, /* xquery bits */ - &dht_get_id_handler, (void *)3); - } - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &disconnect_peers, NULL); -} - /** - * Task to put the id of each peer into teh DHT. + * Task to put the id of each peer into the DHT. * - * @param cls Closure (unused) + * @param cls array with NUM_PEERS DHT handles * @param tc Task context - * */ static void -put_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +do_puts (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_TESTING_Daemon *d; + struct GNUNET_DHT_Handle **hs = cls; + struct GNUNET_HashCode key; + struct GNUNET_HashCode value; unsigned int i; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "putting id's in DHT\n"); - for (i = 0; i < num_peers; i++) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Putting values into DHT\n"); + for (i = 0; i < NUM_PEERS; i++) { - d = GNUNET_TESTING_daemon_get (pg, i); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " putting into DHT: %s\n", - GNUNET_h2s_full (&d->id.hashPubKey)); - GNUNET_DHT_put (hs[i], &d->id.hashPubKey, 10U, + GNUNET_CRYPTO_hash (&i, sizeof (i), &key); + GNUNET_CRYPTO_hash (&key, sizeof (key), &value); + GNUNET_DHT_put (hs[i], &key, 10U, GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, - GNUNET_BLOCK_TYPE_TEST, sizeof (struct GNUNET_PeerIdentity), - (const char *) &d->id, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_TIME_UNIT_FOREVER_REL, NULL, NULL); - + GNUNET_BLOCK_TYPE_TEST, + sizeof (value), &value, + GNUNET_TIME_UNIT_FOREVER_ABS, + GNUNET_TIME_UNIT_FOREVER_REL, + NULL, NULL); } - put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY, &put_id, NULL); - if (GNUNET_SCHEDULER_NO_TASK == test_task) - test_task = GNUNET_SCHEDULER_add_now (&do_test, NULL); + put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY, + &do_puts, hs); } /** - * peergroup_ready: start test when all peers are connected - * - * @param cls closure - * @param emsg error message - * - */ -static void -peergroup_ready (void *cls, const char *emsg) -{ - struct GNUNET_TESTING_Daemon *d; - char *buf; - int buf_len; - unsigned int i; - - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peergroup callback called with error, aborting test!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error from testing: `%s'\n", - emsg); - ok++; - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peer Group started successfully with %u connections\n", - total_connections); - if (data_file != NULL) - { - buf = NULL; - buf_len = GNUNET_asprintf (&buf, "CONNECTIONS_0: %u\n", total_connections); - if (buf_len > 0) - GNUNET_DISK_file_write (data_file, buf, buf_len); - GNUNET_free (buf); - } - peers_running = GNUNET_TESTING_daemons_running (pg); - - GNUNET_assert (peers_running == num_peers); - hs = GNUNET_malloc (num_peers * sizeof (struct GNUNET_DHT_Handle *)); - for (i = 0; i < num_peers; i++) - { - d = GNUNET_TESTING_daemon_get (pg, i); - hs[i] = GNUNET_DHT_connect (d->cfg, 32); - } - - test_task = GNUNET_SCHEDULER_NO_TASK; - put_task = GNUNET_SCHEDULER_add_now (&put_id, NULL); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &disconnect_peers, NULL); - -} - - -/** - * Function that will be called whenever two daemons are connected by - * the testing library. + * Main function of the test. * - * @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) - */ -static void -connect_cb (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) -{ - if (emsg == NULL) - { - total_connections++; - GNUNET_PEER_intern (first); - GNUNET_PEER_intern (second); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Problem with new connection (%s)\n", emsg); - } -} - - -/** - * run: load configuration options and schedule test to run (start peergroup) - * @param cls closure - * @param args argv - * @param cfgfile configuration file name (can be NULL) - * @param cfg configuration handle + * @param cls closure (NULL) + * @param ctx argument to give to GNUNET_DHT_TEST_cleanup on test end + * @param num_peers number of peers that are running + * @param peers array of peers + * @param dhts handle to each of the DHTs of the peers */ static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) +run (void *cls, + struct GNUNET_DHT_TEST_Context *ctx, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, + struct GNUNET_DHT_Handle **dhts) { - char *temp_str; - struct GNUNET_TESTING_Host *hosts; - char *data_filename; - - ok = 1; - testing_cfg = GNUNET_CONFIGURATION_dup (cfg); - - GNUNET_log_setup ("test_dht_topo", - "WARNING", - NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n"); - GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing", - "use_progressbars", "YES"); - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing", - "num_peers", &num_peers)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Option TESTING:NUM_PEERS is required!\n"); - return; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (testing_cfg, "testing", - "topology_output_file", - &topology_file)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Option test_dht_topo:topology_output_file is required!\n"); - return; - } - - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (testing_cfg, "test_dht_topo", - "data_output_file", - &data_filename)) + unsigned int i; + unsigned int j; + struct GNUNET_HashCode key; + struct GetOperation *get_op; + + GNUNET_assert (NUM_PEERS == num_peers); + my_peers = peers; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peers setup, starting test\n"); + put_task = GNUNET_SCHEDULER_add_now (&do_puts, dhts); + for (i=0;i<num_peers;i++) { - data_file = - GNUNET_DISK_file_open (data_filename, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - if (data_file == NULL) + GNUNET_CRYPTO_hash (&i, sizeof (i), &key); + for (j=0;j<num_peers;j++) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n", - data_filename); - GNUNET_free (data_filename); + get_op = GNUNET_malloc (sizeof (struct GetOperation)); + GNUNET_CONTAINER_DLL_insert (get_head, + get_tail, + get_op); + get_op->get = GNUNET_DHT_get_start (dhts[j], + GNUNET_BLOCK_TYPE_TEST, /* type */ + &key, /*key to search */ + 4U, /* replication level */ + GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, + NULL, /* xquery */ + 0, /* xquery bits */ + &dht_get_handler, get_op); } } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "test_dht_topo", - "output_file", &temp_str)) - { - output_file = - GNUNET_DISK_file_open (temp_str, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - if (output_file == NULL) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n", - temp_str); - } - GNUNET_free_non_null (temp_str); - - hosts = GNUNET_TESTING_hosts_load (testing_cfg); - - pg = GNUNET_TESTING_peergroup_start (testing_cfg, num_peers, TIMEOUT, - &connect_cb, &peergroup_ready, NULL, - hosts); - GNUNET_assert (pg != NULL); - shutdown_handle = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &shutdown_task, NULL); + timeout_task = GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, + &shutdown_task, ctx); } @@ -557,62 +406,42 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int xargc, char *xargv[]) { - static struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - static char *const argv_torus[] = { "test-dht-2dtorus", - "-c", - "test_dht_2dtorus.conf", - NULL - }; - static char *const argv_line[] = { "test-dht-line", - "-c", - "test_dht_line.conf", - NULL - }; - char *const *argv; - int argc; + const char *cfg_filename; + const char *test_name; - if (strstr (xargv[0], "test_dht_2dtorus") != NULL) + if (NULL != strstr (xargv[0], "test_dht_2dtorus")) { - argv = argv_torus; - argc = sizeof (argv_torus) / sizeof (char *); - test_topology = TORUS; + cfg_filename = "test_dht_2dtorus.conf"; + test_name = "test-dht-2dtorus"; + NUM_PEERS = 16; } - else if (strstr (xargv[0], "test_dht_line") != NULL) + else if (NULL != strstr (xargv[0], "test_dht_line")) { - argv = argv_line; - argc = sizeof (argv_line) / sizeof (char *); - test_topology = LINE; + cfg_filename = "test_dht_line.conf"; + test_name = "test-dht-line"; + NUM_PEERS = 5; } - else + else if (NULL != strstr (xargv[0], "test_dht_twopeer")) { - GNUNET_break (0); - return 1; + cfg_filename = "test_dht_line.conf"; + test_name = "test-dht-twopeer"; + NUM_PEERS = 2; } - GNUNET_PROGRAM_run (argc - 1, argv, - xargv[0], - gettext_noop ("Test dht in different topologies."), - options, - &run, NULL); -#if REMOVE_DIR - GNUNET_DISK_directory_remove ("/tmp/test_dht_topo"); -#endif - if (0 == found_1) + else if (NULL != strstr (xargv[0], "test_dht_multipeer")) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID 1 not found!\n"); + cfg_filename = "test_dht_multipeer.conf"; + test_name = "test-dht-multipeer"; + NUM_PEERS = 10; } - if (TORUS == test_topology) + else { - if (0 == found_2) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID 2 not found!\n"); - } - if (0 == found_far) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID far not found!\n"); - } + GNUNET_break (0); + return 1; } + GNUNET_DHT_TEST_run (test_name, + cfg_filename, + NUM_PEERS, + &run, NULL); return ok; } diff --git a/src/dht/test_dht_twopeer.c b/src/dht/test_dht_twopeer.c deleted file mode 100644 index f0ac05b..0000000 --- a/src/dht/test_dht_twopeer.c +++ /dev/null @@ -1,494 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2009 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - 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 dht/test_dht_twopeer.c - * @brief base testcase for testing DHT service with - * two running peers - */ -#include "platform.h" -#include "gnunet_testing_lib.h" -#include "gnunet_core_service.h" -#include "gnunet_dht_service.h" - -/* DEFINES */ -#define MAX_GET_ATTEMPTS 10 - -#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5) - -#define DEFAULT_NUM_PEERS 2 - -/* Structs */ - -struct PeerGetContext -{ - struct GNUNET_PeerIdentity *peer; - - struct GNUNET_DHT_Handle *dht_handle; - - struct GNUNET_DHT_GetHandle *get_handle; - - unsigned int get_attempts; - - GNUNET_SCHEDULER_TaskIdentifier retry_task; -}; - -/* Globals */ -static char *test_directory; - -static struct PeerGetContext curr_get_ctx; - -static unsigned int expected_connections; - -static unsigned long long peers_left; - -static struct GNUNET_TESTING_PeerGroup *pg; - -static unsigned long long num_peers; - -static unsigned int total_gets; - -static unsigned int gets_succeeded; - -static unsigned int total_connections; - -static unsigned int failed_connections; - -static GNUNET_SCHEDULER_TaskIdentifier die_task; - -static int ok; - -static struct GNUNET_PeerIdentity peer1id; - -static struct GNUNET_PeerIdentity peer2id; - -static struct GNUNET_DHT_Handle *peer1dht; - -static struct GNUNET_DHT_Handle *peer2dht; - -/** - * Check whether peers successfully shut down. - */ -static void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - if (ok == 0) - ok = 2; - } -} - -static void -finish_testing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_assert (pg != NULL); - GNUNET_assert (peer1dht != NULL); - GNUNET_assert (peer2dht != NULL); - GNUNET_DHT_disconnect (peer1dht); - GNUNET_DHT_disconnect (peer2dht); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - pg = NULL; - ok = 0; -} - -static void -end_badly_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - if (peer1dht != NULL) - GNUNET_DHT_disconnect (peer1dht); - - if (peer2dht != NULL) - GNUNET_DHT_disconnect (peer2dht); - - if (pg != NULL) - { - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - pg = NULL; - } - - if (curr_get_ctx.retry_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (curr_get_ctx.retry_task); - curr_get_ctx.retry_task = GNUNET_SCHEDULER_NO_TASK; - } -} - - -static void -end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - const char *emsg = cls; - - FPRINTF (stderr, "Error: %s\n", emsg); - if (curr_get_ctx.retry_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (curr_get_ctx.retry_task); - curr_get_ctx.retry_task = GNUNET_SCHEDULER_NO_TASK; - } - if (curr_get_ctx.get_handle != NULL) - { - GNUNET_DHT_get_stop (curr_get_ctx.get_handle); - } - - GNUNET_SCHEDULER_add_now (&end_badly_cont, NULL); - ok = 1; -} - - -/* Forward declaration */ -static void -do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - -/** - * Iterator called on each result obtained for a DHT - * operation that expects a reply - * - * @param cls closure - * @param exp when will this value expire - * @param key key of the result - * @param type type of the result - * @param size number of bytes in data - * @param data pointer to the result data - */ -static void -get_result_iterator (void *cls, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_length, enum GNUNET_BLOCK_Type type, - size_t size, const void *data) -{ - struct PeerGetContext *get_context = cls; - - if (0 != - memcmp (&get_context->peer->hashPubKey, key, sizeof (GNUNET_HashCode))) - { - FPRINTF (stderr, "%s", "??\n"); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Key returned is not the same key as was searched for!\n"); - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "key mismatch in get response!\n"); - return; - } - if (get_context->retry_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (get_context->retry_task); - get_context->retry_task = GNUNET_SCHEDULER_NO_TASK; - } - - if (get_context->peer == &peer2id) - { - get_context->peer = &peer1id; - get_context->dht_handle = peer2dht; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received first correct GET request response!\n"); - GNUNET_DHT_get_stop (get_context->get_handle); - GNUNET_SCHEDULER_add_now (&do_get, get_context); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received second correct GET request response!\n"); - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_DHT_get_stop (get_context->get_handle); - die_task = GNUNET_SCHEDULER_add_now (&finish_testing, NULL); - } - -} - -static void -stop_retry_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - - -static void -get_stop_finished (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct PeerGetContext *get_context = cls; - - if (get_context->get_attempts >= MAX_GET_ATTEMPTS) - { - FPRINTF (stderr, "%s", "?\n"); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Too many attempts failed, ending test!\n", - get_context->get_attempts); - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "GET attempt failed, ending test!\n"); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Get attempt %u failed, retrying request!\n", - get_context->get_attempts); - FPRINTF (stderr, "%s", "."); - get_context->get_attempts++; - get_context->retry_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 60), - &stop_retry_get, get_context); - get_context->get_handle = - GNUNET_DHT_get_start (get_context->dht_handle, - GNUNET_BLOCK_TYPE_DHT_HELLO, - &get_context->peer->hashPubKey, 1, - GNUNET_DHT_RO_NONE, NULL, 0, &get_result_iterator, - get_context); -} - - -static void -stop_retry_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct PeerGetContext *get_context = cls; - - get_context->retry_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Get attempt %u failed, canceling request!\n", - get_context->get_attempts); - GNUNET_DHT_get_stop (get_context->get_handle); - get_context->get_handle = NULL; - GNUNET_SCHEDULER_add_now (&get_stop_finished, get_context); -} - - -static void -do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct PeerGetContext *get_context = cls; - - get_context->retry_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 10), - &stop_retry_get, get_context); - get_context->get_handle = - GNUNET_DHT_get_start (get_context->dht_handle, - GNUNET_BLOCK_TYPE_DHT_HELLO, - &get_context->peer->hashPubKey, 1, - GNUNET_DHT_RO_FIND_PEER, NULL, 0, - &get_result_iterator, get_context); -} - - -static void -topology_callback (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) -{ - if (emsg == NULL) - { - total_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "connected peer %s to peer %s, distance %u\n", - first_daemon->shortname, second_daemon->shortname, distance); - } - else - { - failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to connect peer %s to peer %s with error :\n%s\n", - first_daemon->shortname, second_daemon->shortname, emsg); - } - - if (total_connections == expected_connections) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Created %d total connections, which is our target number! Starting next phase of testing.\n", - total_connections); - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "Timeout trying to GET"); - - curr_get_ctx.dht_handle = peer1dht; - curr_get_ctx.peer = &peer2id; - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 2), &do_get, - &curr_get_ctx); - } - else if (total_connections + failed_connections == expected_connections) - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from topology_callback (too many failed connections)"); - } -} - - -static void -connect_topology (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - expected_connections = -1; - if ((pg != NULL) && (peers_left == 0)) - expected_connections = - GNUNET_TESTING_connect_topology (pg, GNUNET_TESTING_TOPOLOGY_CLIQUE, - GNUNET_TESTING_TOPOLOGY_OPTION_ALL, - 0.0, TIMEOUT, 12, NULL, NULL); - - GNUNET_SCHEDULER_cancel (die_task); - if (expected_connections == GNUNET_SYSERR) - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from connect topology (bad return)"); - else - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "from connect topology (timeout)"); -} - - -static void -peers_started_callback (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - if (emsg != NULL) - { - FPRINTF (stderr, "Failed to start daemon: `%s'\n", emsg); - return; - } - GNUNET_assert (id != NULL); - if (peers_left == num_peers) - { - memcpy (&peer1id, id, sizeof (struct GNUNET_PeerIdentity)); - peer1dht = GNUNET_DHT_connect (cfg, 100); - if (peer1dht == NULL) - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, "Failed to get dht handle!\n"); - } - } - else - { - memcpy (&peer2id, id, sizeof (struct GNUNET_PeerIdentity)); - peer2dht = GNUNET_DHT_connect (cfg, 100); - if (peer2dht == NULL) - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, "Failed to get dht handle!\n"); - } - } - - - peers_left--; - - if (peers_left == 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All %d daemons started, now connecting peers!\n", num_peers); - GNUNET_SCHEDULER_cancel (die_task); - /* Set up task in case topology creation doesn't finish - * within a reasonable amount of time */ - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "from peers_started_callback"); - - GNUNET_SCHEDULER_add_now (&connect_topology, NULL); - ok = 0; - } -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", - &test_directory)) - { - ok = 404; - return; - } - - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", - &num_peers)) - num_peers = DEFAULT_NUM_PEERS; - - peers_left = num_peers; - total_gets = num_peers; - gets_succeeded = 0; - /* Set up a task to end testing if peer start fails */ - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "didn't start all daemons in reasonable amount of time!!!"); - - pg = GNUNET_TESTING_daemons_start (cfg, num_peers, 10, num_peers, TIMEOUT, - NULL, NULL, &peers_started_callback, NULL, - &topology_callback, NULL, NULL); - -} - -static int -check () -{ - int ret; - - char *const argv[] = { "test-dht-twopeer", - "-c", - "test_dht_twopeer_data.conf", - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - ret = - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-dht-twopeer", "nohelp", options, &run, &ok); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "`test-dht-twopeer': Failed with error code %d\n", ret); - } - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-dht-twopeer", - "WARNING", - NULL); - ret = check (); - /** - * Need to remove base directory, subdirectories taken care - * of by the testing framework. - */ - if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to remove testing directory %s\n", test_directory); - } - return ret; -} - -/* end of test_dht_twopeer.c */ diff --git a/src/dht/test_dht_twopeer_data.conf b/src/dht/test_dht_twopeer_data.conf deleted file mode 100644 index 2889a41..0000000 --- a/src/dht/test_dht_twopeer_data.conf +++ /dev/null @@ -1,76 +0,0 @@ -[PATHS] -DEFAULTCONFIG = test_dht_twopeer_data.conf -SERVICEHOME = /tmp/test-dht-twopeer/ - -[resolver] -AUTOSTART = YES - -[dht] -DEBUG = NO -AUTOSTART = YES -#PREFIX = xterm -T dht -e gdb --args -PORT = 12100 -BINARY = gnunet-service-dht - -[block] -plugins = test dht dns - -[dhtcache] -QUOTA = 1 MB -DATABASE = sqlite - -[transport] -PLUGINS = tcp -DEBUG = NO -NEIGHBOUR_LIMIT = 50 -PORT = 12365 - -[ats] -WAN_QUOTA_IN = 1 GB -WAN_QUOTA_OUT = 1 GB - -[core] -HOSTNAME = localhost -PORT = 12092 - -[arm] -DEFAULTSERVICES = core dht -PORT = 12366 -DEBUG = NO - -[transport-tcp] -TIMEOUT = 300 s -PORT = 12368 -BINDTO = 127.0.0.1 - -[TESTING] -WEAKRANDOM = YES -NUM_PEERS = 2 -HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat - -[gnunetd] -HOSTKEY = $SERVICEHOME/.hostkey - -[nat] -DISABLEV6 = YES -ENABLE_UPNP = NO -BEHIND_NAT = NO -ALLOW_NAT = NO -INTERNAL_ADDRESS = 127.0.0.1 -EXTERNAL_ADDRESS = 127.0.0.1 -USE_LOCALADDR = YES - -[dns] -AUTOSTART = NO - -[mesh] -AUTOSTART = NO - -[nse] -AUTOSTART = NO - -[fs] -AUTOSTART = NO - -[namestore] -AUTOSTART = NO diff --git a/src/dht/test_dht_twopeer_get_put.c b/src/dht/test_dht_twopeer_get_put.c deleted file mode 100644 index 3271d04..0000000 --- a/src/dht/test_dht_twopeer_get_put.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2009 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - 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 dht/test_dht_twopeer_get_put.c - * @brief base testcase for testing DHT service with - * two running peers. - * - * This testcase starts peers using the GNUNET_TESTING_daemons_start - * function call. On peer start, connects to the peers DHT service - * by calling GNUNET_DHT_connected. Once notified about all peers - * being started (by the peers_started_callback function), calls - * GNUNET_TESTING_connect_topology, which connects the peers in a - * "straight line" topology. On notification that all peers have - * been properly connected, calls the do_get function which initiates - * a GNUNET_DHT_get from the *second* peer. Once the GNUNET_DHT_get - * function starts, runs the do_put function to insert data at the first peer. - * If the GET is successful, schedules finish_testing - * to stop the test and shut down peers. If GET is unsuccessful - * after GET_TIMEOUT seconds, prints an error message and shuts down - * the peers. - */ -#include "platform.h" -#include "gnunet_testing_lib.h" -#include "gnunet_core_service.h" -#include "gnunet_dht_service.h" -#include "block_dns.h" -#include "gnunet_signatures.h" - -/* DEFINES */ -#define VERBOSE GNUNET_NO - -/* Timeout for entire testcase */ -#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 40) - -/* Timeout for waiting for replies to get requests */ -#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30) - -/* If number of peers not in config file, use this number */ -#define DEFAULT_NUM_PEERS 2 - -#define DNS GNUNET_NO - -/* Globals */ - -/** - * Directory to store temp data in, defined in config file - */ -static char *test_directory; - -/** - * Variable used to store the number of connections we should wait for. - */ -static unsigned int expected_connections; - -/** - * Variable used to keep track of how many peers aren't yet started. - */ -static unsigned long long peers_left; - -/** - * Handle to the set of all peers run for this test. - */ -static struct GNUNET_TESTING_PeerGroup *pg; - -/** - * Global handle we will use for GET requests. - */ -struct GNUNET_DHT_GetHandle *global_get_handle; - - -/** - * Total number of peers to run, set based on config file. - */ -static unsigned long long num_peers; - -/** - * Global used to count how many connections we have currently - * been notified about (how many times has topology_callback been called - * with success?) - */ -static unsigned int total_connections; - -/** - * Global used to count how many failed connections we have - * been notified about (how many times has topology_callback - * been called with failure?) - */ -static unsigned int failed_connections; - -/* Task handle to use to schedule test failure */ -GNUNET_SCHEDULER_TaskIdentifier die_task; - -/* Global return value (0 for success, anything else for failure) */ -static int ok; - -#if DNS -struct GNUNET_DNS_Record data; -#endif - -/** - * Peer identity of the first peer started. - */ -static struct GNUNET_PeerIdentity peer1id; - -/** - * Peer identity of the second peer started. - */ -static struct GNUNET_PeerIdentity peer2id; - -/** - * Handle to the first peers DHT service (via the API) - */ -static struct GNUNET_DHT_Handle *peer1dht; - -/** - * Handle to the second peers DHT service (via the API) - */ -static struct GNUNET_DHT_Handle *peer2dht; - -static void -do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - -/** - * Check whether peers successfully shut down. - */ -void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - if (ok == 0) - ok = 2; - } -} - -/** - * Function scheduled to be run on the successful completion of this - * testcase. Specifically, called when our get request completes. - */ -static void -finish_testing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_assert (pg != NULL); - GNUNET_assert (peer1dht != NULL); - GNUNET_assert (peer2dht != NULL); - GNUNET_DHT_disconnect (peer1dht); - GNUNET_DHT_disconnect (peer2dht); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - ok = 0; -} - -/** - * Continuation for the GNUNET_DHT_get_stop call, so that we don't shut - * down the peers without freeing memory associated with GET request. - */ -static void -end_badly_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - if (peer1dht != NULL) - GNUNET_DHT_disconnect (peer1dht); - - if (peer2dht != NULL) - GNUNET_DHT_disconnect (peer2dht); - - if (pg != NULL) - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); -} - -/** - * Check if the get_handle is being used, if so stop the request. Either - * way, schedule the end_badly_cont function which actually shuts down the - * test. - */ -static void -end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failing test with error: `%s'!\n", - (char *) cls); - if (global_get_handle != NULL) - { - GNUNET_DHT_get_stop (global_get_handle); - global_get_handle = NULL; - } - GNUNET_SCHEDULER_add_now (&end_badly_cont, NULL); - ok = 1; -} - -/** - * Iterator called if the GET request initiated returns a response. - * - * @param cls closure - * @param exp when will this value expire - * @param key key of the result - * @param type type of the result - * @param size number of bytes in data - * @param data pointer to the result data - */ -void -get_result_iterator (void *cls, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_size, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_size, enum GNUNET_BLOCK_Type type, - size_t size, const void *result_data) -{ - GNUNET_HashCode original_key; /* Key data was stored data under */ - char original_data[4]; /* Made up data that was stored */ - - memset (&original_key, 42, sizeof (GNUNET_HashCode)); /* Set the key to what it was set to previously */ - memset (original_data, 43, sizeof (original_data)); - -#if DNS - if ((sizeof (original_data) != size) || - (0 != memcmp (&data.service_descriptor, key, sizeof (GNUNET_HashCode))) || - (0 != memcmp ((char *) &data, result_data, sizeof (original_data)))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Key or data is not the same as was inserted!\n"); - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_SCHEDULER_add_now (&end_badly, - "key or data mismatch in get response!\n"); - return; - } -#else - if ((sizeof (original_data) != size) || - (0 != memcmp (&original_key, key, sizeof (GNUNET_HashCode))) || - (0 != memcmp (original_data, result_data, sizeof (original_data)))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Key or data is not the same as was inserted!\n"); - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_SCHEDULER_add_now (&end_badly, - "key or data mismatch in get response!\n"); - return; - } -#endif - - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_DHT_get_stop (global_get_handle); - GNUNET_SCHEDULER_add_now (&finish_testing, NULL); -} - -/** - * Start the GET request for the same key/data that was inserted. - */ -static void -do_get (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_HashCode key; /* Key for data lookup */ - -#if DNS - memcpy (&key, &data.service_descriptor, sizeof (GNUNET_HashCode)); -#else - memset (&key, 42, sizeof (GNUNET_HashCode)); /* Set the key to the same thing as when data was inserted */ -#endif - global_get_handle = - GNUNET_DHT_get_start (peer2dht, -#if DNS - GNUNET_BLOCK_TYPE_DNS, -#else - GNUNET_BLOCK_TYPE_TEST, -#endif - &key, 1, GNUNET_DHT_RO_NONE, NULL, 0, - &get_result_iterator, NULL); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 10), &do_put, NULL); -} - -/** - * Called when the PUT request has been transmitted to the DHT service. - * Schedule the GET request for some time in the future. - */ -static void -put_finished (void *cls, int success) -{ - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &end_badly, - "waiting for get response (data not found)"); -} - - -#if !DNS -/** - * Set up some data, and call API PUT function - */ -static void -do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_HashCode key; /* Made up key to store data under */ - char data[4]; /* Made up data to store */ - - memset (&key, 42, sizeof (GNUNET_HashCode)); /* Set the key to something simple so we can issue GET request */ - memset (data, 43, sizeof (data)); - - /* Insert the data at the first peer */ - GNUNET_DHT_put (peer1dht, &key, 1, GNUNET_DHT_RO_NONE, GNUNET_BLOCK_TYPE_TEST, - sizeof (data), data, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_TIME_UNIT_FOREVER_REL, &put_finished, NULL); -} -#else - -/** - * Set up some data, and call API PUT function - */ -static void -do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - char *name = "philipptoelke.gnunet."; - size_t size = sizeof (struct GNUNET_DNS_Record); - - memset (&data, 0, size); - - data.purpose.size = htonl (size - sizeof (struct GNUNET_CRYPTO_RsaSignature)); - data.purpose.purpose = GNUNET_SIGNATURE_PURPOSE_DNS_RECORD; - - GNUNET_CRYPTO_hash (name, strlen (name) + 1, &data.service_descriptor); - - data.service_type = htonl (GNUNET_DNS_SERVICE_TYPE_UDP); - data.ports = htons (69); - - char *keyfile; - - GNUNET_asprintf (&keyfile, "/tmp/test_dns_data_key"); - struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key = - GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); - GNUNET_free (keyfile); - GNUNET_assert (my_private_key != NULL); - - GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &data.peer); - - data.expiration_time = - GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS); - - /* Sign the block */ - if (GNUNET_OK != - GNUNET_CRYPTO_rsa_sign (my_private_key, &data.purpose, &data.signature)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "could not sign DNS_Record\n"); - return; - } - GNUNET_CRYPTO_rsa_key_free (my_private_key); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting with key %08x\n", - *((unsigned int *) &data.service_descriptor)); - - GNUNET_DHT_put (peer1dht, &data.service_descriptor, DEFAULT_PUT_REPLICATION, - GNUNET_DHT_RO_NONE, GNUNET_BLOCK_TYPE_DNS, size, - (char *) &data, - GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS), - GNUNET_TIME_UNIT_MINUTES, &put_finished, NULL); -} -#endif - -/** - * This function is called whenever a connection attempt is finished between two of - * the started peers (started with GNUNET_TESTING_daemons_start). The total - * number of times this function is called should equal the number returned - * from the GNUNET_TESTING_connect_topology call. - * - * The emsg variable is NULL on success (peers connected), and non-NULL on - * failure (peers failed to connect). - */ -void -topology_callback (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) -{ - if (emsg == NULL) - { - total_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "connected peer %s to peer %s, distance %u\n", - first_daemon->shortname, second_daemon->shortname, distance); - } - else - { - failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to connect peer %s to peer %s with error :\n%s\n", - first_daemon->shortname, second_daemon->shortname, emsg); - } - - if (total_connections == expected_connections) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Created %d total connections, which is our target number! Starting next phase of testing.\n", - total_connections); - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, "from test gets"); - - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 2), &do_get, NULL); - } - else if (total_connections + failed_connections == expected_connections) - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from topology_callback (too many failed connections)"); - } -} - - -/** - * Callback which is called whenever a peer is started (as a result of the - * GNUNET_TESTING_daemons_start call. - * - * @param cls closure argument given to GNUNET_TESTING_daemons_start - * @param id the GNUNET_PeerIdentity of the started peer - * @param cfg the configuration for this specific peer (needed to connect - * to the DHT) - * @param d the handle to the daemon started - * @param emsg NULL if peer started, non-NULL on error - */ -static void -peers_started_callback (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to start daemon with error: `%s'\n", emsg); - return; - } - GNUNET_assert (id != NULL); - - /* This is the first peer started */ - if (peers_left == num_peers) - { - memcpy (&peer1id, id, sizeof (struct GNUNET_PeerIdentity)); /* Save the peer id */ - peer1dht = GNUNET_DHT_connect (cfg, 100); /* Connect to the first peers DHT service */ - if (peer1dht == NULL) /* If DHT connect failed */ - { - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_SCHEDULER_add_now (&end_badly, "Failed to get dht handle!\n"); - } - } - else /* This is the second peer started */ - { - memcpy (&peer2id, id, sizeof (struct GNUNET_PeerIdentity)); /* Same as for first peer... */ - peer2dht = GNUNET_DHT_connect (cfg, 100); - if (peer2dht == NULL) - { - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_SCHEDULER_add_now (&end_badly, "Failed to get dht handle!\n"); - } - } - - /* Decrement number of peers left to start */ - peers_left--; - - if (peers_left == 0) /* Indicates all peers started */ - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All %d daemons started, now connecting peers!\n", num_peers); - expected_connections = -1; - if ((pg != NULL)) /* Sanity check */ - { - /* Connect peers in a "straight line" topology, return the number of expected connections */ - expected_connections = - GNUNET_TESTING_connect_topology (pg, GNUNET_TESTING_TOPOLOGY_LINE, - GNUNET_TESTING_TOPOLOGY_OPTION_ALL, - 0.0, TIMEOUT, 12, NULL, NULL); - } - - /* Cancel current timeout fail task */ - GNUNET_SCHEDULER_cancel (die_task); - if (expected_connections == GNUNET_SYSERR) /* Some error happened */ - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from connect topology (bad return)"); - - /* Schedule timeout on failure task */ - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "from connect topology (timeout)"); - ok = 0; - } -} - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - - /* Get path from configuration file */ - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", - &test_directory)) - { - ok = 404; - return; - } - - /* Get number of peers to start from configuration (should be two) */ - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", - &num_peers)) - num_peers = DEFAULT_NUM_PEERS; - - /* Set peers_left so we know when all peers started */ - peers_left = num_peers; - - /* Set up a task to end testing if peer start fails */ - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "didn't start all daemons in reasonable amount of time!!!"); - - /* Start num_peers peers, call peers_started_callback on peer start, topology_callback on peer connect */ - /* Read the API documentation for other parameters! */ - pg = GNUNET_TESTING_daemons_start (cfg, num_peers, 2, 2, TIMEOUT, NULL, NULL, - &peers_started_callback, NULL, - &topology_callback, NULL, NULL); - -} - -static int -check () -{ - int ret; - - /* Arguments for GNUNET_PROGRAM_run */ - char *const argv[] = { "test-dht-twopeer-get-put", /* Name to give running binary */ - "-c", - "test_dht_twopeer_data.conf", /* Config file to use */ - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - /* Run the run function as a new program */ - ret = - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-dht-twopeer-get-put", "nohelp", options, &run, - &ok); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "`test-dht-twopeer': Failed with error code %d\n", ret); - } - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-dht-twopeer", - "WARNING", - NULL); - ret = check (); - /** - * Need to remove base directory, subdirectories taken care - * of by the testing framework. - */ - if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to remove testing directory %s\n", test_directory); - } - return ret; -} - -/* end of test_dht_twopeer_get_put.c */ diff --git a/src/dht/test_dht_twopeer_path_tracking.c b/src/dht/test_dht_twopeer_path_tracking.c deleted file mode 100644 index 6ecf6a3..0000000 --- a/src/dht/test_dht_twopeer_path_tracking.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2009 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - 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 dht/test_dht_twopeer_path_tracking.c - * @brief testcase for testing DHT service with - * two running peers, logging the path of the dht requests. - */ -#include "platform.h" -#include "gnunet_testing_lib.h" -#include "gnunet_core_service.h" -#include "gnunet_dht_service.h" - -/* DEFINES */ -#define VERBOSE GNUNET_NO - -/* Timeout for entire testcase */ -#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5) - -/* Timeout for waiting for replies to get requests */ -#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30) - -/* If number of peers not in config file, use this number */ -#define DEFAULT_NUM_PEERS 2 - -/* Globals */ - -/** - * Directory to store temp data in, defined in config file - */ -static char *test_directory; - -/** - * Variable used to store the number of connections we should wait for. - */ -static unsigned int expected_connections; - -/** - * Variable used to keep track of how many peers aren't yet started. - */ -static unsigned long long peers_left; - -/** - * Handle to the set of all peers run for this test. - */ -static struct GNUNET_TESTING_PeerGroup *pg; - -/** - * Global handle we will use for GET requests. - */ -struct GNUNET_DHT_GetHandle *global_get_handle; - - -/** - * Total number of peers to run, set based on config file. - */ -static unsigned long long num_peers; - -/** - * Global used to count how many connections we have currently - * been notified about (how many times has topology_callback been called - * with success?) - */ -static unsigned int total_connections; - -/** - * Global used to count how many failed connections we have - * been notified about (how many times has topology_callback - * been called with failure?) - */ -static unsigned int failed_connections; - -/** - * Task handle to use to schedule test failure - */ -GNUNET_SCHEDULER_TaskIdentifier die_task; - -/** - * Global return value (0 for success, anything else for failure) - */ -static int ok; - -/** - * Peer identity of the first peer started. - */ -static struct GNUNET_PeerIdentity peer1id; - -/** - * Peer identity of the second peer started. - */ -static struct GNUNET_PeerIdentity peer2id; - -/** - * Handle to the first peers DHT service (via the API) - */ -static struct GNUNET_DHT_Handle *peer1dht; - -/** - * Handle to the second peers DHT service (via the API) - */ -static struct GNUNET_DHT_Handle *peer2dht; - -/** - * Check whether peers successfully shut down. - */ -void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - if (ok == 0) - ok = 2; - } -} - -/** - * Function scheduled to be run on the successful completion of this - * testcase. Specifically, called when our get request completes. - */ -static void -finish_testing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_assert (pg != NULL); - GNUNET_assert (peer1dht != NULL); - GNUNET_assert (peer2dht != NULL); - GNUNET_DHT_disconnect (peer1dht); - GNUNET_DHT_disconnect (peer2dht); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - ok = 0; -} - -/** - * Continuation for the GNUNET_DHT_get_stop call, so that we don't shut - * down the peers without freeing memory associated with GET request. - */ -static void -end_badly_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - if (peer1dht != NULL) - GNUNET_DHT_disconnect (peer1dht); - - if (peer2dht != NULL) - GNUNET_DHT_disconnect (peer2dht); - - if (pg != NULL) - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); -} - -/** - * Check if the get_handle is being used, if so stop the request. Either - * way, schedule the end_badly_cont function which actually shuts down the - * test. - */ -static void -end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failing test with error: `%s'!\n", - (char *) cls); - if (global_get_handle != NULL) - { - GNUNET_DHT_get_stop (global_get_handle); - global_get_handle = NULL; - } - GNUNET_SCHEDULER_add_now (&end_badly_cont, NULL); - ok = 1; -} - -/** - * Iterator called if the GET request initiated returns a response. - * - * @param cls closure - * @param exp when will this value expire - * @param key key of the result - * @param type type of the result - * @param size number of bytes in data - * @param data pointer to the result data - */ -static void -get_result_iterator (void *cls, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_length, enum GNUNET_BLOCK_Type type, - size_t size, const void *data) -{ - GNUNET_HashCode original_key; /* Key data was stored data under */ - char original_data[4]; /* Made up data that was stored */ - - memset (&original_key, 42, sizeof (GNUNET_HashCode)); /* Set the key to what it was set to previously */ - memset (original_data, 43, sizeof (original_data)); -#if VERBOSE - unsigned int i; -#endif - - if ((0 != memcmp (&original_key, key, sizeof (GNUNET_HashCode))) || - (0 != memcmp (original_data, data, sizeof (original_data)))) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Key or data is not the same as was inserted!\n"); - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_SCHEDULER_add_now (&end_badly, - "key or data mismatch in get response!\n"); - return; - } - -#if VERBOSE - if (put_path != NULL) - { - FPRINTF (stderr, "%s", "PUT Path: "); - for (i = 0; i < put_path_length; i++) - FPRINTF (stderr, "%s%s", i == 0 ? "" : "->", GNUNET_i2s (&put_path[i])); - FPRINTF (stderr, "%s", "\n"); - } - if (get_path != NULL) - { - FPRINTF (stderr, "%s", "GET Path: "); - for (i = 0; i < get_path_length; i++) - FPRINTF (stderr, "%s%s", i == 0 ? "" : "->", GNUNET_i2s (&get_path[i])); - FPRINTF (stderr, "%s", "\n"); - } -#endif - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received correct GET response!\n"); - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_DHT_get_stop (global_get_handle); - GNUNET_SCHEDULER_add_now (&finish_testing, NULL); -} - - -/** - * Called when the PUT request has been transmitted to the DHT service. - * Schedule the GET request for some time in the future. - */ -static void -put_finished (void *cls, int success) -{ - GNUNET_HashCode key; /* Key for data lookup */ - - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &end_badly, - "waiting for get response (data not found)"); - memset (&key, 42, sizeof (GNUNET_HashCode)); /* Set the key to the same thing as when data was inserted */ - global_get_handle = - GNUNET_DHT_get_start (peer2dht, - GNUNET_BLOCK_TYPE_TEST, &key, 1, - GNUNET_DHT_RO_RECORD_ROUTE, NULL, 0, - &get_result_iterator, NULL); -} - -/** - * Set up some data, and call API PUT function - */ -static void -do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_HashCode key; /* Made up key to store data under */ - char data[4]; /* Made up data to store */ - - memset (&key, 42, sizeof (GNUNET_HashCode)); /* Set the key to something simple so we can issue GET request */ - memset (data, 43, sizeof (data)); - - /* Insert the data at the first peer */ - GNUNET_DHT_put (peer1dht, &key, 1, GNUNET_DHT_RO_RECORD_ROUTE, - GNUNET_BLOCK_TYPE_TEST, sizeof (data), data, - GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_TIME_UNIT_FOREVER_REL, - &put_finished, NULL); -} - -/** - * This function is called whenever a connection attempt is finished between two of - * the started peers (started with GNUNET_TESTING_daemons_start). The total - * number of times this function is called should equal the number returned - * from the GNUNET_TESTING_connect_topology call. - * - * The emsg variable is NULL on success (peers connected), and non-NULL on - * failure (peers failed to connect). - */ -static void -topology_callback (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) -{ - if (emsg == NULL) - { - total_connections++; -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "connected peer %s to peer %s, distance %u\n", - first_daemon->shortname, second_daemon->shortname, distance); -#endif - } -#if VERBOSE - else - { - failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to connect peer %s to peer %s with error :\n%s\n", - first_daemon->shortname, second_daemon->shortname, emsg); - } -#endif - - if (total_connections == expected_connections) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Created %d total connections, which is our target number! Starting next phase of testing.\n", - total_connections); -#endif - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, "from test gets"); - - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 2), &do_put, NULL); - } - else if (total_connections + failed_connections == expected_connections) - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from topology_callback (too many failed connections)"); - } -} - - -/** - * Callback which is called whenever a peer is started (as a result of the - * GNUNET_TESTING_daemons_start call. - * - * @param cls closure argument given to GNUNET_TESTING_daemons_start - * @param id the GNUNET_PeerIdentity of the started peer - * @param cfg the configuration for this specific peer (needed to connect - * to the DHT) - * @param d the handle to the daemon started - * @param emsg NULL if peer started, non-NULL on error - */ -static void -peers_started_callback (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to start daemon with error: `%s'\n", emsg); - return; - } - GNUNET_assert (id != NULL); - - /* This is the first peer started */ - if (peers_left == num_peers) - { - memcpy (&peer1id, id, sizeof (struct GNUNET_PeerIdentity)); /* Save the peer id */ - peer1dht = GNUNET_DHT_connect (cfg, 100); /* Connect to the first peers DHT service */ - if (peer1dht == NULL) /* If DHT connect failed */ - { - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_SCHEDULER_add_now (&end_badly, "Failed to get dht handle!\n"); - } - } - else /* This is the second peer started */ - { - memcpy (&peer2id, id, sizeof (struct GNUNET_PeerIdentity)); /* Same as for first peer... */ - peer2dht = GNUNET_DHT_connect (cfg, 100); - if (peer2dht == NULL) - { - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_SCHEDULER_add_now (&end_badly, "Failed to get dht handle!\n"); - } - } - - /* Decrement number of peers left to start */ - peers_left--; - - if (peers_left == 0) /* Indicates all peers started */ - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All %d daemons started, now connecting peers!\n", num_peers); -#endif - expected_connections = -1; - if ((pg != NULL)) /* Sanity check */ - { - /* Connect peers in a "straight line" topology, return the number of expected connections */ - expected_connections = - GNUNET_TESTING_connect_topology (pg, GNUNET_TESTING_TOPOLOGY_LINE, - GNUNET_TESTING_TOPOLOGY_OPTION_ALL, - 0.0, TIMEOUT, 2, NULL, NULL); - } - - /* Cancel current timeout fail task */ - GNUNET_SCHEDULER_cancel (die_task); - if (expected_connections == GNUNET_SYSERR) /* Some error happened */ - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from connect topology (bad return)"); - - /* Schedule timeout on failure task */ - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "from connect topology (timeout)"); - ok = 0; - } -} - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - - /* Get path from configuration file */ - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", - &test_directory)) - { - ok = 404; - return; - } - - /* Get number of peers to start from configuration (should be two) */ - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", - &num_peers)) - num_peers = DEFAULT_NUM_PEERS; - - /* Set peers_left so we know when all peers started */ - peers_left = num_peers; - - /* Set up a task to end testing if peer start fails */ - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "didn't start all daemons in reasonable amount of time!!!"); - - /* Start num_peers peers, call peers_started_callback on peer start, topology_callback on peer connect */ - /* Read the API documentation for other parameters! */ - pg = GNUNET_TESTING_daemons_start (cfg, peers_left, /* Total number of peers */ - peers_left, /* Number of outstanding connections */ - peers_left, /* Number of parallel ssh connections, or peers being started at once */ - TIMEOUT, NULL, NULL, - &peers_started_callback, NULL, - &topology_callback, NULL, NULL); - -} - -static int -check () -{ - int ret; - - /* Arguments for GNUNET_PROGRAM_run */ - char *const argv[] = { "test-dht-twopeer-put-get", /* Name to give running binary */ - "-c", - "test_dht_twopeer_data.conf", /* Config file to use */ -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - /* Run the run function as a new program */ - ret = - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-dht-twopeer-put-get", "nohelp", options, &run, - &ok); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "`test-dht-twopeer': Failed with error code %d\n", ret); - } - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-dht-twopeer", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); - /** - * Need to remove base directory, subdirectories taken care - * of by the testing framework. - */ - if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to remove testing directory %s\n", test_directory); - } - return ret; -} - -/* end of test_dht_twopeer_put_get.c */ diff --git a/src/dht/test_dht_twopeer_put_get.c b/src/dht/test_dht_twopeer_put_get.c deleted file mode 100644 index 44150e3..0000000 --- a/src/dht/test_dht_twopeer_put_get.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2009 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - 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 dht/test_dht_twopeer_put_get.c - * @brief base testcase for testing DHT service with - * two running peers. - * - * This testcase starts peers using the GNUNET_TESTING_daemons_start - * function call. On peer start, connects to the peers DHT service - * by calling GNUNET_DHT_connected. Once notified about all peers - * being started (by the peers_started_callback function), calls - * GNUNET_TESTING_connect_topology, which connects the peers in a - * "straight line" topology. On notification that all peers have - * been properly connected, runs the do_put function to insert data - * at the first peer. Once the GNUNET_DHT_put function completes, - * calls the do_get function which initiates a GNUNET_DHT_get from - * the *second* peer. If the GET is successful, schedules finish_testing - * to stop the test and shut down peers. If GET is unsuccessful - * after GET_TIMEOUT seconds, prints an error message and shuts down - * the peers. - */ -#include "platform.h" -#include "gnunet_testing_lib.h" -#include "gnunet_core_service.h" -#include "gnunet_dht_service.h" -#include "block_dns.h" -#include "gnunet_signatures.h" - -/* DEFINES */ -#define VERBOSE GNUNET_NO - -/* Timeout for entire testcase */ -#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5) - -/* Timeout for waiting for replies to get requests */ -#define GET_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30) - -/* If number of peers not in config file, use this number */ -#define DEFAULT_NUM_PEERS 2 - -/* Globals */ - -/** - * Directory to store temp data in, defined in config file - */ -static char *test_directory; - -/** - * Variable used to store the number of connections we should wait for. - */ -static unsigned int expected_connections; - -/** - * Variable used to keep track of how many peers aren't yet started. - */ -static unsigned long long peers_left; - -/** - * Handle to the set of all peers run for this test. - */ -static struct GNUNET_TESTING_PeerGroup *pg; - -/** - * Global handle we will use for GET requests. - */ -struct GNUNET_DHT_GetHandle *global_get_handle; - - -/** - * Total number of peers to run, set based on config file. - */ -static unsigned long long num_peers; - -/** - * Global used to count how many connections we have currently - * been notified about (how many times has topology_callback been called - * with success?) - */ -static unsigned int total_connections; - -/** - * Global used to count how many failed connections we have - * been notified about (how many times has topology_callback - * been called with failure?) - */ -static unsigned int failed_connections; - -/* Task handle to use to schedule test failure */ -static GNUNET_SCHEDULER_TaskIdentifier die_task; - -/* Global return value (0 for success, anything else for failure) */ -static int ok; - -/** - * Peer identity of the first peer started. - */ -static struct GNUNET_PeerIdentity peer1id; - -/** - * Peer identity of the second peer started. - */ -static struct GNUNET_PeerIdentity peer2id; - -/** - * Handle to the first peers DHT service (via the API) - */ -static struct GNUNET_DHT_Handle *peer1dht; - -/** - * Handle to the second peers DHT service (via the API) - */ -static struct GNUNET_DHT_Handle *peer2dht; - -/** - * Handle for our PUT operation. - */ -static struct GNUNET_DHT_PutHandle *put_op; - - -/** - * Check whether peers successfully shut down. - */ -static void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - if (ok == 0) - ok = 2; - } -} - -/** - * Function scheduled to be run on the successful completion of this - * testcase. Specifically, called when our get request completes. - */ -static void -finish_testing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_assert (pg != NULL); - GNUNET_assert (peer1dht != NULL); - GNUNET_assert (peer2dht != NULL); - GNUNET_DHT_disconnect (peer1dht); - GNUNET_DHT_disconnect (peer2dht); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - ok = 0; -} - -/** - * Continuation for the GNUNET_DHT_get_stop call, so that we don't shut - * down the peers without freeing memory associated with GET request. - */ -static void -end_badly_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - if (NULL != put_op) - { - GNUNET_DHT_put_cancel (put_op); - put_op = NULL; - } - if (peer1dht != NULL) - GNUNET_DHT_disconnect (peer1dht); - - if (peer2dht != NULL) - GNUNET_DHT_disconnect (peer2dht); - - if (pg != NULL) - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); -} - - -/** - * Check if the get_handle is being used, if so stop the request. Either - * way, schedule the end_badly_cont function which actually shuts down the - * test. - */ -static void -end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failing test with error: `%s'!\n", - (char *) cls); - if (global_get_handle != NULL) - { - GNUNET_DHT_get_stop (global_get_handle); - global_get_handle = NULL; - } - GNUNET_SCHEDULER_add_now (&end_badly_cont, NULL); - ok = 1; -} - -/** - * Iterator called if the GET request initiated returns a response. - * - * @param cls closure - * @param exp when will this value expire - * @param key key of the result - * @param type type of the result - * @param size number of bytes in data - * @param data pointer to the result data - */ -static void -get_result_iterator (void *cls, struct GNUNET_TIME_Absolute exp, - const GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_size, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_size, enum GNUNET_BLOCK_Type type, - size_t size, const void *result_data) -{ - GNUNET_HashCode original_key; /* Key data was stored data under */ - char original_data[4]; /* Made up data that was stored */ - - memset (&original_key, 42, sizeof (GNUNET_HashCode)); /* Set the key to what it was set to previously */ - memset (original_data, 43, sizeof (original_data)); - - if ((sizeof (original_data) != size) || - (0 != memcmp (&original_key, key, sizeof (GNUNET_HashCode))) || - (0 != memcmp (original_data, result_data, sizeof (original_data)))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Key or data is not the same as was inserted!\n"); - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_SCHEDULER_add_now (&end_badly, - "key or data mismatch in get response!\n"); - return; - } - - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_DHT_get_stop (global_get_handle); - global_get_handle = NULL; - GNUNET_SCHEDULER_add_now (&finish_testing, NULL); -} - - -/** - * Called when the PUT request has been transmitted to the DHT service. - * Schedule the GET request for some time in the future. - */ -static void -put_finished (void *cls, int success) -{ - GNUNET_HashCode key; /* Key for data lookup */ - - put_op = NULL; - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &end_badly, - "waiting for get response (data not found)"); - - memset (&key, 42, sizeof (GNUNET_HashCode)); /* Set the key to the same thing as when data was inserted */ - global_get_handle = - GNUNET_DHT_get_start (peer2dht, - GNUNET_BLOCK_TYPE_TEST, &key, 1, GNUNET_DHT_RO_NONE, - NULL, 0, &get_result_iterator, NULL); -} - - -/** - * Set up some data, and call API PUT function - */ -static void -do_put (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_HashCode key; /* Made up key to store data under */ - char data[4]; /* Made up data to store */ - - memset (&key, 42, sizeof (GNUNET_HashCode)); /* Set the key to something simple so we can issue GET request */ - memset (data, 43, sizeof (data)); - - /* Insert the data at the first peer */ - put_op = GNUNET_DHT_put (peer1dht, &key, 1, GNUNET_DHT_RO_NONE, GNUNET_BLOCK_TYPE_TEST, - sizeof (data), data, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_TIME_UNIT_FOREVER_REL, &put_finished, NULL); -} - - -/** - * This function is called whenever a connection attempt is finished between two of - * the started peers (started with GNUNET_TESTING_daemons_start). The total - * number of times this function is called should equal the number returned - * from the GNUNET_TESTING_connect_topology call. - * - * The emsg variable is NULL on success (peers connected), and non-NULL on - * failure (peers failed to connect). - */ -static void -topology_callback (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) -{ - if (emsg == NULL) - { - total_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "connected peer %s to peer %s, distance %u\n", - first_daemon->shortname, second_daemon->shortname, distance); - } - else - { - failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to connect peer %s to peer %s with error :\n%s\n", - first_daemon->shortname, second_daemon->shortname, emsg); - } - - if (total_connections == expected_connections) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Created %d total connections, which is our target number! Starting next phase of testing.\n", - total_connections); - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, "from test gets"); - - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &do_put, NULL); - } - else if (total_connections + failed_connections == expected_connections) - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from topology_callback (too many failed connections)"); - } -} - - -/** - * Callback which is called whenever a peer is started (as a result of the - * GNUNET_TESTING_daemons_start call. - * - * @param cls closure argument given to GNUNET_TESTING_daemons_start - * @param id the GNUNET_PeerIdentity of the started peer - * @param cfg the configuration for this specific peer (needed to connect - * to the DHT) - * @param d the handle to the daemon started - * @param emsg NULL if peer started, non-NULL on error - */ -static void -peers_started_callback (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to start daemon with error: `%s'\n", emsg); - return; - } - GNUNET_assert (id != NULL); - - /* This is the first peer started */ - if (peers_left == num_peers) - { - memcpy (&peer1id, id, sizeof (struct GNUNET_PeerIdentity)); /* Save the peer id */ - peer1dht = GNUNET_DHT_connect (cfg, 100); /* Connect to the first peers DHT service */ - if (peer1dht == NULL) /* If DHT connect failed */ - { - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_SCHEDULER_add_now (&end_badly, "Failed to get dht handle!\n"); - } - } - else /* This is the second peer started */ - { - memcpy (&peer2id, id, sizeof (struct GNUNET_PeerIdentity)); /* Same as for first peer... */ - peer2dht = GNUNET_DHT_connect (cfg, 100); - if (peer2dht == NULL) - { - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_SCHEDULER_add_now (&end_badly, "Failed to get dht handle!\n"); - } - } - - /* Decrement number of peers left to start */ - peers_left--; - - if (peers_left == 0) /* Indicates all peers started */ - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All %d daemons started, now connecting peers!\n", num_peers); - expected_connections = -1; - if ((pg != NULL)) /* Sanity check */ - { - /* Connect peers in a "straight line" topology, return the number of expected connections */ - expected_connections = - GNUNET_TESTING_connect_topology (pg, GNUNET_TESTING_TOPOLOGY_LINE, - GNUNET_TESTING_TOPOLOGY_OPTION_ALL, - 0.0, TIMEOUT, 12, NULL, NULL); - } - - /* Cancel current timeout fail task */ - GNUNET_SCHEDULER_cancel (die_task); - if (expected_connections == GNUNET_SYSERR) /* Some error happened */ - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from connect topology (bad return)"); - - /* Schedule timeout on failure task */ - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "from connect topology (timeout)"); - ok = 0; - } -} - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - - /* Get path from configuration file */ - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", - &test_directory)) - { - ok = 404; - return; - } - - /* Get number of peers to start from configuration (should be two) */ - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", - &num_peers)) - num_peers = DEFAULT_NUM_PEERS; - - /* Set peers_left so we know when all peers started */ - peers_left = num_peers; - - /* Set up a task to end testing if peer start fails */ - die_task = - GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, - "didn't start all daemons in reasonable amount of time!!!"); - - /* Start num_peers peers, call peers_started_callback on peer start, topology_callback on peer connect */ - /* Read the API documentation for other parameters! */ - pg = GNUNET_TESTING_daemons_start (cfg, num_peers, 2, 2, TIMEOUT, NULL, NULL, - &peers_started_callback, NULL, - &topology_callback, NULL, NULL); - -} - -static int -check () -{ - int ret; - - /* Arguments for GNUNET_PROGRAM_run */ - char *const argv[] = { "test-dht-twopeer-put-get", /* Name to give running binary */ - "-c", - "test_dht_twopeer_data.conf", /* Config file to use */ - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - /* Run the run function as a new program */ - ret = - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-dht-twopeer-put-get", "nohelp", options, &run, - &ok); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "`test-dht-twopeer': Failed with error code %d\n", ret); - } - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-dht-twopeer", - "WARNING", - NULL); - ret = check (); - /** - * Need to remove base directory, subdirectories taken care - * of by the testing framework. - */ - if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to remove testing directory %s\n", test_directory); - } - return ret; -} - -/* end of test_dht_twopeer_put_get.c */ |