diff options
Diffstat (limited to 'src/testing')
44 files changed, 1638 insertions, 16313 deletions
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am index 572c033..2b0cb98 100644 --- a/src/testing/Makefile.am +++ b/src/testing/Makefile.am @@ -14,97 +14,32 @@ pkgcfgdir= $(pkgdatadir)/config.d/ dist_pkgcfg_DATA = \ testing.conf -if HAVE_EXPENSIVE_TESTS - EXPENSIVE_TESTS = \ - test_testing_topology_stability \ - test_testing_topology_clique_random \ - test_testing_topology_clique_minimum \ - test_testing_topology_clique_dfs \ - test_testing_topology_churn \ - test_testing_topology_line \ - test_testing_topology_blacklist \ - test_testing_group_remote \ - test_testing_topology_ring \ - test_testing_topology_2d_torus \ - test_testing_topology_small_world_ring \ - test_testing_topology_small_world_torus \ - test_testing_topology_erdos_renyi \ - test_testing_topology_internat \ - test_testing_topology_scale_free -endif - lib_LTLIBRARIES = \ - libgnunettesting.la \ - libgnunettesting_new.la + libgnunettesting.la libgnunettesting_la_SOURCES = \ - helper.c \ - testing.c \ - testing_group.c \ - testing_peergroup.c -libgnunettesting_la_LIBADD = $(XLIB) \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - -lm \ - $(top_builddir)/src/util/libgnunetutil.la + testing.c +libgnunettesting_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunettesting_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 0:1:0 - - -libgnunettesting_new_la_SOURCES = \ - testing_new.c -libgnunettesting_new_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la -libgnunettesting_new_la_LDFLAGS = \ - $(GN_LIB_LDFLAGS) \ - -version-info 0:1:0 - + -version-info 2:0:1 bin_PROGRAMS = \ + gnunet-testing-run-service \ gnunet-testing -check_PROGRAMS = \ - test_testing \ - test_testing_connect \ - test_testing_reconnect \ - test_testing_group \ - test_testing_peergroup \ - test_testing_topology_stability \ - test_testing_topology_clique \ - test_testing_topology_clique_random \ - test_testing_topology_clique_minimum \ - test_testing_topology_clique_dfs \ - test_testing_topology_churn \ - test_testing_topology_line \ - test_testing_topology_blacklist \ - test_testing_group_remote \ - test_testing_2dtorus \ - test_testing_topology_ring \ - test_testing_topology_2d_torus \ - test_testing_topology_small_world_ring \ - test_testing_topology_small_world_torus \ - test_testing_topology_erdos_renyi \ - test_testing_topology_internat \ - test_testing_topology_none \ - test_testing_topology_scale_free \ - test_testing_new_portreservation \ - test_testing_new_peerstartup \ - test_testing_new_servicestartup -if ENABLE_TEST_RUN -TESTS = \ - test_testing \ - test_testing_connect \ - test_testing_reconnect \ - test_testing_group \ - test_testing_peergroup \ - test_testing_new_portreservation \ - test_testing_new_peerstartup \ - test_testing_new_servicestartup -endif +gnunet_testing_run_service_SOURCES = \ + gnunet-testing-run-service.c + +gnunet_testing_run_service_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(GN_LIBINTL) +gnunet_testing_run_service_DEPENDENCIES = \ + libgnunettesting.la gnunet_testing_SOURCES = \ gnunet-testing.c @@ -116,197 +51,36 @@ gnunet_testing_DEPENDENCIES = \ libgnunettesting.la -test_testing_SOURCES = \ - test_testing.c -test_testing_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_connect_SOURCES = \ - test_testing_connect.c -test_testing_connect_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_reconnect_SOURCES = \ - test_testing_reconnect.c -test_testing_reconnect_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_group_SOURCES = \ - test_testing_group.c -test_testing_group_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_peergroup_SOURCES = \ - test_testing_peergroup.c -test_testing_peergroup_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_clique_SOURCES = \ - test_testing_topology.c -test_testing_topology_clique_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_stability_SOURCES = \ - test_testing_topology.c -test_testing_topology_stability_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_blacklist_SOURCES = \ - test_testing_topology_blacklist.c -test_testing_topology_blacklist_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_churn_SOURCES = \ - test_testing_topology_churn.c -test_testing_topology_churn_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_clique_random_SOURCES = \ - test_testing_topology.c -test_testing_topology_clique_random_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_clique_minimum_SOURCES = \ - test_testing_topology.c -test_testing_topology_clique_minimum_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_clique_dfs_SOURCES = \ - test_testing_topology.c -test_testing_topology_clique_dfs_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_line_SOURCES = \ - test_testing_topology.c -test_testing_topology_line_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - - -test_testing_group_remote_SOURCES = \ - test_testing_group_remote.c -test_testing_group_remote_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_2dtorus_SOURCES = \ - test_testing_2dtorus.c -test_testing_2dtorus_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_ring_SOURCES = \ - test_testing_topology.c -test_testing_topology_ring_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_2d_torus_SOURCES = \ - test_testing_topology.c -test_testing_topology_2d_torus_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_small_world_ring_SOURCES = \ - test_testing_topology.c -test_testing_topology_small_world_ring_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_small_world_torus_SOURCES = \ - test_testing_topology.c -test_testing_topology_small_world_torus_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la +check_PROGRAMS = \ + test_testing_portreservation \ + test_testing_peerstartup \ + test_testing_servicestartup -test_testing_topology_internat_SOURCES = \ - test_testing_topology.c -test_testing_topology_internat_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la +if ENABLE_TEST_RUN +TESTS = \ + test_testing_portreservation \ + test_testing_peerstartup \ + test_testing_servicestartup +endif -test_testing_topology_erdos_renyi_SOURCES = \ - test_testing_topology.c -test_testing_topology_erdos_renyi_LDADD = \ +test_testing_portreservation_SOURCES = \ + test_testing_portreservation.c +test_testing_portreservation_LDADD = \ $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la -test_testing_topology_scale_free_SOURCES = \ - test_testing_topology.c -test_testing_topology_scale_free_LDADD = \ +test_testing_peerstartup_SOURCES = \ + test_testing_peerstartup.c +test_testing_peerstartup_LDADD = \ $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la -test_testing_topology_none_SOURCES = \ - test_testing_topology.c -test_testing_topology_none_LDADD = \ +test_testing_servicestartup_SOURCES = \ + test_testing_servicestartup.c +test_testing_servicestartup_LDADD = \ $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_new_portreservation_SOURCES = \ - test_testing_new_portreservation.c -test_testing_new_portreservation_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting_new.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_new_peerstartup_SOURCES = \ - test_testing_new_peerstartup.c -test_testing_new_peerstartup_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting_new.la \ $(top_builddir)/src/util/libgnunetutil.la -test_testing_new_servicestartup_SOURCES = \ - test_testing_new_servicestartup.c -test_testing_new_servicestartup_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting_new.la \ - $(top_builddir)/src/util/libgnunetutil.la EXTRA_DIST = \ - test_testing_defaults.conf \ - test_testing_data.conf \ - test_testing_connect_peer1.conf \ - test_testing_connect_peer2.conf \ - test_testing_2dtorus.conf \ - test_testing_data_topology_clique.conf \ - test_testing_data_topology_clique_random.conf \ - test_testing_data_topology_clique_minimum.conf \ - test_testing_data_topology_clique_dfs.conf \ - test_testing_data_topology_ring.conf \ - test_testing_data_topology_2d_torus.conf \ - test_testing_data_topology_small_world_ring.conf \ - test_testing_data_topology_small_world_torus.conf \ - test_testing_data_topology_erdos_renyi.conf \ - test_testing_data_topology_internat.conf \ - test_testing_data_topology_scale_free.conf \ - test_testing_data_topology_blacklist.conf \ - test_testing_data_topology_churn.conf \ - test_testing_data_topology_none.conf \ - test_testing_data_remote.conf \ - test_testing_data_topology_stability.conf \ - test_testing_peergroup_data.conf + test_testing_defaults.conf diff --git a/src/testing/Makefile.in b/src/testing/Makefile.in index 459066f..66ee17c 100644 --- a/src/testing/Makefile.in +++ b/src/testing/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. @@ -18,6 +18,23 @@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -37,53 +54,29 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -bin_PROGRAMS = gnunet-testing$(EXEEXT) -check_PROGRAMS = test_testing$(EXEEXT) test_testing_connect$(EXEEXT) \ - test_testing_reconnect$(EXEEXT) test_testing_group$(EXEEXT) \ - test_testing_peergroup$(EXEEXT) \ - test_testing_topology_stability$(EXEEXT) \ - test_testing_topology_clique$(EXEEXT) \ - test_testing_topology_clique_random$(EXEEXT) \ - test_testing_topology_clique_minimum$(EXEEXT) \ - test_testing_topology_clique_dfs$(EXEEXT) \ - test_testing_topology_churn$(EXEEXT) \ - test_testing_topology_line$(EXEEXT) \ - test_testing_topology_blacklist$(EXEEXT) \ - test_testing_group_remote$(EXEEXT) \ - test_testing_2dtorus$(EXEEXT) \ - test_testing_topology_ring$(EXEEXT) \ - test_testing_topology_2d_torus$(EXEEXT) \ - test_testing_topology_small_world_ring$(EXEEXT) \ - test_testing_topology_small_world_torus$(EXEEXT) \ - test_testing_topology_erdos_renyi$(EXEEXT) \ - test_testing_topology_internat$(EXEEXT) \ - test_testing_topology_none$(EXEEXT) \ - test_testing_topology_scale_free$(EXEEXT) \ - test_testing_new_portreservation$(EXEEXT) \ - test_testing_new_peerstartup$(EXEEXT) \ - test_testing_new_servicestartup$(EXEEXT) -@ENABLE_TEST_RUN_TRUE@TESTS = test_testing$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_testing_connect$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_testing_reconnect$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_testing_group$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_testing_peergroup$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_testing_new_portreservation$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_testing_new_peerstartup$(EXEEXT) \ -@ENABLE_TEST_RUN_TRUE@ test_testing_new_servicestartup$(EXEEXT) +bin_PROGRAMS = gnunet-testing-run-service$(EXEEXT) \ + gnunet-testing$(EXEEXT) +check_PROGRAMS = test_testing_portreservation$(EXEEXT) \ + test_testing_peerstartup$(EXEEXT) \ + test_testing_servicestartup$(EXEEXT) +@ENABLE_TEST_RUN_TRUE@TESTS = test_testing_portreservation$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_testing_peerstartup$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@ test_testing_servicestartup$(EXEEXT) subdir = src/testing DIST_COMMON = $(dist_pkgcfg_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \ $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \ - $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glib-2.0.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/libunistring.m4 \ + $(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ @@ -113,221 +106,55 @@ 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)$(bindir)" \ "$(DESTDIR)$(pkgcfgdir)" LTLIBRARIES = $(lib_LTLIBRARIES) am__DEPENDENCIES_1 = -libgnunettesting_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_libgnunettesting_la_OBJECTS = helper.lo testing.lo testing_group.lo \ - testing_peergroup.lo +libgnunettesting_la_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(am__DEPENDENCIES_1) +am_libgnunettesting_la_OBJECTS = testing.lo libgnunettesting_la_OBJECTS = $(am_libgnunettesting_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 libgnunettesting_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libgnunettesting_la_LDFLAGS) \ $(LDFLAGS) -o $@ -libgnunettesting_new_la_DEPENDENCIES = \ - $(top_builddir)/src/util/libgnunetutil.la -am_libgnunettesting_new_la_OBJECTS = testing_new.lo -libgnunettesting_new_la_OBJECTS = \ - $(am_libgnunettesting_new_la_OBJECTS) -libgnunettesting_new_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libgnunettesting_new_la_LDFLAGS) \ - $(LDFLAGS) -o $@ PROGRAMS = $(bin_PROGRAMS) am_gnunet_testing_OBJECTS = gnunet-testing.$(OBJEXT) gnunet_testing_OBJECTS = $(am_gnunet_testing_OBJECTS) -am_test_testing_OBJECTS = test_testing.$(OBJEXT) -test_testing_OBJECTS = $(am_test_testing_OBJECTS) -test_testing_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_2dtorus_OBJECTS = test_testing_2dtorus.$(OBJEXT) -test_testing_2dtorus_OBJECTS = $(am_test_testing_2dtorus_OBJECTS) -test_testing_2dtorus_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_connect_OBJECTS = test_testing_connect.$(OBJEXT) -test_testing_connect_OBJECTS = $(am_test_testing_connect_OBJECTS) -test_testing_connect_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_group_OBJECTS = test_testing_group.$(OBJEXT) -test_testing_group_OBJECTS = $(am_test_testing_group_OBJECTS) -test_testing_group_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_group_remote_OBJECTS = \ - test_testing_group_remote.$(OBJEXT) -test_testing_group_remote_OBJECTS = \ - $(am_test_testing_group_remote_OBJECTS) -test_testing_group_remote_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_new_peerstartup_OBJECTS = \ - test_testing_new_peerstartup.$(OBJEXT) -test_testing_new_peerstartup_OBJECTS = \ - $(am_test_testing_new_peerstartup_OBJECTS) -test_testing_new_peerstartup_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting_new.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_new_portreservation_OBJECTS = \ - test_testing_new_portreservation.$(OBJEXT) -test_testing_new_portreservation_OBJECTS = \ - $(am_test_testing_new_portreservation_OBJECTS) -test_testing_new_portreservation_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting_new.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_new_servicestartup_OBJECTS = \ - test_testing_new_servicestartup.$(OBJEXT) -test_testing_new_servicestartup_OBJECTS = \ - $(am_test_testing_new_servicestartup_OBJECTS) -test_testing_new_servicestartup_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting_new.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_peergroup_OBJECTS = test_testing_peergroup.$(OBJEXT) -test_testing_peergroup_OBJECTS = $(am_test_testing_peergroup_OBJECTS) -test_testing_peergroup_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_reconnect_OBJECTS = test_testing_reconnect.$(OBJEXT) -test_testing_reconnect_OBJECTS = $(am_test_testing_reconnect_OBJECTS) -test_testing_reconnect_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_2d_torus_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_2d_torus_OBJECTS = \ - $(am_test_testing_topology_2d_torus_OBJECTS) -test_testing_topology_2d_torus_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_blacklist_OBJECTS = \ - test_testing_topology_blacklist.$(OBJEXT) -test_testing_topology_blacklist_OBJECTS = \ - $(am_test_testing_topology_blacklist_OBJECTS) -test_testing_topology_blacklist_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_churn_OBJECTS = \ - test_testing_topology_churn.$(OBJEXT) -test_testing_topology_churn_OBJECTS = \ - $(am_test_testing_topology_churn_OBJECTS) -test_testing_topology_churn_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_clique_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_clique_OBJECTS = \ - $(am_test_testing_topology_clique_OBJECTS) -test_testing_topology_clique_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_clique_dfs_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_clique_dfs_OBJECTS = \ - $(am_test_testing_topology_clique_dfs_OBJECTS) -test_testing_topology_clique_dfs_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_clique_minimum_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_clique_minimum_OBJECTS = \ - $(am_test_testing_topology_clique_minimum_OBJECTS) -test_testing_topology_clique_minimum_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_clique_random_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_clique_random_OBJECTS = \ - $(am_test_testing_topology_clique_random_OBJECTS) -test_testing_topology_clique_random_DEPENDENCIES = \ +am_gnunet_testing_run_service_OBJECTS = \ + gnunet-testing-run-service.$(OBJEXT) +gnunet_testing_run_service_OBJECTS = \ + $(am_gnunet_testing_run_service_OBJECTS) +am_test_testing_peerstartup_OBJECTS = \ + test_testing_peerstartup.$(OBJEXT) +test_testing_peerstartup_OBJECTS = \ + $(am_test_testing_peerstartup_OBJECTS) +test_testing_peerstartup_DEPENDENCIES = \ $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_erdos_renyi_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_erdos_renyi_OBJECTS = \ - $(am_test_testing_topology_erdos_renyi_OBJECTS) -test_testing_topology_erdos_renyi_DEPENDENCIES = \ +am_test_testing_portreservation_OBJECTS = \ + test_testing_portreservation.$(OBJEXT) +test_testing_portreservation_OBJECTS = \ + $(am_test_testing_portreservation_OBJECTS) +test_testing_portreservation_DEPENDENCIES = \ $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_internat_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_internat_OBJECTS = \ - $(am_test_testing_topology_internat_OBJECTS) -test_testing_topology_internat_DEPENDENCIES = \ +am_test_testing_servicestartup_OBJECTS = \ + test_testing_servicestartup.$(OBJEXT) +test_testing_servicestartup_OBJECTS = \ + $(am_test_testing_servicestartup_OBJECTS) +test_testing_servicestartup_DEPENDENCIES = \ $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_line_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_line_OBJECTS = \ - $(am_test_testing_topology_line_OBJECTS) -test_testing_topology_line_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_none_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_none_OBJECTS = \ - $(am_test_testing_topology_none_OBJECTS) -test_testing_topology_none_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_ring_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_ring_OBJECTS = \ - $(am_test_testing_topology_ring_OBJECTS) -test_testing_topology_ring_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_scale_free_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_scale_free_OBJECTS = \ - $(am_test_testing_topology_scale_free_OBJECTS) -test_testing_topology_scale_free_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_small_world_ring_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_small_world_ring_OBJECTS = \ - $(am_test_testing_topology_small_world_ring_OBJECTS) -test_testing_topology_small_world_ring_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_small_world_torus_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_small_world_torus_OBJECTS = \ - $(am_test_testing_topology_small_world_torus_OBJECTS) -test_testing_topology_small_world_torus_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la -am_test_testing_topology_stability_OBJECTS = \ - test_testing_topology.$(OBJEXT) -test_testing_topology_stability_OBJECTS = \ - $(am_test_testing_topology_stability_OBJECTS) -test_testing_topology_stability_DEPENDENCIES = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -339,74 +166,38 @@ 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 = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) 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 = $(libgnunettesting_la_SOURCES) \ - $(libgnunettesting_new_la_SOURCES) $(gnunet_testing_SOURCES) \ - $(test_testing_SOURCES) $(test_testing_2dtorus_SOURCES) \ - $(test_testing_connect_SOURCES) $(test_testing_group_SOURCES) \ - $(test_testing_group_remote_SOURCES) \ - $(test_testing_new_peerstartup_SOURCES) \ - $(test_testing_new_portreservation_SOURCES) \ - $(test_testing_new_servicestartup_SOURCES) \ - $(test_testing_peergroup_SOURCES) \ - $(test_testing_reconnect_SOURCES) \ - $(test_testing_topology_2d_torus_SOURCES) \ - $(test_testing_topology_blacklist_SOURCES) \ - $(test_testing_topology_churn_SOURCES) \ - $(test_testing_topology_clique_SOURCES) \ - $(test_testing_topology_clique_dfs_SOURCES) \ - $(test_testing_topology_clique_minimum_SOURCES) \ - $(test_testing_topology_clique_random_SOURCES) \ - $(test_testing_topology_erdos_renyi_SOURCES) \ - $(test_testing_topology_internat_SOURCES) \ - $(test_testing_topology_line_SOURCES) \ - $(test_testing_topology_none_SOURCES) \ - $(test_testing_topology_ring_SOURCES) \ - $(test_testing_topology_scale_free_SOURCES) \ - $(test_testing_topology_small_world_ring_SOURCES) \ - $(test_testing_topology_small_world_torus_SOURCES) \ - $(test_testing_topology_stability_SOURCES) +SOURCES = $(libgnunettesting_la_SOURCES) $(gnunet_testing_SOURCES) \ + $(gnunet_testing_run_service_SOURCES) \ + $(test_testing_peerstartup_SOURCES) \ + $(test_testing_portreservation_SOURCES) \ + $(test_testing_servicestartup_SOURCES) DIST_SOURCES = $(libgnunettesting_la_SOURCES) \ - $(libgnunettesting_new_la_SOURCES) $(gnunet_testing_SOURCES) \ - $(test_testing_SOURCES) $(test_testing_2dtorus_SOURCES) \ - $(test_testing_connect_SOURCES) $(test_testing_group_SOURCES) \ - $(test_testing_group_remote_SOURCES) \ - $(test_testing_new_peerstartup_SOURCES) \ - $(test_testing_new_portreservation_SOURCES) \ - $(test_testing_new_servicestartup_SOURCES) \ - $(test_testing_peergroup_SOURCES) \ - $(test_testing_reconnect_SOURCES) \ - $(test_testing_topology_2d_torus_SOURCES) \ - $(test_testing_topology_blacklist_SOURCES) \ - $(test_testing_topology_churn_SOURCES) \ - $(test_testing_topology_clique_SOURCES) \ - $(test_testing_topology_clique_dfs_SOURCES) \ - $(test_testing_topology_clique_minimum_SOURCES) \ - $(test_testing_topology_clique_random_SOURCES) \ - $(test_testing_topology_erdos_renyi_SOURCES) \ - $(test_testing_topology_internat_SOURCES) \ - $(test_testing_topology_line_SOURCES) \ - $(test_testing_topology_none_SOURCES) \ - $(test_testing_topology_ring_SOURCES) \ - $(test_testing_topology_scale_free_SOURCES) \ - $(test_testing_topology_small_world_ring_SOURCES) \ - $(test_testing_topology_small_world_torus_SOURCES) \ - $(test_testing_topology_stability_SOURCES) + $(gnunet_testing_SOURCES) \ + $(gnunet_testing_run_service_SOURCES) \ + $(test_testing_peerstartup_SOURCES) \ + $(test_testing_portreservation_SOURCES) \ + $(test_testing_servicestartup_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac DATA = $(dist_pkgcfg_DATA) ETAGS = etags CTAGS = ctags @@ -448,6 +239,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@ @@ -458,6 +253,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@ @@ -480,6 +276,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@ @@ -501,6 +299,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@ @@ -510,6 +309,7 @@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ NM = @NM@ NMEDIT = @NMEDIT@ +NSS_DIR = @NSS_DIR@ OBJC = @OBJC@ OBJCDEPMODE = @OBJCDEPMODE@ OBJCFLAGS = @OBJCFLAGS@ @@ -525,6 +325,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@ @@ -556,6 +357,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@ @@ -578,6 +380,7 @@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ +gitcommand = @gitcommand@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ @@ -591,7 +394,6 @@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ -lt_ECHO = @lt_ECHO@ ltdl_LIBOBJS = @ltdl_LIBOBJS@ ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ mandir = @mandir@ @@ -609,6 +411,7 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ subdirs = @subdirs@ +svnversioncommand = @svnversioncommand@ sys_symbol_underscore = @sys_symbol_underscore@ sysconfdir = @sysconfdir@ target = @target@ @@ -627,54 +430,30 @@ pkgcfgdir = $(pkgdatadir)/config.d/ dist_pkgcfg_DATA = \ testing.conf -@HAVE_EXPENSIVE_TESTS_TRUE@EXPENSIVE_TESTS = \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_stability \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_clique_random \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_clique_minimum \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_clique_dfs \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_churn \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_line \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_blacklist \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_group_remote \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_ring \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_2d_torus \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_small_world_ring \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_small_world_torus \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_erdos_renyi \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_internat \ -@HAVE_EXPENSIVE_TESTS_TRUE@ test_testing_topology_scale_free - lib_LTLIBRARIES = \ - libgnunettesting.la \ - libgnunettesting_new.la + libgnunettesting.la libgnunettesting_la_SOURCES = \ - helper.c \ - testing.c \ - testing_group.c \ - testing_peergroup.c - -libgnunettesting_la_LIBADD = $(XLIB) \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/statistics/libgnunetstatistics.la \ - $(top_builddir)/src/transport/libgnunettransport.la \ - $(top_builddir)/src/hello/libgnunethello.la \ - -lm \ - $(top_builddir)/src/util/libgnunetutil.la + testing.c + +libgnunettesting_la_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) libgnunettesting_la_LDFLAGS = \ $(GN_LIB_LDFLAGS) \ - -version-info 0:1:0 + -version-info 2:0:1 -libgnunettesting_new_la_SOURCES = \ - testing_new.c +gnunet_testing_run_service_SOURCES = \ + gnunet-testing-run-service.c -libgnunettesting_new_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la +gnunet_testing_run_service_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(GN_LIBINTL) -libgnunettesting_new_la_LDFLAGS = \ - $(GN_LIB_LDFLAGS) \ - -version-info 0:1:0 +gnunet_testing_run_service_DEPENDENCIES = \ + libgnunettesting.la gnunet_testing_SOURCES = \ gnunet-testing.c @@ -687,225 +466,29 @@ gnunet_testing_LDADD = \ gnunet_testing_DEPENDENCIES = \ libgnunettesting.la -test_testing_SOURCES = \ - test_testing.c - -test_testing_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_connect_SOURCES = \ - test_testing_connect.c - -test_testing_connect_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_reconnect_SOURCES = \ - test_testing_reconnect.c - -test_testing_reconnect_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_group_SOURCES = \ - test_testing_group.c - -test_testing_group_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_peergroup_SOURCES = \ - test_testing_peergroup.c +test_testing_portreservation_SOURCES = \ + test_testing_portreservation.c -test_testing_peergroup_LDADD = \ +test_testing_portreservation_LDADD = \ $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_clique_SOURCES = \ - test_testing_topology.c - -test_testing_topology_clique_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_stability_SOURCES = \ - test_testing_topology.c - -test_testing_topology_stability_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_blacklist_SOURCES = \ - test_testing_topology_blacklist.c - -test_testing_topology_blacklist_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_churn_SOURCES = \ - test_testing_topology_churn.c - -test_testing_topology_churn_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_clique_random_SOURCES = \ - test_testing_topology.c - -test_testing_topology_clique_random_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_clique_minimum_SOURCES = \ - test_testing_topology.c - -test_testing_topology_clique_minimum_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_clique_dfs_SOURCES = \ - test_testing_topology.c - -test_testing_topology_clique_dfs_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_line_SOURCES = \ - test_testing_topology.c - -test_testing_topology_line_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_group_remote_SOURCES = \ - test_testing_group_remote.c - -test_testing_group_remote_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_2dtorus_SOURCES = \ - test_testing_2dtorus.c - -test_testing_2dtorus_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_ring_SOURCES = \ - test_testing_topology.c - -test_testing_topology_ring_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_2d_torus_SOURCES = \ - test_testing_topology.c - -test_testing_topology_2d_torus_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_small_world_ring_SOURCES = \ - test_testing_topology.c - -test_testing_topology_small_world_ring_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_small_world_torus_SOURCES = \ - test_testing_topology.c - -test_testing_topology_small_world_torus_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_internat_SOURCES = \ - test_testing_topology.c - -test_testing_topology_internat_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la -test_testing_topology_erdos_renyi_SOURCES = \ - test_testing_topology.c +test_testing_peerstartup_SOURCES = \ + test_testing_peerstartup.c -test_testing_topology_erdos_renyi_LDADD = \ +test_testing_peerstartup_LDADD = \ $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ $(top_builddir)/src/util/libgnunetutil.la -test_testing_topology_scale_free_SOURCES = \ - test_testing_topology.c +test_testing_servicestartup_SOURCES = \ + test_testing_servicestartup.c -test_testing_topology_scale_free_LDADD = \ +test_testing_servicestartup_LDADD = \ $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_topology_none_SOURCES = \ - test_testing_topology.c - -test_testing_topology_none_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting.la \ - $(top_builddir)/src/core/libgnunetcore.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_new_portreservation_SOURCES = \ - test_testing_new_portreservation.c - -test_testing_new_portreservation_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting_new.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_new_peerstartup_SOURCES = \ - test_testing_new_peerstartup.c - -test_testing_new_peerstartup_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting_new.la \ - $(top_builddir)/src/util/libgnunetutil.la - -test_testing_new_servicestartup_SOURCES = \ - test_testing_new_servicestartup.c - -test_testing_new_servicestartup_LDADD = \ - $(top_builddir)/src/testing/libgnunettesting_new.la \ $(top_builddir)/src/util/libgnunetutil.la EXTRA_DIST = \ - test_testing_defaults.conf \ - test_testing_data.conf \ - test_testing_connect_peer1.conf \ - test_testing_connect_peer2.conf \ - test_testing_2dtorus.conf \ - test_testing_data_topology_clique.conf \ - test_testing_data_topology_clique_random.conf \ - test_testing_data_topology_clique_minimum.conf \ - test_testing_data_topology_clique_dfs.conf \ - test_testing_data_topology_ring.conf \ - test_testing_data_topology_2d_torus.conf \ - test_testing_data_topology_small_world_ring.conf \ - test_testing_data_topology_small_world_torus.conf \ - test_testing_data_topology_erdos_renyi.conf \ - test_testing_data_topology_internat.conf \ - test_testing_data_topology_scale_free.conf \ - test_testing_data_topology_blacklist.conf \ - test_testing_data_topology_churn.conf \ - test_testing_data_topology_none.conf \ - test_testing_data_remote.conf \ - test_testing_data_topology_stability.conf \ - test_testing_peergroup_data.conf + test_testing_defaults.conf all: all-am @@ -943,7 +526,6 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): 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 \ @@ -951,6 +533,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)"; \ } @@ -972,14 +556,15 @@ clean-libLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libgnunettesting.la: $(libgnunettesting_la_OBJECTS) $(libgnunettesting_la_DEPENDENCIES) +libgnunettesting.la: $(libgnunettesting_la_OBJECTS) $(libgnunettesting_la_DEPENDENCIES) $(EXTRA_libgnunettesting_la_DEPENDENCIES) $(AM_V_CCLD)$(libgnunettesting_la_LINK) -rpath $(libdir) $(libgnunettesting_la_OBJECTS) $(libgnunettesting_la_LIBADD) $(LIBS) -libgnunettesting_new.la: $(libgnunettesting_new_la_OBJECTS) $(libgnunettesting_new_la_DEPENDENCIES) - $(AM_V_CCLD)$(libgnunettesting_new_la_LINK) -rpath $(libdir) $(libgnunettesting_new_la_OBJECTS) $(libgnunettesting_new_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ @@ -1028,87 +613,21 @@ clean-checkPROGRAMS: list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list -gnunet-testing$(EXEEXT): $(gnunet_testing_OBJECTS) $(gnunet_testing_DEPENDENCIES) +gnunet-testing$(EXEEXT): $(gnunet_testing_OBJECTS) $(gnunet_testing_DEPENDENCIES) $(EXTRA_gnunet_testing_DEPENDENCIES) @rm -f gnunet-testing$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gnunet_testing_OBJECTS) $(gnunet_testing_LDADD) $(LIBS) -test_testing$(EXEEXT): $(test_testing_OBJECTS) $(test_testing_DEPENDENCIES) - @rm -f test_testing$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_OBJECTS) $(test_testing_LDADD) $(LIBS) -test_testing_2dtorus$(EXEEXT): $(test_testing_2dtorus_OBJECTS) $(test_testing_2dtorus_DEPENDENCIES) - @rm -f test_testing_2dtorus$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_2dtorus_OBJECTS) $(test_testing_2dtorus_LDADD) $(LIBS) -test_testing_connect$(EXEEXT): $(test_testing_connect_OBJECTS) $(test_testing_connect_DEPENDENCIES) - @rm -f test_testing_connect$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_connect_OBJECTS) $(test_testing_connect_LDADD) $(LIBS) -test_testing_group$(EXEEXT): $(test_testing_group_OBJECTS) $(test_testing_group_DEPENDENCIES) - @rm -f test_testing_group$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_group_OBJECTS) $(test_testing_group_LDADD) $(LIBS) -test_testing_group_remote$(EXEEXT): $(test_testing_group_remote_OBJECTS) $(test_testing_group_remote_DEPENDENCIES) - @rm -f test_testing_group_remote$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_group_remote_OBJECTS) $(test_testing_group_remote_LDADD) $(LIBS) -test_testing_new_peerstartup$(EXEEXT): $(test_testing_new_peerstartup_OBJECTS) $(test_testing_new_peerstartup_DEPENDENCIES) - @rm -f test_testing_new_peerstartup$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_new_peerstartup_OBJECTS) $(test_testing_new_peerstartup_LDADD) $(LIBS) -test_testing_new_portreservation$(EXEEXT): $(test_testing_new_portreservation_OBJECTS) $(test_testing_new_portreservation_DEPENDENCIES) - @rm -f test_testing_new_portreservation$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_new_portreservation_OBJECTS) $(test_testing_new_portreservation_LDADD) $(LIBS) -test_testing_new_servicestartup$(EXEEXT): $(test_testing_new_servicestartup_OBJECTS) $(test_testing_new_servicestartup_DEPENDENCIES) - @rm -f test_testing_new_servicestartup$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_new_servicestartup_OBJECTS) $(test_testing_new_servicestartup_LDADD) $(LIBS) -test_testing_peergroup$(EXEEXT): $(test_testing_peergroup_OBJECTS) $(test_testing_peergroup_DEPENDENCIES) - @rm -f test_testing_peergroup$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_peergroup_OBJECTS) $(test_testing_peergroup_LDADD) $(LIBS) -test_testing_reconnect$(EXEEXT): $(test_testing_reconnect_OBJECTS) $(test_testing_reconnect_DEPENDENCIES) - @rm -f test_testing_reconnect$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_reconnect_OBJECTS) $(test_testing_reconnect_LDADD) $(LIBS) -test_testing_topology_2d_torus$(EXEEXT): $(test_testing_topology_2d_torus_OBJECTS) $(test_testing_topology_2d_torus_DEPENDENCIES) - @rm -f test_testing_topology_2d_torus$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_2d_torus_OBJECTS) $(test_testing_topology_2d_torus_LDADD) $(LIBS) -test_testing_topology_blacklist$(EXEEXT): $(test_testing_topology_blacklist_OBJECTS) $(test_testing_topology_blacklist_DEPENDENCIES) - @rm -f test_testing_topology_blacklist$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_blacklist_OBJECTS) $(test_testing_topology_blacklist_LDADD) $(LIBS) -test_testing_topology_churn$(EXEEXT): $(test_testing_topology_churn_OBJECTS) $(test_testing_topology_churn_DEPENDENCIES) - @rm -f test_testing_topology_churn$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_churn_OBJECTS) $(test_testing_topology_churn_LDADD) $(LIBS) -test_testing_topology_clique$(EXEEXT): $(test_testing_topology_clique_OBJECTS) $(test_testing_topology_clique_DEPENDENCIES) - @rm -f test_testing_topology_clique$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_clique_OBJECTS) $(test_testing_topology_clique_LDADD) $(LIBS) -test_testing_topology_clique_dfs$(EXEEXT): $(test_testing_topology_clique_dfs_OBJECTS) $(test_testing_topology_clique_dfs_DEPENDENCIES) - @rm -f test_testing_topology_clique_dfs$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_clique_dfs_OBJECTS) $(test_testing_topology_clique_dfs_LDADD) $(LIBS) -test_testing_topology_clique_minimum$(EXEEXT): $(test_testing_topology_clique_minimum_OBJECTS) $(test_testing_topology_clique_minimum_DEPENDENCIES) - @rm -f test_testing_topology_clique_minimum$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_clique_minimum_OBJECTS) $(test_testing_topology_clique_minimum_LDADD) $(LIBS) -test_testing_topology_clique_random$(EXEEXT): $(test_testing_topology_clique_random_OBJECTS) $(test_testing_topology_clique_random_DEPENDENCIES) - @rm -f test_testing_topology_clique_random$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_clique_random_OBJECTS) $(test_testing_topology_clique_random_LDADD) $(LIBS) -test_testing_topology_erdos_renyi$(EXEEXT): $(test_testing_topology_erdos_renyi_OBJECTS) $(test_testing_topology_erdos_renyi_DEPENDENCIES) - @rm -f test_testing_topology_erdos_renyi$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_erdos_renyi_OBJECTS) $(test_testing_topology_erdos_renyi_LDADD) $(LIBS) -test_testing_topology_internat$(EXEEXT): $(test_testing_topology_internat_OBJECTS) $(test_testing_topology_internat_DEPENDENCIES) - @rm -f test_testing_topology_internat$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_internat_OBJECTS) $(test_testing_topology_internat_LDADD) $(LIBS) -test_testing_topology_line$(EXEEXT): $(test_testing_topology_line_OBJECTS) $(test_testing_topology_line_DEPENDENCIES) - @rm -f test_testing_topology_line$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_line_OBJECTS) $(test_testing_topology_line_LDADD) $(LIBS) -test_testing_topology_none$(EXEEXT): $(test_testing_topology_none_OBJECTS) $(test_testing_topology_none_DEPENDENCIES) - @rm -f test_testing_topology_none$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_none_OBJECTS) $(test_testing_topology_none_LDADD) $(LIBS) -test_testing_topology_ring$(EXEEXT): $(test_testing_topology_ring_OBJECTS) $(test_testing_topology_ring_DEPENDENCIES) - @rm -f test_testing_topology_ring$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_ring_OBJECTS) $(test_testing_topology_ring_LDADD) $(LIBS) -test_testing_topology_scale_free$(EXEEXT): $(test_testing_topology_scale_free_OBJECTS) $(test_testing_topology_scale_free_DEPENDENCIES) - @rm -f test_testing_topology_scale_free$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_scale_free_OBJECTS) $(test_testing_topology_scale_free_LDADD) $(LIBS) -test_testing_topology_small_world_ring$(EXEEXT): $(test_testing_topology_small_world_ring_OBJECTS) $(test_testing_topology_small_world_ring_DEPENDENCIES) - @rm -f test_testing_topology_small_world_ring$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_small_world_ring_OBJECTS) $(test_testing_topology_small_world_ring_LDADD) $(LIBS) -test_testing_topology_small_world_torus$(EXEEXT): $(test_testing_topology_small_world_torus_OBJECTS) $(test_testing_topology_small_world_torus_DEPENDENCIES) - @rm -f test_testing_topology_small_world_torus$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_small_world_torus_OBJECTS) $(test_testing_topology_small_world_torus_LDADD) $(LIBS) -test_testing_topology_stability$(EXEEXT): $(test_testing_topology_stability_OBJECTS) $(test_testing_topology_stability_DEPENDENCIES) - @rm -f test_testing_topology_stability$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_testing_topology_stability_OBJECTS) $(test_testing_topology_stability_LDADD) $(LIBS) +gnunet-testing-run-service$(EXEEXT): $(gnunet_testing_run_service_OBJECTS) $(gnunet_testing_run_service_DEPENDENCIES) $(EXTRA_gnunet_testing_run_service_DEPENDENCIES) + @rm -f gnunet-testing-run-service$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_testing_run_service_OBJECTS) $(gnunet_testing_run_service_LDADD) $(LIBS) +test_testing_peerstartup$(EXEEXT): $(test_testing_peerstartup_OBJECTS) $(test_testing_peerstartup_DEPENDENCIES) $(EXTRA_test_testing_peerstartup_DEPENDENCIES) + @rm -f test_testing_peerstartup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_testing_peerstartup_OBJECTS) $(test_testing_peerstartup_LDADD) $(LIBS) +test_testing_portreservation$(EXEEXT): $(test_testing_portreservation_OBJECTS) $(test_testing_portreservation_DEPENDENCIES) $(EXTRA_test_testing_portreservation_DEPENDENCIES) + @rm -f test_testing_portreservation$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_testing_portreservation_OBJECTS) $(test_testing_portreservation_LDADD) $(LIBS) +test_testing_servicestartup$(EXEEXT): $(test_testing_servicestartup_OBJECTS) $(test_testing_servicestartup_DEPENDENCIES) $(EXTRA_test_testing_servicestartup_DEPENDENCIES) + @rm -f test_testing_servicestartup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_testing_servicestartup_OBJECTS) $(test_testing_servicestartup_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -1116,49 +635,33 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-testing-run-service.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-testing.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_2dtorus.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_connect.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_group.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_group_remote.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_new_peerstartup.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_new_portreservation.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_new_servicestartup.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_peergroup.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_reconnect.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_topology.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_topology_blacklist.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_topology_churn.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_peerstartup.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_portreservation.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_testing_servicestartup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testing.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testing_group.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testing_new.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testing_peergroup.Plo@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 @@ -1167,8 +670,11 @@ clean-libtool: -rm -rf .libs _libs install-dist_pkgcfgDATA: $(dist_pkgcfg_DATA) @$(NORMAL_INSTALL) - test -z "$(pkgcfgdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)" @list='$(dist_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"; \ @@ -1182,9 +688,7 @@ uninstall-dist_pkgcfgDATA: @$(NORMAL_UNINSTALL) @list='$(dist_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)'; \ @@ -1319,14 +823,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 @@ -1381,10 +886,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: diff --git a/src/testing/gnunet-testing-run-service.c b/src/testing/gnunet-testing-run-service.c new file mode 100644 index 0000000..ed60a40 --- /dev/null +++ b/src/testing/gnunet-testing-run-service.c @@ -0,0 +1,211 @@ +/* + This file is part of GNUnet. + (C) 2001, 2002, 2004, 2005, 2006, 2007, 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 testing/gnunet-testing-run-service.c + * @brief tool to start a service for testing + * @author Florian Dold + * + * Start a peer, running only the service specified on the command line. + * Outputs the path to the temporary configuration file to stdout. + * + * The peer will run until this program is killed, + * or stdin is closed. When reading the character 'r' from stdin, + * the running service is restarted with the same configuration. + * + * This executable is intended to be used by gnunet-java, in order to reliably + * start and stop services for test cases. + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testing_lib.h" + +#define LOG(kind,...) \ + GNUNET_log_from (kind, "gnunet-testing", __VA_ARGS__) + + +/** + * File handle to STDIN, for reading restart/quit commands. + */ +static struct GNUNET_DISK_FileHandle *fh; + +/** + * FIXME + */ +static char *tmpfilename; + +/** + * FIXME + */ +static GNUNET_SCHEDULER_TaskIdentifier tid; + +/** + * FIXME + */ +static struct GNUNET_TESTING_Peer *my_peer; + + + + +/** + * Cleanup called by signal handlers and when stdin is closed. + * Removes the temporary file. + * + * @param cls unused + * @param tc scheduler context + */ +static void +cleanup (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (NULL != tmpfilename) + { + if (0 != UNLINK (tmpfilename)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", tmpfilename); + } + if (GNUNET_SCHEDULER_NO_TASK != tid) + { + GNUNET_SCHEDULER_cancel (tid); + tid = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != fh) + { + GNUNET_DISK_file_close (fh); + fh = NULL; + } +} + + +/** + * Called whenever we can read stdin non-blocking + * + * @param cls unused + * @param tc scheduler context + */ +static void +stdin_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + int c; + + tid = GNUNET_SCHEDULER_NO_TASK; + if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason)) + return; + GNUNET_assert (0 != (GNUNET_SCHEDULER_REASON_READ_READY & tc->reason)); + c = getchar (); + switch (c) + { + case EOF: + case 'q': + GNUNET_SCHEDULER_shutdown (); + return; + case 'r': + GNUNET_TESTING_peer_stop (my_peer); + GNUNET_TESTING_peer_start (my_peer); + printf ("restarted\n"); + fflush (stdout); + break; + case '\n': + case '\r': + /* ignore whitespace */ + break; + default: + fprintf (stderr, _("Unknown command, use 'q' to quit or 'r' to restart peer\n")); + break; + } + tid = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, fh, + &stdin_cb, NULL); +} + + +/** + * Main function called by the testing library. + * Executed inside a running scheduler. + * + * @param cls unused + * @param cfg configuration of the peer that was started + * @param peer handle to the peer + */ +static void +testing_main (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) +{ + my_peer = peer; + if (NULL == (tmpfilename = GNUNET_DISK_mktemp ("gnunet-testing"))) + { + GNUNET_break (0); + GNUNET_SCHEDULER_shutdown (); + return; + } + if (GNUNET_SYSERR == + GNUNET_CONFIGURATION_write ((struct GNUNET_CONFIGURATION_Handle *) cfg, + tmpfilename)) + { + GNUNET_break (0); + return; + } + printf("ok\n%s\n", tmpfilename); + fflush(stdout); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup, NULL); + fh = GNUNET_DISK_get_handle_from_native (stdin); + tid = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, fh, + &stdin_cb, NULL); +} + + +/** + * The main function. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static char *cfg_name; + static char *srv_name; + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'c', "config", "FILENAME", + gettext_noop ("name of the template configuration file to use (optional)"), 1, + &GNUNET_GETOPT_set_string, &cfg_name}, + {'s', "service", "SERVICE", + gettext_noop ("name of the service to run"), 1, + &GNUNET_GETOPT_set_string, &srv_name}, + GNUNET_GETOPT_OPTION_HELP ("tool to start a service for testing"), + GNUNET_GETOPT_OPTION_END + }; + int ret; + + if (GNUNET_SYSERR == + GNUNET_GETOPT_run("gnunet-testing-run-service", options, argc, argv)) + return 1; + ret = GNUNET_TESTING_service_run ("gnunet_service_test", srv_name, + cfg_name, &testing_main, NULL); + if (0 != ret) + { + printf ("error\n"); + } + else + { + printf ("bye\n"); + } + return ret; +} + diff --git a/src/testing/gnunet-testing.c b/src/testing/gnunet-testing.c index bdbb5e8..28c5be9 100644 --- a/src/testing/gnunet-testing.c +++ b/src/testing/gnunet-testing.c @@ -24,10 +24,10 @@ * @author Christian Grothoff */ #include "platform.h" -#include "gnunet_getopt_lib.h" -#include "gnunet_program_lib.h" +#include "gnunet_util_lib.h" #include "gnunet_testing_lib.h" + #define HOSTKEYFILESIZE 914 /** @@ -35,66 +35,51 @@ */ static int ret; -static unsigned int create_hostkey; +static char *create_hostkey; -static unsigned int create_cfg; +static int create_cfg; -static int create_no; +static unsigned int create_no; -static char * create_cfg_template; +static char *create_cfg_template; -static char * create_hostkey_file; static int create_unique_cfgs (const char * template, const unsigned int no) { - int fail = GNUNET_NO; - - uint16_t port = 20000; - uint32_t upnum = 1; - uint32_t fdnum = 1; + struct GNUNET_TESTING_System *system; + int fail; + unsigned int cur; + char *cur_file; + struct GNUNET_CONFIGURATION_Handle *cfg_new; + struct GNUNET_CONFIGURATION_Handle *cfg_tmpl; if (GNUNET_NO == GNUNET_DISK_file_test(template)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Configuration template `%s': file not found\n", create_cfg_template); return 1; } - - int cur = 0; - char * cur_file; - char *service_home = NULL; - char *cur_service_home = NULL; - - struct GNUNET_CONFIGURATION_Handle *cfg_new = NULL; - struct GNUNET_CONFIGURATION_Handle *cfg_tmpl = GNUNET_CONFIGURATION_create(); + cfg_tmpl = GNUNET_CONFIGURATION_create(); /* load template */ if ((create_cfg_template != NULL) && (GNUNET_OK != GNUNET_CONFIGURATION_load(cfg_tmpl, create_cfg_template))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not load template `%s'\n", create_cfg_template); - GNUNET_CONFIGURATION_destroy(cfg_tmpl); + GNUNET_CONFIGURATION_destroy (cfg_tmpl); return 1; } /* load defaults */ - else if (GNUNET_OK != GNUNET_CONFIGURATION_load(cfg_tmpl, NULL)) + if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg_tmpl, NULL)) { - GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not load template `%s'\n", create_cfg_template); + GNUNET_CONFIGURATION_destroy (cfg_tmpl); return 1; } - if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg_tmpl, "PATHS", "SERVICEHOME", &service_home)) - { - GNUNET_asprintf(&service_home, "%s", "/tmp/testing"); - } - else - { - int s = strlen (service_home); - if (service_home[s-1] == DIR_SEPARATOR) - service_home[s-1] = '\0'; - } - - while (cur < no) + fail = GNUNET_NO; + system = GNUNET_TESTING_system_create ("testing", NULL /* controller */, NULL); + for (cur = 0; cur < no; cur++) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating configuration no. %u \n", cur); if (create_cfg_template != NULL) @@ -102,118 +87,72 @@ create_unique_cfgs (const char * template, const unsigned int no) else GNUNET_asprintf (&cur_file,"%04u%s",cur, ".conf"); - - GNUNET_asprintf (&cur_service_home, "%s-%04u%c",service_home, cur, DIR_SEPARATOR); - GNUNET_CONFIGURATION_set_value_string (cfg_tmpl,"PATHS","SERVICEHOME", cur_service_home); - GNUNET_CONFIGURATION_set_value_string (cfg_tmpl,"PATHS","DEFAULTCONFIG", cur_file); - GNUNET_free (cur_service_home); - - cfg_new = GNUNET_TESTING_create_cfg(cfg_tmpl, cur, &port, &upnum, NULL, &fdnum); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing configuration no. %u to file `%s' \n", cur, cur_file); + cfg_new = GNUNET_CONFIGURATION_dup (cfg_tmpl); + if (GNUNET_OK != + GNUNET_TESTING_configuration_create (system, cfg_new)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not create another configuration\n"); + GNUNET_CONFIGURATION_destroy (cfg_new); + fail = GNUNET_YES; + break; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Writing configuration no. %u to file `%s' \n", cur, cur_file); if (GNUNET_OK != GNUNET_CONFIGURATION_write(cfg_new, cur_file)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to write configuration no. %u \n", cur); fail = GNUNET_YES; } - GNUNET_CONFIGURATION_destroy (cfg_new); GNUNET_free (cur_file); - if (fail == GNUNET_YES) + if (GNUNET_YES == fail) break; - cur ++; } - GNUNET_CONFIGURATION_destroy(cfg_tmpl); - GNUNET_free (service_home); - if (fail == GNUNET_NO) - return 0; - else + GNUNET_TESTING_system_destroy (system, GNUNET_NO); + if (GNUNET_YES == fail) return 1; + return 0; } + static int create_hostkeys (const unsigned int no) { + struct GNUNET_TESTING_System *system; + struct GNUNET_PeerIdentity id; struct GNUNET_DISK_FileHandle *fd; - int cur = 0; - uint64_t fs; - uint64_t total_hostkeys; - char *hostkey_data; - char *hostkey_src_file; - char *hostkey_dest_file; - - /* prepare hostkeys */ - if (create_hostkey_file == NULL) - hostkey_src_file = "../../contrib/testing_hostkeys.dat"; - else - { - hostkey_src_file = create_hostkey_file; - } + struct GNUNET_CRYPTO_RsaPrivateKey *pk; + struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *pkb; - if (GNUNET_YES != GNUNET_DISK_file_test (hostkey_src_file)) + system = GNUNET_TESTING_system_create ("testing", NULL, NULL); + pk = GNUNET_TESTING_hostkey_get (system, create_no, &id); + if (NULL == pk) { - if (create_hostkey_file == NULL) - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not read hostkeys file, specify hostkey file with -H!\n")); - else - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Specified hostkey file `%s' not found!\n"), create_hostkey_file); + fprintf (stderr, _("Could not extract hostkey %u (offset too large?)\n"), create_no); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); return 1; } - else - { - /* Check hostkey file size, read entire thing into memory */ - fd = GNUNET_DISK_file_open (hostkey_src_file, GNUNET_DISK_OPEN_READ, - GNUNET_DISK_PERM_NONE); - if (NULL == fd) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", hostkey_src_file); - return 1; - } - - if (GNUNET_OK != GNUNET_DISK_file_size (hostkey_src_file, &fs, GNUNET_YES, GNUNET_YES)) - fs = 0; - - if (0 != (fs % HOSTKEYFILESIZE)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "File size %llu seems incorrect for hostkeys...\n", fs); - } - else - { - total_hostkeys = fs / HOSTKEYFILESIZE; - hostkey_data = GNUNET_malloc_large (fs); - GNUNET_assert (fs == GNUNET_DISK_file_read (fd, hostkey_data, fs)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Read %llu hostkeys from file\n", total_hostkeys); - } - GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); - } - - while (cur < no) - { - GNUNET_asprintf (&hostkey_dest_file, "%04u-hostkey",cur); - GNUNET_assert (GNUNET_OK == - GNUNET_DISK_directory_create_for_file (hostkey_dest_file)); - fd = GNUNET_DISK_file_open (hostkey_dest_file, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - GNUNET_assert (fd != NULL); - GNUNET_assert (HOSTKEYFILESIZE == - GNUNET_DISK_file_write (fd, &hostkey_data[cur * HOSTKEYFILESIZE], HOSTKEYFILESIZE)); - GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", - "Wrote hostkey to file: `%s' \n", hostkey_dest_file); - GNUNET_free (hostkey_dest_file); - cur ++; - } - - GNUNET_free (hostkey_data); - + (void) GNUNET_DISK_directory_create_for_file (create_hostkey); + fd = GNUNET_DISK_file_open (create_hostkey, + GNUNET_DISK_OPEN_READWRITE | + GNUNET_DISK_OPEN_CREATE, + GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); + GNUNET_assert (fd != NULL); + pkb = GNUNET_CRYPTO_rsa_encode_key (pk); + GNUNET_assert (HOSTKEYFILESIZE == + GNUNET_DISK_file_write (fd, pkb, ntohs (pkb->len))); + GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); + GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "transport-testing", + "Wrote hostkey to file: `%s'\n", create_hostkey); + GNUNET_free (pkb); + GNUNET_CRYPTO_rsa_key_free (pk); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); return 0; } + /** * Main function that will be run by the scheduler. * @@ -227,11 +166,12 @@ run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { /* main code here */ - if (create_cfg == GNUNET_YES) + if (GNUNET_YES == create_cfg) { if (create_no > 0) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating %u configuration files based on template `%s'\n", create_no, create_cfg_template); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Creating %u configuration files based on template `%s'\n", create_no, create_cfg_template); ret = create_unique_cfgs (create_cfg_template, create_no); } else @@ -240,21 +180,11 @@ run (void *cls, char *const *args, const char *cfgfile, ret = 1; } } - - if (create_hostkey == GNUNET_YES) + if (NULL != create_hostkey) { - if (create_no > 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating %u hostkeys \n", create_no); - ret = create_hostkeys (create_no); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Missing arguments! \n"); - ret = 1; - } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Extracting hostkey %u\n", create_no); + ret = create_hostkeys (create_no); } - GNUNET_free_non_null (create_cfg_template); } @@ -272,20 +202,23 @@ main (int argc, char *const *argv) static const struct GNUNET_GETOPT_CommandLineOption options[] = { {'C', "cfg", NULL, gettext_noop ("create unique configuration files"), GNUNET_NO, &GNUNET_GETOPT_set_one, &create_cfg}, - {'k', "key", NULL, gettext_noop ("create hostkey files from pre-computed hostkey list"), - GNUNET_NO, &GNUNET_GETOPT_set_one, &create_hostkey}, - {'H', "hostkeys", NULL, gettext_noop ("host key file"), - GNUNET_YES, &GNUNET_GETOPT_set_string, &create_hostkey_file}, - {'n', "number", NULL, gettext_noop ("number of unique configuration files or hostkeys to create"), + {'k', "key", "FILENAME", gettext_noop ("extract hostkey file from pre-computed hostkey list"), + GNUNET_YES, &GNUNET_GETOPT_set_string, &create_hostkey}, + {'n', "number", "NUMBER", gettext_noop ("number of unique configuration files to create, or number of the hostkey to extract"), GNUNET_YES, &GNUNET_GETOPT_set_uint, &create_no}, - {'t', "template", NULL, gettext_noop ("configuration template"), + {'t', "template", "FILENAME", gettext_noop ("configuration template"), GNUNET_YES, &GNUNET_GETOPT_set_string, &create_cfg_template}, GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-testing", - gettext_noop ("Command line tool to access the testing library"), options, &run, - NULL)) ? ret : 1; + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-testing", + gettext_noop ("Command line tool to access the testing library"), options, &run, + NULL)) ? ret : 1; + GNUNET_free ((void*) argv); + return ret; } /* end of gnunet-testing.c */ diff --git a/src/testing/helper.c b/src/testing/helper.c deleted file mode 100644 index ebb37eb..0000000 --- a/src/testing/helper.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - 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 testing/helper.c - * @brief helper functions for testing - * @author Christian Grothoff - * - */ -#include "platform.h" -#include "gnunet_testing_lib.h" - - - - -/** - * Obtain the peer identity of the peer with the given configuration - * handle. This function reads the private key of the peer, obtains - * the public key and hashes it. - * - * @param cfg configuration of the peer - * @param pid where to store the peer identity - * @return GNUNET_OK on success, GNUNET_SYSERR on failure - */ -int -GNUNET_TESTING_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_PeerIdentity *pid) -{ - char *keyfile; - struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY", - &keyfile)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ - ("Peer is lacking HOSTKEY configuration setting.\n")); - return GNUNET_SYSERR; - } - my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); - GNUNET_free (keyfile); - if (my_private_key == NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Could not access hostkey.\n")); - return GNUNET_SYSERR; - } - GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key); - GNUNET_CRYPTO_rsa_key_free (my_private_key); - GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), - &pid->hashPubKey); - return GNUNET_OK; -} - - -/* end of helper.c */ diff --git a/src/testing/test_testing.c b/src/testing/test_testing.c deleted file mode 100644 index 3e2cd65..0000000 --- a/src/testing/test_testing.c +++ /dev/null @@ -1,126 +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 testing/test_testing.c - * @brief testcase for testing.c - */ -#include "platform.h" -#include "gnunet_testing_lib.h" - -#define VERBOSE GNUNET_YES - -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) - -static int ok; - -static void -end_cb (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Ending with error: %s\n", emsg); - ok = 1; - } - else - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Daemon terminated, will now exit.\n"); -#endif - ok = 0; - } -} - - - -void -do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_TESTING_Daemon *d = cls; - - GNUNET_TESTING_daemon_stop (d, TIMEOUT, &end_cb, NULL, GNUNET_YES, GNUNET_NO); -} - - -static void -my_cb (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - GNUNET_assert (id != NULL); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Daemon `%s' started, will now stop it.\n", GNUNET_i2s (id)); -#endif - GNUNET_SCHEDULER_add_now (&do_shutdown, d); -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - struct GNUNET_TESTING_Daemon *d; - - ok = 1; -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemon.\n"); -#endif - d = GNUNET_TESTING_daemon_start (cfg, TIMEOUT, GNUNET_NO, NULL, NULL, 0, NULL, - NULL, NULL, &my_cb, NULL); - GNUNET_assert (d != NULL); -} - -static int -check () -{ - char *const argv[] = { "test-testing", - "-c", - "test_testing_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-testing", "nohelp", options, &run, &ok); - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-testing", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); - - return ret; -} - -/* end of test_testing.c */ diff --git a/src/testing/test_testing_2dtorus.c b/src/testing/test_testing_2dtorus.c deleted file mode 100644 index 00a66d6..0000000 --- a/src/testing/test_testing_2dtorus.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2011 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ -/** - * @file testing/test_testing_2dtorus.c - * - * @brief Test for creating a 2dtorus. - */ -#include "platform.h" -#include "gnunet_testing_lib.h" - -#define VERBOSE GNUNET_YES -#define REMOVE_DIR GNUNET_YES - -/** - * How long until we give up on connecting the peers? - */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500) - -/** - * Time to wait for stuff that should be rather fast - */ -#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) - - -/** - * How many events have happened - */ -static int ok; - -/** - * Be verbose - */ -static int verbose; - -/** - * Total number of peers in the test. - */ -static unsigned long long num_peers; - -/** - * Global configuration file - */ -static struct GNUNET_CONFIGURATION_Handle *testing_cfg; - -/** - * Total number of currently running peers. - */ -static unsigned long long peers_running; - -/** - * Total number of successful connections in the whole network. - */ -static unsigned int total_connections; - -/** - * Total number of counted topo connections - */ -static unsigned int topo_connections; - -/** - * Total number of failed connections in the whole network. - */ -static unsigned int failed_connections; - -/** - * The currently running peer group. - */ -static struct GNUNET_TESTING_PeerGroup *pg; - -/** - * Task called to disconnect peers - */ -static GNUNET_SCHEDULER_TaskIdentifier disconnect_task; - -/** - * Task called to shutdown test. - */ -static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle; - - -/** - * Check whether peers successfully shut down. - */ -static void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Shutdown of peers failed!\n"); -#endif - ok--; - } - else - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "test: All peers successfully shut down!\n"); -#endif - } -} - - -static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Ending test.\n"); -#endif - - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - GNUNET_CONFIGURATION_destroy (testing_cfg); -} - - -static void -disconnect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: disconnecting peers\n"); - - if (GNUNET_SCHEDULER_NO_TASK != shutdown_handle) - { - GNUNET_SCHEDULER_cancel (shutdown_handle); - shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); - } -} - - -/** - * Prototype of a callback function indicating that two peers - * are currently connected. - * - * @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 emsg error message (NULL on success) - */ -void -topo_cb (void *cls, const struct GNUNET_PeerIdentity *first, - const struct GNUNET_PeerIdentity *second, const char *emsg) -{ - topo_connections++; - if (NULL != emsg) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test: Error by topo %u: %s\n", - topo_connections, emsg); - } - else - { - if (first == NULL || second == NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Connection %u NULL\n", - topo_connections); - if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (disconnect_task); - GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); - } - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Connection %u ok\n", - topo_connections); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: %s\n", GNUNET_i2s (first)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: %s\n", GNUNET_i2s (second)); - } -} - - -/** - * 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) -{ - 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; - } -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "************************************************************\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "test: Peer Group started successfully!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Have %u connections\n", - total_connections); -#endif - - peers_running = GNUNET_TESTING_daemons_running (pg); - if (0 < failed_connections) - { - ok = GNUNET_SYSERR; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: %u connections have FAILED!\n", - failed_connections); - disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); - - } - else - { - GNUNET_TESTING_get_topology (pg, &topo_cb, NULL); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_peers, NULL); - ok = GNUNET_OK; - } - -} - - -/** - * 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++; - } - else - { - failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "test: Problem with new connection (%s)\n", emsg); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: (%s)\n", GNUNET_i2s (first)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: (%s)\n", GNUNET_i2s (second)); - } - -} - - -/** - * 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) -{ - struct GNUNET_TESTING_Host *hosts; - - ok = GNUNET_NO; - total_connections = 0; - failed_connections = 0; - testing_cfg = GNUNET_CONFIGURATION_dup (cfg); - - GNUNET_log_setup ("test_testing_2dtorus", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Starting daemons.\n"); - GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing", - "use_progressbars", "YES"); -#endif - - 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; - } - - 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); -} - - -/** - * test_testing_2dtorus 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 argc, char *argv[]) -{ - char *const argv2[] = { - argv[0], - "-c", - "test_testing_2dtorus.conf", -#if VERBOSE - "-L", - "DEBUG", -#endif - NULL - }; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Start\n"); - - - GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, - "test_testing_2dtorus", - gettext_noop ("Test testing 2d torus."), options, &run, - NULL); -#if REMOVE_DIR - GNUNET_DISK_directory_remove ("/tmp/test_testing_2dtorus"); -#endif - if (GNUNET_OK != ok) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test: FAILED!\n"); - return 1; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: success\n"); - return 0; -} - -/* end of test_testing_2dtorus.c */ diff --git a/src/testing/test_testing_2dtorus.conf b/src/testing/test_testing_2dtorus.conf deleted file mode 100644 index 54bb7c5..0000000 --- a/src/testing/test_testing_2dtorus.conf +++ /dev/null @@ -1,81 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -SERVICEHOME = /tmp/test_testing_2dtorus/ -DEFAULTCONFIG = test_testing_2dtorus.conf - -[arm] -PORT = 10010 -DEFAULTSERVICES = core -#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 - -[nse] -WORKBITS = 0 - -[dns] -AUTOSTART = NO -PORT = 10011 - -[transport] -PORT = 10002 -AUTOSTART = YES -PLUGINS = tcp - -[nat] -DISABLEV6 = YES -BINDTO = 127.0.0.1 -ENABLE_UPNP = NO -BEHIND_NAT = NO -ALLOW_NAT = NO -INTERNAL_ADDRESS = 127.0.0.1 -EXTERNAL_ADDRESS = 127.0.0.1 - -[ats] -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 = 2D_TORUS -CONNECT_TOPOLOGY = 2D_TORUS -#TOPOLOGY_FILE = small.dat -CONNECT_TOPOLOGY = 2D_TORUS -#CONNECT_TOPOLOGY_OPTION = CONNECT_MINIMUM -#CONNECT_TOPOLOGY_OPTION_MODIFIER = 25 -#PERCENTAGE = 3 -#PROBABILITY = .1 -F2F = NO -CONNECT_TIMEOUT = 600 s -CONNECT_ATTEMPTS = 2 -DEBUG = YES -HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat -MAX_CONCURRENT_SSH = 10 -USE_PROGRESSBARS = YES -PEERGROUP_TIMEOUT = 2400 s -TOPOLOGY_OUTPUT_FILE = testing_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 diff --git a/src/testing/test_testing_connect.c b/src/testing/test_testing_connect.c deleted file mode 100644 index c69c203..0000000 --- a/src/testing/test_testing_connect.c +++ /dev/null @@ -1,197 +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 testing/test_testing_connect.c - * @brief testcase for functions to connect two peers in testing.c - */ -#include "platform.h" -#include "gnunet_testing_lib.h" - -#define VERBOSE GNUNET_NO - -/** - * How long until we give up on connecting the peers? - */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) - -#define CONNECT_ATTEMPTS 3 - -static int ok; - -static struct GNUNET_TESTING_Daemon *d1; - -static struct GNUNET_TESTING_Daemon *d2; - -static struct GNUNET_CONFIGURATION_Handle *c1; - -static struct GNUNET_CONFIGURATION_Handle *c2; - -static struct GNUNET_TESTING_ConnectContext *cc; - -static void -end2_cb (void *cls, const char *emsg) -{ - - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Ending with error: %s\n", emsg); - ok = 1; - } - else - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Both daemons terminated, will now exit.\n"); -#endif - ok = 0; - } -} - -static void -end1_cb (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Stopping daemon 1 gave: %s\n", - emsg); - ok = 1; - } - else - { - ok = 0; - } - - GNUNET_TESTING_daemon_stop (d2, TIMEOUT, &end2_cb, NULL, GNUNET_YES, - GNUNET_NO); - d2 = NULL; -} - -static void -finish_testing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_TESTING_daemon_stop (d1, TIMEOUT, &end1_cb, NULL, GNUNET_YES, - GNUNET_NO); - d1 = NULL; -} - -static void -my_connect_complete (void *cls, const struct GNUNET_PeerIdentity *first, - const struct GNUNET_PeerIdentity *second, - unsigned int 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) -{ - cc = NULL; - GNUNET_SCHEDULER_add_now (&finish_testing, NULL); -} - - -static void -my_cb2 (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - GNUNET_assert (id != NULL); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Daemon `%s' started.\n", - GNUNET_i2s (id)); -#endif - cc = GNUNET_TESTING_daemons_connect (d1, d2, TIMEOUT, CONNECT_ATTEMPTS, - GNUNET_YES, &my_connect_complete, NULL); -} - - -static void -my_cb1 (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - GNUNET_assert (id != NULL); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Daemon `%s' started.\n", - GNUNET_i2s (id)); -#endif - d2 = GNUNET_TESTING_daemon_start (c2, TIMEOUT, GNUNET_NO, NULL, NULL, 0, NULL, - NULL, NULL, &my_cb2, NULL); - GNUNET_assert (d2 != NULL); - -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - ok = 1; -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemon.\n"); -#endif - c1 = GNUNET_CONFIGURATION_create (); - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_load (c1, - "test_testing_connect_peer1.conf")); - c2 = GNUNET_CONFIGURATION_create (); - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_load (c2, - "test_testing_connect_peer2.conf")); - d1 = GNUNET_TESTING_daemon_start (c1, TIMEOUT, GNUNET_NO, NULL, NULL, 0, NULL, - NULL, NULL, &my_cb1, NULL); - GNUNET_assert (d1 != NULL); -} - -static int -check () -{ - char *const argv[] = { "test-testing", - "-c", - "test_testing_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-testing-connect", "nohelp", options, &run, &ok); - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-testing-connect", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); - return ret; -} - -/* end of test_testing_connect.c */ diff --git a/src/testing/test_testing_connect_peer1.conf b/src/testing/test_testing_connect_peer1.conf deleted file mode 100644 index cccda5e..0000000 --- a/src/testing/test_testing_connect_peer1.conf +++ /dev/null @@ -1,37 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -SERVICEHOME = /tmp/test-gnunet-testing-connect-peer1/ -DEFAULTCONFIG = test_testing_connect_peer1.conf - -[transport-tcp] -PORT = 12568 - -[arm] -PORT = 12566 -DEFAULTSERVICES = core -UNIXPATH = /tmp/gnunet-p1-service-arm.sock - -[statistics] -PORT = 12567 -UNIXPATH = /tmp/gnunet-p1-service-statistics.sock - -[resolver] -PORT = 12564 -UNIXPATH = /tmp/gnunet-p1-service-resolver.sock - -[peerinfo] -PORT = 12569 -UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock - -[transport] -PORT = 12565 -UNIXPATH = /tmp/gnunet-p1-service-transport.sock - -[core] -PORT = 12570 -UNIXPATH = /tmp/gnunet-p1-service-core.sock - -[ats] -PORT = 12571 -UNIXPATH = /tmp/gnunet-p1-service-ats.sock - diff --git a/src/testing/test_testing_connect_peer2.conf b/src/testing/test_testing_connect_peer2.conf deleted file mode 100644 index 08ec551..0000000 --- a/src/testing/test_testing_connect_peer2.conf +++ /dev/null @@ -1,37 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -SERVICEHOME = /tmp/test-gnunet-testing-connect-peer2/ -DEFAULTCONFIG = test_testing_connect_peer2.conf - -[transport-tcp] -PORT = 22568 - -[arm] -PORT = 22566 -DEFAULTSERVICES = core -UNIXPATH = /tmp/gnunet-p2-service-arm.sock - -[statistics] -PORT = 22567 -UNIXPATH = /tmp/gnunet-p2-service-statistics.sock - -[resolver] -PORT = 22564 -UNIXPATH = /tmp/gnunet-p2-service-resolver.sock - -[peerinfo] -PORT = 22569 -UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock - -[transport] -PORT = 22565 -UNIXPATH = /tmp/gnunet-p2-service-transport.sock - -[core] -PORT = 22570 -UNIXPATH = /tmp/gnunet-p2-service-core.sock - -[ats] -PORT = 22571 -UNIXPATH = /tmp/gnunet-p2-service-ats.sock - diff --git a/src/testing/test_testing_data.conf b/src/testing/test_testing_data.conf deleted file mode 100644 index c46cb0d..0000000 --- a/src/testing/test_testing_data.conf +++ /dev/null @@ -1,7 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data.conf - -[arm] -DEFAULTSERVICES = core - diff --git a/src/testing/test_testing_data_remote.conf b/src/testing/test_testing_data_remote.conf deleted file mode 100644 index d58666f..0000000 --- a/src/testing/test_testing_data_remote.conf +++ /dev/null @@ -1,12 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_remote.conf - -[TESTING] -CONTROL_HOST = 127.0.0.1 -HOSTFILE = remote_hosts.txt -MAX_OUTSTANDING_SSH = 5 - -[statistics] -AUTOSTART = NO - diff --git a/src/testing/test_testing_data_topology_2d_torus.conf b/src/testing/test_testing_data_topology_2d_torus.conf deleted file mode 100644 index cbdaceb..0000000 --- a/src/testing/test_testing_data_topology_2d_torus.conf +++ /dev/null @@ -1,7 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_2d_torus.conf - -[TESTING] -NUM_PEERS = 13 -TOPOLOGY = 2D_TORUS diff --git a/src/testing/test_testing_data_topology_blacklist.conf b/src/testing/test_testing_data_topology_blacklist.conf deleted file mode 100644 index 36e378d..0000000 --- a/src/testing/test_testing_data_topology_blacklist.conf +++ /dev/null @@ -1,13 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_blacklist.conf - -[TESTING] -NUM_PEERS = 4 -TOPOLOGY = CLIQUE -BLACKLIST_TOPOLOGY = RING -BLACKLIST_TRANSPORTS = tcp udp http - -[transport-udp] -PORT = 2568 - diff --git a/src/testing/test_testing_data_topology_churn.conf b/src/testing/test_testing_data_topology_churn.conf deleted file mode 100644 index b337165..0000000 --- a/src/testing/test_testing_data_topology_churn.conf +++ /dev/null @@ -1,10 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_churn.conf - -[TESTING] -NUM_PEERS = 12 - -[arm] -DEFAULTSERVICES = peerinfo transport core - diff --git a/src/testing/test_testing_data_topology_clique.conf b/src/testing/test_testing_data_topology_clique.conf deleted file mode 100644 index 69cecb7..0000000 --- a/src/testing/test_testing_data_topology_clique.conf +++ /dev/null @@ -1,10 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -CONNECT_TIMEOUT = 180 s -CONNECT_ATTEMPTS = 14 -NUM_PEERS = 4 -TOPOLOGY = CLIQUE -SETTLE_TIME = 0 diff --git a/src/testing/test_testing_data_topology_clique_dfs.conf b/src/testing/test_testing_data_topology_clique_dfs.conf deleted file mode 100644 index c7abeae..0000000 --- a/src/testing/test_testing_data_topology_clique_dfs.conf +++ /dev/null @@ -1,13 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -NUM_PEERS = 7 -TOPOLOGY = CLIQUE -CONNECT_TOPOLOGY_OPTION = CONNECT_DFS -CONNECT_TOPOLOGY_OPTION_MODIFIER = 2.0 - -[arm] -DEFAULTSERVICES = peerinfo transport core - diff --git a/src/testing/test_testing_data_topology_clique_minimum.conf b/src/testing/test_testing_data_topology_clique_minimum.conf deleted file mode 100644 index ef95cb1..0000000 --- a/src/testing/test_testing_data_topology_clique_minimum.conf +++ /dev/null @@ -1,10 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -NUM_PEERS = 20 -TOPOLOGY = CLIQUE -CONNECT_TOPOLOGY_OPTION = CONNECT_MINIMUM -CONNECT_TOPOLOGY_OPTION_MODIFIER = 2.0 - diff --git a/src/testing/test_testing_data_topology_clique_random.conf b/src/testing/test_testing_data_topology_clique_random.conf deleted file mode 100644 index cd44b65..0000000 --- a/src/testing/test_testing_data_topology_clique_random.conf +++ /dev/null @@ -1,16 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -NUM_PEERS = 20 -TOPOLOGY = CLIQUE -CONNECT_TOPOLOGY_OPTION = CONNECT_RANDOM_SUBSET -CONNECT_TOPOLOGY_OPTION_MODIFIER = .15 - -[statistics] -AUTOSTART = NO - -[resolver] -AUTOSTART = NO - diff --git a/src/testing/test_testing_data_topology_erdos_renyi.conf b/src/testing/test_testing_data_topology_erdos_renyi.conf deleted file mode 100644 index 8e17413..0000000 --- a/src/testing/test_testing_data_topology_erdos_renyi.conf +++ /dev/null @@ -1,7 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -TOPOLOGY = ERDOS_RENYI - diff --git a/src/testing/test_testing_data_topology_internat.conf b/src/testing/test_testing_data_topology_internat.conf deleted file mode 100644 index af3f62f..0000000 --- a/src/testing/test_testing_data_topology_internat.conf +++ /dev/null @@ -1,7 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -TOPOLOGY = INTERNAT - diff --git a/src/testing/test_testing_data_topology_none.conf b/src/testing/test_testing_data_topology_none.conf deleted file mode 100644 index dbee5d0..0000000 --- a/src/testing/test_testing_data_topology_none.conf +++ /dev/null @@ -1,37 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -NUM_PEERS = 1000 -TOPOLOGY = NONE -F2F = NO -BLACKLIST_TOPOLOGY = NONE -CONNECT_TOPOLOGY = RING - -[arm] -PORT = 0 - -[statistics] -AUTOSTART = NO -PORT = 0 - -[resolver] -AUTOSTART = NO -PORT = 0 - -[peerinfo] -PORT = 0 - -[transport] -PORT = 0 - -[core] -PORT = 0 - -[topology] -PORT = 0 - -[hostlist] -PORT = 0 - diff --git a/src/testing/test_testing_data_topology_ring.conf b/src/testing/test_testing_data_topology_ring.conf deleted file mode 100644 index 6159030..0000000 --- a/src/testing/test_testing_data_topology_ring.conf +++ /dev/null @@ -1,7 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -TOPOLOGY = RING - diff --git a/src/testing/test_testing_data_topology_scale_free.conf b/src/testing/test_testing_data_topology_scale_free.conf deleted file mode 100644 index 7690eac..0000000 --- a/src/testing/test_testing_data_topology_scale_free.conf +++ /dev/null @@ -1,11 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_scale_free.conf - -[TESTING] -NUM_PEERS = 50 -TOPOLOGY = SCALE_FREE - -[arm] -DEFAULTSERVICES = peerinfo transport core - diff --git a/src/testing/test_testing_data_topology_small_world_ring.conf b/src/testing/test_testing_data_topology_small_world_ring.conf deleted file mode 100644 index 01931df..0000000 --- a/src/testing/test_testing_data_topology_small_world_ring.conf +++ /dev/null @@ -1,8 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -NUM_PEERS = 25 -TOPOLOGY = SMALL_WORLD_RING - diff --git a/src/testing/test_testing_data_topology_small_world_torus.conf b/src/testing/test_testing_data_topology_small_world_torus.conf deleted file mode 100644 index 7c35454..0000000 --- a/src/testing/test_testing_data_topology_small_world_torus.conf +++ /dev/null @@ -1,7 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -TOPOLOGY = SMALL_WORLD - diff --git a/src/testing/test_testing_data_topology_stability.conf b/src/testing/test_testing_data_topology_stability.conf deleted file mode 100644 index 1bfcd1b..0000000 --- a/src/testing/test_testing_data_topology_stability.conf +++ /dev/null @@ -1,9 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_data_topology_clique.conf - -[TESTING] -SETTLE_TIME = 600 s -NUM_PEERS = 2 -TOPOLOGY = CLIQUE - diff --git a/src/testing/test_testing_defaults.conf b/src/testing/test_testing_defaults.conf index ba7e269..1a58a31 100644 --- a/src/testing/test_testing_defaults.conf +++ b/src/testing/test_testing_defaults.conf @@ -1,6 +1,5 @@ [PATHS] SERVICEHOME = /tmp/test-gnunet-testing/ -DEFAULTCONFIG = test_testing_defaults.conf [resolver] PORT = 2564 @@ -9,6 +8,9 @@ PORT = 2564 PORT = 2565 PLUGINS = tcp +[transport-tcp] +TESTING_IGNORE_KEYS = SOMETHING;KEY1;ACCEPT_FROM; + [arm] PORT = 2566 DEFAULTSERVICES = @@ -26,12 +28,6 @@ PORT = 2569 [core] PORT = 2570 -[testing] -NUM_PEERS = 5 -WEAKRANDOM = YES -F2F = YES -HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat - [dht] AUTOSTART = NO @@ -76,3 +72,7 @@ AUTOSTART = NO [lockmanager] AUTOSTART = NO + +[consensus] +AUTOSTART = NO + diff --git a/src/testing/test_testing_group.c b/src/testing/test_testing_group.c deleted file mode 100644 index f5df45b..0000000 --- a/src/testing/test_testing_group.c +++ /dev/null @@ -1,166 +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 testing/test_testing_group.c - * @brief testcase for functions to connect peers in testing.c - */ -#include "platform.h" -#include "gnunet_testing_lib.h" - -#define VERBOSE GNUNET_NO - -#define NUM_PEERS 4 - -/** - * How long until we give up on connecting the peers? - */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) - -static int ok; - -static int peers_left; - -static int failed_peers; - -static struct GNUNET_TESTING_PeerGroup *pg; - -/** - * Check whether peers successfully shut down. - */ -void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed!\n"); -#endif - if (ok == 0) - ok = 666; - } - else - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); -#endif - } -} - - -static void -my_cb (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - if (id == NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Start callback called with error (too long starting peers), aborting test!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error from testing: `%s'\n"); - failed_peers++; - if (failed_peers == peers_left) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Too many peers failed, ending test!\n"); - ok = 1; - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - } - return; - } - - peers_left--; - if (peers_left == 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All peers started successfully, ending test!\n"); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - ok = 0; - } - else if (failed_peers == peers_left) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Too many peers failed, ending test!\n"); - ok = 1; - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - } -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - ok = 1; -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n"); -#endif - peers_left = NUM_PEERS; - 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, &my_cb, NULL, NULL, - NULL, NULL); - GNUNET_assert (pg != NULL); -} - -static int -check () -{ - char *const argv[] = { "test-testing", - "-c", - "test_testing_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-testing-group", "nohelp", options, &run, &ok); - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-testing-group", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); - /** - * Still need to remove the base testing directory here, - * because group starts will create subdirectories under this - * main dir. However, we no longer need to sleep, as the - * shutdown sequence won't return until everything is cleaned - * up. - */ - GNUNET_DISK_directory_remove ("/tmp/test-gnunet-testing"); - return ret; -} - -/* end of test_testing_group.c */ diff --git a/src/testing/test_testing_group_remote.c b/src/testing/test_testing_group_remote.c deleted file mode 100644 index b06655c..0000000 --- a/src/testing/test_testing_group_remote.c +++ /dev/null @@ -1,263 +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 testing/test_testing_group_remote.c - * @brief testcase for testing remote and local starting and connecting - * of hosts from the testing library. The test_testing_data_remote.conf - * file should be modified if this testcase is intended to be used. - */ -#include "platform.h" -#include "gnunet_testing_lib.h" - -#define VERBOSE GNUNET_YES - - -/** - * How long until we give up on connecting the peers? - */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) - -#define DEFAULT_NUM_PEERS 8; - -static int ok; - -static int peers_left; - -static int peers_failed; - -static struct GNUNET_TESTING_PeerGroup *pg; - -static unsigned long long num_peers; - - -/** - * Check whether peers successfully shut down. - */ -void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Shutdown of peers failed (error %s)!\n", emsg); -#endif - if (ok == 0) - ok = 666; - } - else - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); -#endif - } -} - - -static void -my_cb (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - if (emsg != NULL) - { - peers_failed++; - } - - peers_left--; - if (peers_left == 0) - { - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - ok = 0; - } - else if (peers_failed == peers_left) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Too many peers failed, ending test!\n"); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - } -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - struct GNUNET_TESTING_Host *hosts; - struct GNUNET_TESTING_Host *hostpos; - struct GNUNET_TESTING_Host *temphost; - char *hostfile; - struct stat frstat; - char *buf; - char *data; - int count; - int ret; - - ok = 1; -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n"); -#endif - - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", - &num_peers)) - num_peers = DEFAULT_NUM_PEERS; - - GNUNET_assert (num_peers > 0 && num_peers < (unsigned long long) -1); - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "hostfile", - &hostfile)) - hostfile = NULL; - - hosts = NULL; - data = NULL; - if (hostfile != NULL) - { - if (GNUNET_OK != GNUNET_DISK_file_test (hostfile)) - GNUNET_DISK_fn_write (hostfile, NULL, 0, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - if ((0 != STAT (hostfile, &frstat)) || (frstat.st_size == 0)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not open file specified for host list, ending test!"); - ok = 1119; - GNUNET_free (hostfile); - return; - } - - data = GNUNET_malloc_large (frstat.st_size); - GNUNET_assert (data != NULL); - if (frstat.st_size != GNUNET_DISK_fn_read (hostfile, data, frstat.st_size)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not read file %s specified for host list, ending test!", - hostfile); - GNUNET_free (hostfile); - GNUNET_free (data); - return; - } - - GNUNET_free_non_null (hostfile); - - buf = data; - count = 0; - while (count < frstat.st_size) - { - count++; - if (count >= frstat.st_size) - break; - - /* if (((data[count] == '\n') || (data[count] == '\0')) && (buf != &data[count])) */ - if (((data[count] == '\n')) && (buf != &data[count])) - { - data[count] = '\0'; - temphost = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Host)); - ret = - SSCANF (buf, "%a[a-zA-Z0-9]@%a[a-zA-Z0-9.]:%hd", - &temphost->username, &temphost->hostname, &temphost->port); - if (3 == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Successfully read host %s, port %d and user %s from file\n", - temphost->hostname, temphost->port, temphost->username); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Error reading line `%s' in hostfile\n", buf); - GNUNET_free (temphost); - buf = &data[count + 1]; - continue; - } - /* temphost->hostname = buf; */ - temphost->next = hosts; - hosts = temphost; - buf = &data[count + 1]; - } - else if ((data[count] == '\n') || (data[count] == '\0')) - buf = &data[count + 1]; - } - } - - peers_left = num_peers; - 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, &my_cb, NULL, NULL, - NULL, hosts); - hostpos = hosts; - while (hostpos != NULL) - { - temphost = hostpos->next; - GNUNET_free (hostpos->hostname); - GNUNET_free (hostpos->username); - GNUNET_free (hostpos); - hostpos = temphost; - } - GNUNET_free_non_null (data); - GNUNET_assert (pg != NULL); - -} - -static int -check () -{ - char *const argv[] = { "test-testing", - "-c", - "test_testing_data_remote.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-testing-group", "nohelp", options, &run, &ok); - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-testing-group", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); - /** - * Still need to remove the base testing directory here, - * because group starts will create subdirectories under this - * main dir. However, we no longer need to sleep, as the - * shutdown sequence won't return until everything is cleaned - * up. - */ - GNUNET_DISK_directory_remove ("/tmp/test-gnunet-testing"); - return ret; -} - -/* end of test_testing_group.c */ diff --git a/src/testing/test_testing_peergroup.c b/src/testing/test_testing_peergroup.c deleted file mode 100644 index 061a0ca..0000000 --- a/src/testing/test_testing_peergroup.c +++ /dev/null @@ -1,157 +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 testing/test_testing_peergroup.c - * @brief testcase for functions to connect peers in testing_peergroup.c - */ -#include "platform.h" -#include "gnunet_testing_lib.h" - -#define VERBOSE GNUNET_NO - -#define NUM_PEERS 4 - -/** - * How long until we give up on connecting the peers? - */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) - -static int ok; - -static int peers_left; - -static struct GNUNET_TESTING_PeerGroup *pg; - -/** - * Check whether peers successfully shut down. - */ -void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed!\n"); -#endif - if (ok == 0) - ok = 666; - } - else - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); -#endif - ok = 0; - } -} - - -static void -my_cb (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peergroup callback called with error, aborting test!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Error from testing: `%s'\n"); - ok = 1; - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - return; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peer Group started successfully, ending test!\n"); - /** - * If something is to actually be DONE with the testcase, it should - * be put in here. Usually there will be a struct declared (or global - * variables can be used) to keep track of the state, statistics, - * handles to peers, etc. The example here is the opaque "TestCaseData" - * struct that could be passed into a function "additional_code_for_testing" - * which can be used to perform actions on the peers in the peergroup. - * Also, the GNUNET_TESTING_daemons_stop call would need to be removed, - * and only called once all of the testing is complete. - */ - - /** - * struct TestcaseData *state_closure; - * GNUNET_SCHEDULER_add_now(&additional_code_for_testing, state_closure); - */ - - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - struct GNUNET_CONFIGURATION_Handle *testing_cfg; - - ok = 1; - testing_cfg = GNUNET_CONFIGURATION_create (); - GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (testing_cfg, cfgfile)); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n"); - GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing", - "use_progressbars", "YES"); -#endif - peers_left = NUM_PEERS; - pg = GNUNET_TESTING_peergroup_start (testing_cfg, peers_left, TIMEOUT, NULL, - &my_cb, NULL, NULL); - GNUNET_assert (pg != NULL); -} - -static int -check () -{ - char *const argv[] = { "test-testing-peergroup", - "-c", - "test_testing_peergroup_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-testing-peergroup", "nohelp", options, &run, &ok); - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-testing-peergroup", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); - GNUNET_DISK_directory_remove ("/tmp/test-gnunet-testing"); - return ret; -} - -/* end of test_testing_peergroup.c */ diff --git a/src/testing/test_testing_peergroup_data.conf b/src/testing/test_testing_peergroup_data.conf deleted file mode 100644 index 6eadede..0000000 --- a/src/testing/test_testing_peergroup_data.conf +++ /dev/null @@ -1,22 +0,0 @@ -@INLINE@ test_testing_defaults.conf -[PATHS] -DEFAULTCONFIG = test_testing_peergroup_data.conf - -[TESTING] -CONNECT_ATTEMPTS = 2 -MAX_OUTSTANDING_CONNECTIONS = 20 -MAX_CONCURRENT_SSH = 1 -PEERGROUP_TIMEOUT = 300 s -TOPOLOGY = CLIQUE -PERCENTAGE = 0.5 -PROBABILITY = 0.5 -CONNECT_TOPOLOGY = CLIQUE -CONNECT_TOPOLOGY_OPTION = CONNECT_NONE -CONNECT_TOPOLOGY_OPTION_MODIFIER = 0.0 -BLACKLIST_TOPOLOGY = NONE -BLACKLIST_TRANSPORTS = tcp udp -USE_PROGRESSBARS = NO - -[arm] -DEFAULTSERVICES = core - diff --git a/src/testing/test_testing_new_peerstartup.c b/src/testing/test_testing_peerstartup.c index 203df2f..fb3967c 100644 --- a/src/testing/test_testing_new_peerstartup.c +++ b/src/testing/test_testing_peerstartup.c @@ -28,13 +28,15 @@ #include "platform.h" #include "gnunet_configuration_lib.h" #include "gnunet_os_lib.h" -#include "gnunet_testing_lib-new.h" +#include "gnunet_testing_lib.h" #define LOG(kind,...) \ GNUNET_log (kind, __VA_ARGS__) -#define TIME_REL_SEC(sec) \ - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) +/** + * The status of the test + */ +int status; /** * The testing context @@ -69,11 +71,16 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct TestingContext *test_ctx = cls; - GNUNET_assert (GNUNET_OK == GNUNET_TESTING_peer_stop (test_ctx->peer)); - GNUNET_TESTING_peer_destroy (test_ctx->peer); - GNUNET_CONFIGURATION_destroy (test_ctx->cfg); - GNUNET_TESTING_hostkeys_unload (test_ctx->system); - GNUNET_TESTING_system_destroy (test_ctx->system, GNUNET_YES); + GNUNET_assert (NULL != test_ctx); + if (NULL != test_ctx->peer) + { + (void) GNUNET_TESTING_peer_stop (test_ctx->peer); + GNUNET_TESTING_peer_destroy (test_ctx->peer); + } + if (NULL != test_ctx->cfg) + GNUNET_CONFIGURATION_destroy (test_ctx->cfg); + if (NULL != test_ctx->system) + GNUNET_TESTING_system_destroy (test_ctx->system, GNUNET_YES); GNUNET_free (test_ctx); } @@ -85,63 +92,35 @@ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { - struct GNUNET_TESTING_System *system; - struct GNUNET_TESTING_Peer *peer; - struct GNUNET_CONFIGURATION_Handle *new_cfg; struct TestingContext *test_ctx; - char *data_dir; - char *hostkeys_file; char *emsg; - char *_tmpdir; - char *tmpdir; -#ifdef MINGW - char *tmpdir_w; -#endif - struct GNUNET_PeerIdentity id; - - _tmpdir = getenv ("TMP"); - if (NULL == _tmpdir) - _tmpdir = getenv ("TEMP"); - if (NULL == _tmpdir) - _tmpdir = getenv ("TMPDIR"); - if (NULL == _tmpdir) - _tmpdir = "/tmp"; - GNUNET_asprintf (&tmpdir, "%s/%s", _tmpdir, "test-gnunet-testing_new-XXXXXX"); -#ifdef MINGW - tmpdir_w = GNUNET_malloc (MAX_PATH + 1); - GNUNET_assert (ERROR_SUCCESS == plibc_conv_to_win_path (tmpdir, tmpdir_w)); - GNUNET_free (tmpdir); - tmpdir = tmpdir_w; - //GNUNET_assert (0 == _mktemp_s (tmpdir, strlen (tmpdir) + 1)); -#else - GNUNET_assert (mkdtemp (tmpdir) == tmpdir); -#endif - /* LOG (GNUNET_ERROR_TYPE_ERROR, */ - /* "Temporary directory: %s\n", tmpdir); */ - system = GNUNET_TESTING_system_create (tmpdir, - "localhost"); - GNUNET_assert (NULL != system); - GNUNET_free (tmpdir); - data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); - GNUNET_asprintf (&hostkeys_file, "%s/testing_hostkeys.dat", data_dir); - GNUNET_free (data_dir); - GNUNET_assert (GNUNET_OK == - GNUNET_TESTING_hostkeys_load (system, hostkeys_file)); - GNUNET_free (hostkeys_file); - new_cfg = GNUNET_CONFIGURATION_dup (cfg); - emsg = NULL; - peer = GNUNET_TESTING_peer_configure (system, new_cfg, 0, &id, &emsg); - GNUNET_assert (NULL != peer); - GNUNET_assert (NULL == emsg); - GNUNET_assert (GNUNET_OK == GNUNET_TESTING_peer_start (peer)); + test_ctx = GNUNET_malloc (sizeof (struct TestingContext)); - test_ctx->system = system; - test_ctx->peer = peer; - test_ctx->cfg = new_cfg; - GNUNET_SCHEDULER_add_delayed (TIME_REL_SEC (5), - &do_shutdown, test_ctx); - + test_ctx->system = + GNUNET_TESTING_system_create ("test-gnunet-testing", + "127.0.0.1", NULL); + emsg = NULL; + if (NULL == test_ctx->system) + goto end; + test_ctx->cfg = GNUNET_CONFIGURATION_dup (cfg); + test_ctx->peer = + GNUNET_TESTING_peer_configure (test_ctx->system, + test_ctx->cfg, + 0, &id, &emsg); + if (NULL == test_ctx->peer) + { + if (NULL != emsg) + printf ("Test failed upon error: %s", emsg); + goto end; + } + if (GNUNET_OK != GNUNET_TESTING_peer_start (test_ctx->peer)) + goto end; + status = GNUNET_OK; + + end: + GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx); + GNUNET_free_non_null (emsg); } @@ -151,11 +130,14 @@ int main (int argc, char *argv[]) GNUNET_GETOPT_OPTION_END }; + status = GNUNET_SYSERR; if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "test_testing_new_peerstartup", "test case for peerstartup using new testing library", options, &run, NULL)) return 1; - return 0; + return (GNUNET_OK == status) ? 0 : 1; } + +/* end of test_testing_peerstartup.c */ diff --git a/src/testing/test_testing_new_portreservation.c b/src/testing/test_testing_portreservation.c index 4010944..21ef51f 100644 --- a/src/testing/test_testing_new_portreservation.c +++ b/src/testing/test_testing_portreservation.c @@ -27,12 +27,17 @@ #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_testing_lib-new.h" +#include "gnunet_testing_lib.h" #define LOG(kind,...) \ GNUNET_log (kind, __VA_ARGS__) /** + * The status of the test + */ +int status; + +/** * Main point of test execution */ static void @@ -45,16 +50,18 @@ run (void *cls, char *const *args, const char *cfgfile, uint16_t old_port1; system = GNUNET_TESTING_system_create ("/tmp/gnunet-testing-new", - "localhost"); + "localhost", NULL); GNUNET_assert (NULL != system); new_port1 = GNUNET_TESTING_reserve_port (system, GNUNET_YES); LOG (GNUNET_ERROR_TYPE_DEBUG, "Reserved TCP port %u\n", new_port1); - GNUNET_assert (0 != new_port1); + if (0 == new_port1) + goto end; new_port2 = GNUNET_TESTING_reserve_port (system, GNUNET_YES); LOG (GNUNET_ERROR_TYPE_DEBUG, "Reserved TCP port %u\n", new_port2); - GNUNET_assert (0 != new_port2); + if (0 == new_port2) + goto end; GNUNET_assert (new_port1 != new_port2); GNUNET_TESTING_release_port (system, GNUNET_YES, new_port1); old_port1 = new_port1; @@ -66,14 +73,20 @@ run (void *cls, char *const *args, const char *cfgfile, GNUNET_assert (old_port1 == new_port1); GNUNET_TESTING_release_port (system, GNUNET_YES, new_port1); GNUNET_TESTING_release_port (system, GNUNET_YES, new_port2); - GNUNET_TESTING_system_destroy (system, GNUNET_NO); + status = GNUNET_OK; + + end: + GNUNET_TESTING_system_destroy (system, GNUNET_YES); } + int main (int argc, char *argv[]) { struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; + + status = GNUNET_SYSERR; if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, @@ -83,8 +96,8 @@ int main (int argc, char *argv[]) options, &run, NULL)) - { return 1; - } - return 0; + return (GNUNET_OK == status) ? 0 : 1; } + +/* end of test_testing_portreservation.c */ diff --git a/src/testing/test_testing_reconnect.c b/src/testing/test_testing_reconnect.c deleted file mode 100644 index bcee386..0000000 --- a/src/testing/test_testing_reconnect.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - This file is part of GNUnet. - (C) 2010 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 testing/test_testing_reconnect.c - * @brief testcase for functions to connect two peers in testing.c - */ -#include "platform.h" -#include "gnunet_testing_lib.h" - -#define VERBOSE GNUNET_YES - -/** - * How long until we give up on connecting the peers? - */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) - -#define CONNECT_ATTEMPTS 3 - -static int ok; - -static struct GNUNET_TESTING_Daemon *d1; - -static struct GNUNET_TESTING_Daemon *d2; - -static struct GNUNET_CONFIGURATION_Handle *c1; - -static struct GNUNET_CONFIGURATION_Handle *c2; - -static struct GNUNET_TESTING_ConnectContext *cc; - -/** - * How many start-connect-stop iterations should we do? - */ -#define NUM_PHASES 2 - -static int phase; - -/** - * Run the next phase of starting daemons, connecting them and - * stopping them again. - */ -static void -run_phase (void); - -static void -end2_cb (void *cls, const char *emsg) -{ - - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Ending with error: %s\n", emsg); - ok = 1; - } - else - { - if (phase < NUM_PHASES) - { - FPRINTF (stderr, "%s", "."); - run_phase (); - return; - } - FPRINTF (stderr, "%s", ".\n"); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Both daemons terminated, will now exit.\n"); -#endif - ok = 0; - } -} - -static void -end1_cb (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Stopping daemon 1 gave: %s\n", - emsg); - ok = 1; - } - else - { - ok = 0; - } - if (d2 != NULL) - { - GNUNET_TESTING_daemon_stop (d2, TIMEOUT, &end2_cb, NULL, - (phase == NUM_PHASES) ? GNUNET_YES : GNUNET_NO, - GNUNET_NO); - d2 = NULL; - } -} - -static void -finish_testing (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_TESTING_daemon_stop (d1, TIMEOUT, &end1_cb, NULL, - (phase == NUM_PHASES) ? GNUNET_YES : GNUNET_NO, - GNUNET_NO); - d1 = NULL; -} - - -static void -my_connect_complete (void *cls, const struct GNUNET_PeerIdentity *first, - const struct GNUNET_PeerIdentity *second, - unsigned int 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) -{ - cc = NULL; -#if VERBOSE - FPRINTF (stderr, "Peer %s ", GNUNET_i2s (first)); - FPRINTF (stderr, "connected to %s\n", GNUNET_i2s (second)); -#endif - GNUNET_SCHEDULER_add_now (&finish_testing, NULL); -} - - - - -static void -my_cb2 (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, "Starting daemon 2 gave: %s\n", - emsg); - GNUNET_assert (0); - return; - } - GNUNET_assert (id != NULL); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Daemon `%s' started.\n", - GNUNET_i2s (id)); -#endif - cc = GNUNET_TESTING_daemons_connect (d1, d2, TIMEOUT, CONNECT_ATTEMPTS, - GNUNET_YES, &my_connect_complete, NULL); -} - - -static void -my_cb1 (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, "Starting daemon 1 gave: %s\n", - emsg); - GNUNET_assert (0); - return; - } - GNUNET_assert (id != NULL); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Daemon `%s' started.\n", - GNUNET_i2s (id)); -#endif - d2 = GNUNET_TESTING_daemon_start (c2, TIMEOUT, GNUNET_NO, NULL, NULL, 0, NULL, - NULL, NULL, &my_cb2, NULL); - GNUNET_assert (d2 != NULL); -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - ok = 1; -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemon.\n"); -#endif - c1 = GNUNET_CONFIGURATION_create (); - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_load (c1, - "test_testing_connect_peer1.conf")); - c2 = GNUNET_CONFIGURATION_create (); - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_load (c2, - "test_testing_connect_peer2.conf")); - run_phase (); -} - -static void -run_phase () -{ - phase++; - d1 = GNUNET_TESTING_daemon_start (c1, TIMEOUT, GNUNET_NO, NULL, NULL, 0, NULL, - NULL, NULL, &my_cb1, NULL); - GNUNET_assert (d1 != NULL); -} - -static int -check () -{ - char *const argv[] = { "test-testing-reconnect", - "-c", - "test_testing_data.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-testing-reconnect", "nohelp", options, &run, &ok); - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test-testing-reconnect", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); - return ret; -} - -/* end of test_testing_reconnect.c */ diff --git a/src/testing/test_testing_new_servicestartup.c b/src/testing/test_testing_servicestartup.c index 3b98688..adb7181 100644 --- a/src/testing/test_testing_new_servicestartup.c +++ b/src/testing/test_testing_servicestartup.c @@ -23,35 +23,20 @@ * @brief test case for testing service startup using new testing API * @author Sree Harsha Totakura */ - #include "platform.h" -#include "gnunet_testing_lib-new.h" +#include "gnunet_scheduler_lib.h" +#include "gnunet_testing_lib.h" #define LOG(kind,...) \ GNUNET_log (kind, __VA_ARGS__) -#define TIME_REL_SEC(sec) \ - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec) /** * Global test status */ static int test_success; -/** - * The shutdown task. Used to signal that testing is done and service has to be - * stopped - * - * @param cls NULL - */ -static void -shutdown_task(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - test_success = GNUNET_YES; - GNUNET_SCHEDULER_shutdown (); -} - /** * The testing callback function @@ -60,12 +45,14 @@ shutdown_task(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param cfg the configuration with which the current testing service is run */ static void -test_run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) +test_run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Peer *peer) { GNUNET_assert (NULL == cls); GNUNET_assert (NULL != cfg); LOG (GNUNET_ERROR_TYPE_DEBUG, "Service arm started successfully\n"); - GNUNET_SCHEDULER_add_delayed (TIME_REL_SEC (3), &shutdown_task, NULL); + test_success = GNUNET_YES; + GNUNET_SCHEDULER_shutdown (); } @@ -74,37 +61,14 @@ test_run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) */ int main (int argc, char *argv[]) { - char *_tmpdir; - char *tmpdir; -#ifdef MINGW - char *tmpdir_w; -#endif - - GNUNET_log_setup ("test_testing_new_servicestartup", "DEBUG", NULL); - _tmpdir = getenv ("TMP"); - if (NULL == _tmpdir) - _tmpdir = getenv ("TEMP"); - if (NULL == _tmpdir) - _tmpdir = getenv ("TMPDIR"); - if (NULL == _tmpdir) - _tmpdir = "/tmp"; - GNUNET_asprintf (&tmpdir, "%s/%s", _tmpdir, "test-gnunet-testing_new-XXXXXX"); -#ifdef MINGW - tmpdir_w = GNUNET_malloc (MAX_PATH + 1); - GNUNET_assert (ERROR_SUCCESS == plibc_conv_to_win_path (tmpdir, tmpdir_w)); - GNUNET_free (tmpdir); - tmpdir = tmpdir_w; - //GNUNET_assert (0 == _mktemp_s (tmpdir, strlen (tmpdir) + 1)); -#else - GNUNET_assert (mkdtemp (tmpdir) == tmpdir); -#endif - test_success = GNUNET_NO; - GNUNET_assert (0 == GNUNET_TESTING_service_run (tmpdir, + GNUNET_assert (0 == GNUNET_TESTING_service_run ("test-testing-servicestartup", "arm", "test_testing_defaults.conf", &test_run, NULL)); - GNUNET_free (tmpdir); return (GNUNET_YES == test_success) ? 0 : 1; } + +/* end of test_testing_servicestartup.c */ + diff --git a/src/testing/test_testing_topology.c b/src/testing/test_testing_topology.c deleted file mode 100644 index b216544..0000000 --- a/src/testing/test_testing_topology.c +++ /dev/null @@ -1,1220 +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 testing/test_testing_topology.c - * @brief base testcase for testing all the topologies provided - */ -#include "platform.h" -#include "gnunet_testing_lib.h" -#include "gnunet_core_service.h" -#include "gnunet_os_lib.h" - - -#define PROGRESS_BARS GNUNET_YES - -#define DELAY_FOR_LOGGING GNUNET_NO - -/** - * How long until we fail the whole testcase? - */ -#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 240) - -/** - * How long until we give up on starting the peers? - */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 500) - -#define SECONDS_PER_PEER_START 120 - -#define DEFAULT_NUM_PEERS 4 - -#define MAX_OUTSTANDING_CONNECTIONS 100 - -static float fail_percentage = 0.05; - -static int ok; - -static unsigned long long num_peers; - -struct GNUNET_TIME_Relative connect_timeout; - -static unsigned long long connect_attempts; - -static unsigned int topology_connections; - -static unsigned int total_connections; - -static unsigned int failed_connections; - -static unsigned int total_server_connections; - -static unsigned int total_messages_received; - -static unsigned int expected_messages; - -static unsigned int expected_connections; - -static unsigned long long peers_left; - -static struct GNUNET_TESTING_PeerGroup *pg; - -const struct GNUNET_CONFIGURATION_Handle *main_cfg; - -GNUNET_SCHEDULER_TaskIdentifier die_task; - -static char *dotOutFileName; - -static struct GNUNET_TIME_Relative settle_time; - -static FILE *dotOutFile; - -static char *topology_string; - -static char *blacklist_transports; - -static int transmit_ready_scheduled; - -static int transmit_ready_failed; - -static int transmit_ready_called; - -static unsigned int modnum; - -static unsigned int dotnum; - -static enum GNUNET_TESTING_Topology topology; - -static enum GNUNET_TESTING_Topology blacklist_topology = GNUNET_TESTING_TOPOLOGY_NONE; /* Don't do any blacklisting */ - -static enum GNUNET_TESTING_Topology connection_topology = GNUNET_TESTING_TOPOLOGY_NONE; /* NONE actually means connect all allowed peers */ - -static enum GNUNET_TESTING_TopologyOption connect_topology_option = - GNUNET_TESTING_TOPOLOGY_OPTION_ALL; - -static double connect_topology_option_modifier = 0.0; - -static char *test_directory; - -#define MTYPE 12345 - -GNUNET_NETWORK_STRUCT_BEGIN - -struct GNUNET_TestMessage -{ - /** - * Header of the message - */ - struct GNUNET_MessageHeader header; - - /** - * Unique identifier for this message. - */ - uint32_t uid; -}; -GNUNET_NETWORK_STRUCT_END - -struct TestMessageContext -{ - /* This is a linked list */ - struct TestMessageContext *next; - - /* Handle to the sending peer core */ - struct GNUNET_CORE_Handle *peer1handle; - - /* Handle to the receiving peer core */ - struct GNUNET_CORE_Handle *peer2handle; - - /* Handle to the sending peer daemon */ - struct GNUNET_TESTING_Daemon *peer1; - - /* Handle to the receiving peer daemon */ - struct GNUNET_TESTING_Daemon *peer2; - - /* Identifier for this message, so we don't disconnect other peers! */ - uint32_t uid; - - /* Has peer1 been notified already of a connection to peer2? */ - int peer1notified; - - /* Has the core of peer2 been connected already? */ - int peer2connected; - - /* Task for disconnecting cores, allow task to be cancelled on shutdown */ - GNUNET_SCHEDULER_TaskIdentifier disconnect_task; - -}; - -static struct TestMessageContext *test_messages; - -/** - * Check whether peers successfully shut down. - */ -static void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Shutdown of peers failed: %s!\n", - emsg); - if (ok == 0) - ok = 666; - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); - } -} - - -#if DELAY_FOR_LOGGING -static void -gather_log_data () -{ - char *peer_number; - char *connect_number; - struct GNUNET_OS_Process *mem_process; - - GNUNET_asprintf (&peer_number, "%llu", num_peers); - GNUNET_asprintf (&connect_number, "%llu", expected_connections); - mem_process = - GNUNET_OS_start_process (NULL, NULL, "./memsize.pl", "memsize.pl", - "totals.txt", peer_number, connect_number, NULL); - GNUNET_OS_process_wait (mem_process); - GNUNET_OS_process_destroy (mem_process); - mem_process = NULL; -} -#endif - - -static void -finish_testing () -{ - GNUNET_assert (pg != NULL); - struct TestMessageContext *pos; - struct TestMessageContext *free_pos; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Called finish testing, stopping daemons.\n"); - pos = test_messages; - while (pos != NULL) - { - if (pos->peer1handle != NULL) - { - GNUNET_CORE_disconnect (pos->peer1handle); - pos->peer1handle = NULL; - } - if (pos->peer2handle != NULL) - { - GNUNET_CORE_disconnect (pos->peer2handle); - pos->peer2handle = NULL; - } - free_pos = pos; - pos = pos->next; - if (free_pos->disconnect_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (free_pos->disconnect_task); - } - GNUNET_free (free_pos); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Transmit_ready's scheduled %d, failed %d, transmit_ready's called %d\n", - transmit_ready_scheduled, transmit_ready_failed, - transmit_ready_called); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Calling daemons_stop\n"); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - - if (dotOutFile != NULL) - { - FPRINTF (dotOutFile, "%s", "}"); - FCLOSE (dotOutFile); - } - ok = 0; -} - - -static void -disconnect_cores (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct TestMessageContext *pos = cls; - - /* Disconnect from the respective cores */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from peer 1 `%4s'\n", - GNUNET_i2s (&pos->peer1->id)); - if (pos->peer1handle != NULL) - { - GNUNET_CORE_disconnect (pos->peer1handle); - pos->peer1handle = NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from peer 2 `%4s'\n", - GNUNET_i2s (&pos->peer2->id)); - if (pos->peer2handle != NULL) - { - GNUNET_CORE_disconnect (pos->peer2handle); - pos->peer2handle = NULL; - } - pos->disconnect_task = GNUNET_SCHEDULER_NO_TASK; - /* Decrement total connections so new can be established */ - total_server_connections -= 2; -} - -#if DO_STATS -static void -stats_finished (void *cls, int result) -{ - GNUNET_SCHEDULER_add_now (&finish_testing, NULL); -} - -/** - * Callback function to process statistic values. - * - * @param cls closure - * @param peer the peer the statistics 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 -stats_print (void *cls, const struct GNUNET_PeerIdentity *peer, - const char *subsystem, const char *name, uint64_t value, - int is_persistent) -{ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s:%s:%s -- %llu\n", GNUNET_i2s (peer), - subsystem, name, value); - return GNUNET_OK; -} -#endif - - -static void -topology_cb (void *cls, const struct GNUNET_PeerIdentity *first, - const struct GNUNET_PeerIdentity *second, const char *emsg) -{ - FILE *outfile = cls; - - if (first != NULL) - { - if (outfile != NULL) - { - FPRINTF (outfile, "\t\"%s\" -- ", GNUNET_i2s (first)); - FPRINTF (outfile, "\"%s\";\n", GNUNET_i2s (second)); - } - topology_connections++; - } - else - { - FPRINTF (stderr, - "Finished iterating over topology, %d total connections!\n", - topology_connections); - if (outfile != NULL) - { - FPRINTF (outfile, "%s", "}\n"); - FCLOSE (outfile); -#if DO_STATS - GNUNET_TESTING_get_statistics (pg, &stats_finished, &stats_print, NULL); -#endif - GNUNET_SCHEDULER_add_now (&finish_testing, NULL); - } - } -} - - -static int -process_mtype (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_MessageHeader *message, - const struct GNUNET_ATS_Information *atsi, - unsigned int atsi_count) -{ - char *dotOutFileNameFinished; - FILE *dotOutFileFinished; - struct TestMessageContext *pos = cls; - struct GNUNET_TestMessage *msg = (struct GNUNET_TestMessage *) message; - - if (pos->uid != ntohl (msg->uid)) - return GNUNET_OK; - -#if PROGRESS_BARS - if ((total_messages_received) % modnum == 0) - { - if (total_messages_received == 0) - FPRINTF (stdout, "%s", "0%%"); - else - FPRINTF (stdout, "%d%%", - (int) (((float) total_messages_received / expected_messages) * - 100)); - - } - else if (total_messages_received % dotnum == 0) - { - FPRINTF (stdout, "%s", "."); - } - fflush (stdout); -#endif - - total_messages_received++; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received message from `%4s', type %d.\n", GNUNET_i2s (peer), - ntohs (message->type)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Total messages received %d, expected %d.\n", - total_messages_received, expected_messages); - - if (total_messages_received == expected_messages) - { -#if PROGRESS_BARS - FPRINTF (stdout, "%s", "100%%]\n"); -#endif - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_asprintf (&dotOutFileNameFinished, "%s.dot", "final_topology"); - dotOutFileFinished = FOPEN (dotOutFileNameFinished, "w"); - GNUNET_free (dotOutFileNameFinished); - if (dotOutFileFinished != NULL) - { - FPRINTF (dotOutFileFinished, "%s", "strict graph G {\n"); - } - topology_connections = 0; - GNUNET_TESTING_get_topology (pg, &topology_cb, dotOutFileFinished); - //GNUNET_SCHEDULER_add_now (&finish_testing, NULL); - } - else - { - pos->disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cores, pos); - } - - return GNUNET_OK; -} - - -static void -end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - char *msg = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Ending with error: %s\n", msg); - struct TestMessageContext *pos; - struct TestMessageContext *free_pos; - - pos = test_messages; - while (pos != NULL) - { - if (pos->peer1handle != NULL) - { - GNUNET_CORE_disconnect (pos->peer1handle); - pos->peer1handle = NULL; - } - if (pos->peer2handle != NULL) - { - GNUNET_CORE_disconnect (pos->peer2handle); - pos->peer2handle = NULL; - } - free_pos = pos; - pos = pos->next; - GNUNET_free (free_pos); - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Transmit_ready's scheduled %d, failed %d, transmit_ready's called %d\n", - transmit_ready_scheduled, transmit_ready_failed, - transmit_ready_called); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Total messages received %d, expected %d.\n", - total_messages_received, expected_messages); - - if (pg != NULL) - { - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - ok = 7331; /* Opposite of leet */ - } - else - ok = 401; /* Never got peers started */ - - if (dotOutFile != NULL) - { - FPRINTF (dotOutFile, "%s", "}"); - FCLOSE (dotOutFile); - } -} - - -static size_t -transmit_ready (void *cls, size_t size, void *buf) -{ - struct GNUNET_TestMessage *m; - struct TestMessageContext *pos = cls; - - GNUNET_assert (buf != NULL); - m = (struct GNUNET_TestMessage *) buf; - m->header.type = htons (MTYPE); - m->header.size = htons (sizeof (struct GNUNET_TestMessage)); - m->uid = htonl (pos->uid); - transmit_ready_called++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "transmit ready for peer %s\ntransmit_ready's scheduled %d, transmit_ready's called %d\n", - GNUNET_i2s (&pos->peer1->id), transmit_ready_scheduled, - transmit_ready_called); - return sizeof (struct GNUNET_TestMessage); -} - - -static struct GNUNET_CORE_MessageHandler no_handlers[] = { - {NULL, 0, 0} -}; - - -static struct GNUNET_CORE_MessageHandler handlers[] = { - {&process_mtype, MTYPE, sizeof (struct GNUNET_TestMessage)}, - {NULL, 0, 0} -}; - - -static void -init_notify_peer2 (void *cls, struct GNUNET_CORE_Handle *server, - const struct GNUNET_PeerIdentity *my_identity) -{ - struct TestMessageContext *pos = cls; - - total_server_connections++; - - pos->peer2connected = GNUNET_YES; - if (pos->peer1notified == GNUNET_YES) /* Peer 1 has been notified of connection to peer 2 */ - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Scheduling message send to peer `%s' from peer `%s' (init_notify_peer2)\n", - GNUNET_i2s (my_identity), - GNUNET_h2s (&pos->peer1->id.hashPubKey)); - if (NULL == - GNUNET_CORE_notify_transmit_ready (pos->peer1handle, GNUNET_YES, 0, - TIMEOUT, &pos->peer2->id, - sizeof (struct GNUNET_TestMessage), - &transmit_ready, pos)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "RECEIVED NULL when asking core (1) for transmission to peer `%4s'\n", - GNUNET_i2s (&pos->peer2->id)); - transmit_ready_failed++; - } - else - { - transmit_ready_scheduled++; - } - } -} - - -/** - * Method called whenever a given peer connects. - * - * @param cls closure - * @param peer peer identity this notification is about - * @param atsi performance data for the connection - * @param atsi_count number of records in 'atsi' - */ -static void -connect_notify_peers (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_ATS_Information *atsi, - unsigned int atsi_count) -{ - struct TestMessageContext *pos = cls; - - if (0 == memcmp (peer, &pos->peer2->id, sizeof (struct GNUNET_PeerIdentity))) - { - pos->peer1notified = GNUNET_YES; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peer `%s' notified of connection to peer `%s'\n", - GNUNET_i2s (&pos->peer1->id), GNUNET_h2s (&peer->hashPubKey)); - } - else - return; - - if (pos->peer2connected == GNUNET_YES) /* Already connected and notified of connection, send message! */ - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Scheduling message send to peer `%s' from peer `%s' (init_notify_peer2)\n", - GNUNET_i2s (&pos->peer2->id), - GNUNET_h2s (&pos->peer1->id.hashPubKey)); - if (NULL == - GNUNET_CORE_notify_transmit_ready (pos->peer1handle, GNUNET_YES, 0, - TIMEOUT, &pos->peer2->id, - sizeof (struct GNUNET_TestMessage), - &transmit_ready, pos)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "RECEIVED NULL when asking core (1) for transmission to peer `%4s'\n", - GNUNET_i2s (&pos->peer2->id)); - transmit_ready_failed++; - } - else - { - transmit_ready_scheduled++; - } - } -} - - -static void -init_notify_peer1 (void *cls, struct GNUNET_CORE_Handle *server, - const struct GNUNET_PeerIdentity *my_identity) -{ - struct TestMessageContext *pos = cls; - - total_server_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Core connection to `%4s' established, setting up handles\n", - GNUNET_i2s (my_identity)); - /* - * Connect to the receiving peer - */ - pos->peer2handle = - GNUNET_CORE_connect (pos->peer2->cfg, 1, pos, &init_notify_peer2, NULL, - NULL, NULL, GNUNET_YES, NULL, GNUNET_YES, handlers); - -} - - -static void -send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct TestMessageContext *pos = cls; - - if ((pos == test_messages) && (settle_time.rel_value > 0)) - { - topology_connections = 0; - GNUNET_TESTING_get_topology (pg, &topology_cb, NULL); - } - if (((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) || (cls == NULL)) - return; - - if (die_task == GNUNET_SCHEDULER_NO_TASK) - { - die_task = - GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, &end_badly, - "from send test messages (timeout)"); - } - - if (total_server_connections >= MAX_OUTSTANDING_CONNECTIONS) - { - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 1), - &send_test_messages, pos); - return; /* Otherwise we'll double schedule messages here! */ - } - - /* - * Connect to the sending peer - */ - pos->peer1handle = - GNUNET_CORE_connect (pos->peer1->cfg, 1, pos, &init_notify_peer1, - &connect_notify_peers, NULL, NULL, GNUNET_NO, NULL, - GNUNET_NO, no_handlers); - - GNUNET_assert (pos->peer1handle != NULL); - - if (total_server_connections < MAX_OUTSTANDING_CONNECTIONS) - { - GNUNET_SCHEDULER_add_now (&send_test_messages, pos->next); - } - else - { - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 1), - &send_test_messages, pos->next); - } -} - - -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) -{ - struct TestMessageContext *temp_context; - - if (emsg == NULL) - { -#if PROGRESS_BARS - if ((total_connections) % modnum == 0) - { - if (total_connections == 0) - FPRINTF (stdout, "%s", "0%%"); - else - FPRINTF (stdout, "%d%%", - (int) (((float) total_connections / expected_connections) * - 100)); - - } - else if (total_connections % dotnum == 0) - { - FPRINTF (stdout, "%s", "."); - } - fflush (stdout); -#endif - total_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "connected peer %s to peer %s\n", - first_daemon->shortname, second_daemon->shortname); - temp_context = GNUNET_malloc (sizeof (struct TestMessageContext)); - temp_context->peer1 = first_daemon; - temp_context->peer2 = second_daemon; - temp_context->next = test_messages; - temp_context->uid = total_connections; - temp_context->disconnect_task = GNUNET_SCHEDULER_NO_TASK; - test_messages = temp_context; - - expected_messages++; - if (dotOutFile != NULL) - FPRINTF (dotOutFile, "\tn%s -- n%s;\n", first_daemon->shortname, - second_daemon->shortname); - } - else - { - failed_connections++; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "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) - { -#if PROGRESS_BARS - FPRINTF (stdout, "%s", "100%%]\n"); -#endif - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Created %d total connections, which is our target number! Calling send messages.\n", - total_connections); - modnum = expected_messages / 4; - dotnum = (expected_messages / 50) + 1; - if (modnum == 0) - modnum = 1; - if (dotnum == 0) - dotnum = 1; - GNUNET_SCHEDULER_cancel (die_task); - die_task = GNUNET_SCHEDULER_NO_TASK; -#if DELAY_FOR_LOGGING - FPRINTF (stdout, "%s", "Sending test messages in 10 seconds.\n"); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 10), - &send_test_messages, test_messages); - gather_log_data (); -#else - if (settle_time.rel_value > 0) - { - GNUNET_TESTING_get_topology (pg, &topology_cb, NULL); - } - GNUNET_SCHEDULER_add_delayed (settle_time, &send_test_messages, - test_messages); -#endif -#if PROGRESS_BARS - FPRINTF (stdout, "%s", "Test message progress: ["); -#endif - - } - else if (total_connections + failed_connections == expected_connections) - { - if (failed_connections < - (unsigned int) (fail_percentage * total_connections)) - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_SCHEDULER_add_now (&send_test_messages, test_messages); - } - else - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from topology_callback (too many failed connections)"); - } - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Have %d total connections, %d failed connections, Want %d (at least %d)\n", - total_connections, failed_connections, expected_connections, - expected_connections - - (unsigned int) (fail_percentage * expected_connections)); - } -} - - -static void -topology_creation_finished (void *cls, const char *emsg) -{ - if (emsg == NULL) - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All topology connections created successfully!\n"); -} - - -static void -connect_topology () -{ - expected_connections = -1; - if ((pg != NULL) && (peers_left == 0)) - { - expected_connections = - GNUNET_TESTING_connect_topology (pg, connection_topology, - connect_topology_option, - connect_topology_option_modifier, - connect_timeout, connect_attempts, - &topology_creation_finished, NULL); -#if PROGRESS_BARS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have %d expected connections\n", - expected_connections); -#endif - } - - GNUNET_SCHEDULER_cancel (die_task); - if (expected_connections < 1) - { - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from connect topology (bad return)"); - return; - } - - die_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, - SECONDS_PER_PEER_START * num_peers), - &end_badly, - "from connect topology (timeout)"); - modnum = expected_connections / 4; - dotnum = (expected_connections / 50) + 1; - if (modnum == 0) - modnum = 1; - if (dotnum == 0) - dotnum = 1; -#if PROGRESS_BARS - FPRINTF (stdout, "%s", "Peer connection progress: ["); -#endif -} - -static void -create_topology () -{ - peers_left = num_peers; /* Reset counter */ - if (GNUNET_TESTING_create_topology - (pg, topology, blacklist_topology, blacklist_transports) != GNUNET_SYSERR) - { -#if PROGRESS_BARS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Topology set up, now starting peers!\n"); - FPRINTF (stdout, "%s", "Daemon start progress ["); -#endif - GNUNET_TESTING_daemons_continue_startup (pg); - } - else - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from create topology (bad return)"); - } - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, - SECONDS_PER_PEER_START * num_peers), - &end_badly, - "from continue startup (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) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to start daemon with error: `%s'\n", emsg); - return; - } - GNUNET_assert (id != NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n", - (num_peers - peers_left) + 1, num_peers); -#if PROGRESS_BARS - if ((num_peers - peers_left) % modnum == 0) - { - if (num_peers - peers_left == 0) - FPRINTF (stdout, "%s", "0%%"); - else - FPRINTF (stdout, "%d%%", - (int) (((float) (num_peers - peers_left) / num_peers) * 100)); - - } - else if ((num_peers - peers_left) % dotnum == 0) - { - FPRINTF (stdout, "%s", "."); - } - fflush (stdout); -#endif - peers_left--; - if (peers_left == 0) - { -#if PROGRESS_BARS - FPRINTF (stdout, "%s", "100%%]\n"); -#endif - 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 (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MINUTES, 8), &end_badly, - "from peers_started_callback"); -#if DELAY_FOR_LOGGING - FPRINTF (stdout, "%s", "Connecting topology in 10 seconds\n"); - gather_log_data (); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 10), - &connect_topology, NULL); -#else - connect_topology (); -#endif - ok = 0; - } -} - -/** - * Callback indicating that the hostkey was created for a peer. - * - * @param cls NULL - * @param id the peer identity - * @param d the daemon handle (pretty useless at this point, remove?) - * @param emsg non-null on failure - */ -void -hostkey_callback (void *cls, const struct GNUNET_PeerIdentity *id, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Hostkey callback received error: %s\n", emsg); - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Hostkey (%d/%d) created for peer `%s'\n", num_peers - peers_left, - num_peers, GNUNET_i2s (id)); -#if PROGRESS_BARS - if ((num_peers - peers_left) % modnum == 0) - { - if (num_peers - peers_left == 0) - FPRINTF (stdout, "%s", "0%%"); - else - FPRINTF (stdout, "%d%%", - (int) (((float) (num_peers - peers_left) / num_peers) * 100)); - - } - else if ((num_peers - peers_left) % dotnum == 0) - { - FPRINTF (stdout, "%s", "."); - } - fflush (stdout); -#endif - peers_left--; - if (peers_left == 0) - { -#if PROGRESS_BARS - FPRINTF (stdout, "%s", "100%%]\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All %d hostkeys created, now creating topology!\n", num_peers); -#endif - 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 create_topology"); - GNUNET_SCHEDULER_add_now (&create_topology, NULL); - ok = 0; - } -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - char *topology_str; - char *connect_topology_str; - char *blacklist_topology_str; - char *connect_topology_option_str; - char *connect_topology_option_modifier_string; - unsigned long long max_outstanding_connections; - - ok = 1; - - dotOutFile = FOPEN (dotOutFileName, "w"); - if (dotOutFile != NULL) - { - FPRINTF (dotOutFile, "%s", "strict graph G {\n"); - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting daemons based on config file %s\n", cfgfile); - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", - &test_directory)) - { - ok = 404; - return; - } - - if ((GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "topology", - &topology_str)) && - (GNUNET_NO == GNUNET_TESTING_topology_get (&topology, topology_str))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid topology `%s' given for section %s option %s\n", - topology_str, "TESTING", "TOPOLOGY"); - topology = GNUNET_TESTING_TOPOLOGY_CLIQUE; /* Defaults to NONE, so set better default here */ - } - - if ((GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "connect_topology", - &connect_topology_str)) && - (GNUNET_NO == - GNUNET_TESTING_topology_get (&connection_topology, - connect_topology_str))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid connect topology `%s' given for section %s option %s\n", - connect_topology_str, "TESTING", "CONNECT_TOPOLOGY"); - } - GNUNET_free_non_null (connect_topology_str); - if ((GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "connect_topology_option", - &connect_topology_option_str)) && - (GNUNET_NO == - GNUNET_TESTING_topology_option_get (&connect_topology_option, - connect_topology_option_str))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid connect topology option `%s' given for section %s option %s\n", - connect_topology_option_str, "TESTING", - "CONNECT_TOPOLOGY_OPTION"); - connect_topology_option = GNUNET_TESTING_TOPOLOGY_OPTION_ALL; /* Defaults to NONE, set to ALL */ - } - GNUNET_free_non_null (connect_topology_option_str); - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "connect_topology_option_modifier", - &connect_topology_option_modifier_string)) - { - if (SSCANF - (connect_topology_option_modifier_string, "%lf", - &connect_topology_option_modifier) != 1) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), - connect_topology_option_modifier_string, - "connect_topology_option_modifier", "TESTING"); - } - GNUNET_free (connect_topology_option_modifier_string); - } - - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "blacklist_transports", - &blacklist_transports)) - blacklist_transports = NULL; - - if ((GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "blacklist_topology", - &blacklist_topology_str)) && - (GNUNET_NO == - GNUNET_TESTING_topology_get (&blacklist_topology, - blacklist_topology_str))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid topology `%s' given for section %s option %s\n", - topology_str, "TESTING", "BLACKLIST_TOPOLOGY"); - } - GNUNET_free_non_null (topology_str); - GNUNET_free_non_null (blacklist_topology_str); - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "SETTLE_TIME", - &settle_time)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "SETTLE_TIME"); - return; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "CONNECT_TIMEOUT", - &connect_timeout)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "CONNECT_TIMEOUT"); - return; - } - - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "connect_attempts", - &connect_attempts)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "connect_attempts"); - return; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", - "max_outstanding_connections", - &max_outstanding_connections)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "max_outstanding_connections"); - return; - } - - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", - &num_peers)) - num_peers = DEFAULT_NUM_PEERS; - - main_cfg = cfg; - - peers_left = num_peers; - modnum = num_peers / 4; - dotnum = (num_peers / 50) + 1; - if (modnum == 0) - modnum = 1; - if (dotnum == 0) - dotnum = 1; -#if PROGRESS_BARS - FPRINTF (stdout, "%s", "Hostkey generation progress: ["); -#endif - /* Set up a task to end testing if peer start fails */ - die_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, - SECONDS_PER_PEER_START * num_peers), - &end_badly, - "didn't generate all hostkeys within a reasonable amount of time!!!"); - - GNUNET_assert (num_peers > 0 && num_peers < (unsigned int) -1); - pg = GNUNET_TESTING_daemons_start (cfg, peers_left, - max_outstanding_connections, peers_left, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, - SECONDS_PER_PEER_START * num_peers), - &hostkey_callback, NULL, - &peers_started_callback, NULL, - &topology_callback, NULL, NULL); - -} - - -static int -check () -{ - char *binary_name; - char *config_file_name; - - GNUNET_asprintf (&binary_name, "test-testing-topology-%s", topology_string); - GNUNET_asprintf (&config_file_name, "test_testing_data_topology_%s.conf", - topology_string); - int ret; - - char *const argv[] = { binary_name, - "-c", - config_file_name, - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - ret = - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - binary_name, "nohelp", options, &run, &ok); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "`test-testing-topology-%s': Failed with error code %d\n", - topology_string, ret); - } - GNUNET_free (binary_name); - GNUNET_free (config_file_name); - return ok; -} - - -int -main (int argc, char *argv[]) -{ - int ret; - char *binary_start_pos; - char *our_binary_name; - char *dotexe; - - binary_start_pos = strchr (argv[0], '/'); - GNUNET_assert (binary_start_pos != NULL); - topology_string = strstr (binary_start_pos, "_topology"); - GNUNET_assert (topology_string != NULL); - topology_string++; - topology_string = strstr (topology_string, "_"); - GNUNET_assert (topology_string != NULL); - topology_string++; - topology_string = GNUNET_strdup (topology_string); - if (NULL != (dotexe = strstr (topology_string, ".exe"))) - dotexe[0] = '\0'; - GNUNET_asprintf (&our_binary_name, "test-testing-topology_%s", - topology_string); - GNUNET_asprintf (&dotOutFileName, "topology_%s.dot", topology_string); - - GNUNET_log_setup (our_binary_name, - "WARNING", - NULL); - ret = check (); - GNUNET_free (topology_string); - - /** - * 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); - } - GNUNET_free (our_binary_name); - return ret; -} - -/* end of test_testing_topology.c */ diff --git a/src/testing/test_testing_topology_blacklist.c b/src/testing/test_testing_topology_blacklist.c deleted file mode 100644 index c90f48d..0000000 --- a/src/testing/test_testing_topology_blacklist.c +++ /dev/null @@ -1,595 +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 testing/test_testing_topology_blacklist.c - * @brief base testcase for testing transport level blacklisting - */ -#include "platform.h" -#include "gnunet_testing_lib.h" -#include "gnunet_core_service.h" - -#define VERBOSE GNUNET_NO - -/** - * How long until we fail the whole testcase? - */ -#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600) - -/** - * How long until we give up on starting the peers? (Must be longer than the connect timeout!) - */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) - -#define DEFAULT_NUM_PEERS 4 - -#define MAX_OUTSTANDING_CONNECTIONS 300 - -static int ok; - -struct GNUNET_TIME_Relative connect_timeout; - -static unsigned long long connect_attempts; - -static unsigned long long num_peers; - -static unsigned int total_connections; - -static unsigned int failed_connections; - -static unsigned int expected_connections; - -static unsigned int expected_failed_connections; - -static unsigned long long peers_left; - -static struct GNUNET_TESTING_PeerGroup *pg; - -const struct GNUNET_CONFIGURATION_Handle *main_cfg; - -GNUNET_SCHEDULER_TaskIdentifier die_task; - -static char *dotOutFileName; - -static FILE *dotOutFile; - -static char *blacklist_transports; - -static enum GNUNET_TESTING_Topology topology = GNUNET_TESTING_TOPOLOGY_CLIQUE; /* Overlay should allow all connections */ - -static enum GNUNET_TESTING_Topology blacklist_topology = GNUNET_TESTING_TOPOLOGY_RING; /* Blacklist underlay into a ring */ - -static enum GNUNET_TESTING_Topology connection_topology = GNUNET_TESTING_TOPOLOGY_NONE; /* NONE actually means connect all allowed peers */ - -static enum GNUNET_TESTING_TopologyOption connect_topology_option = GNUNET_TESTING_TOPOLOGY_OPTION_ALL; /* Try to connect all possible OVERLAY connections */ - -static double connect_topology_option_modifier = 0.0; - -static char *test_directory; - -#define MTYPE 12345 - -GNUNET_NETWORK_STRUCT_BEGIN - -struct GNUNET_TestMessage -{ - /** - * Header of the message - */ - struct GNUNET_MessageHeader header; - - /** - * Unique identifier for this message. - */ - uint32_t uid; -}; -GNUNET_NETWORK_STRUCT_END - -/** - * Check whether peers successfully shut down. - */ -void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed!\n"); -#endif - if (ok == 0) - ok = 666; - } - else - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); -#endif - } -} - -static void -finish_testing () -{ - GNUNET_assert (pg != NULL); - -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Called finish testing, stopping daemons.\n"); -#endif - sleep (1); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Calling daemons_stop\n"); -#endif - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "daemons_stop finished\n"); -#endif - if (dotOutFile != NULL) - { - FPRINTF (dotOutFile, "%s", "}"); - FCLOSE (dotOutFile); - } - - ok = 0; -} - -static void -end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - char *msg = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "End badly was called (%s)... stopping daemons.\n", msg); - - if (pg != NULL) - { - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - ok = 7331; /* Opposite of leet */ - } - else - ok = 401; /* Never got peers started */ - - if (dotOutFile != NULL) - { - FPRINTF (dotOutFile, "%s", "}"); - FCLOSE (dotOutFile); - } -} - - - -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\n", - first_daemon->shortname, second_daemon->shortname); -#endif - if (dotOutFile != NULL) - FPRINTF (dotOutFile, "\tn%s -- n%s;\n", first_daemon->shortname, - second_daemon->shortname); - } - - else - { - failed_connections++; -#if VERBOSE - 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 (that's bad)!\n", - total_connections); -#endif - - GNUNET_SCHEDULER_cancel (die_task); - die_task = GNUNET_SCHEDULER_NO_TASK; - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from topology_callback (too many successful connections)"); - } - else if (total_connections + failed_connections == expected_connections) - { - if ((failed_connections == expected_failed_connections) && - (total_connections == - expected_connections - expected_failed_connections)) - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = GNUNET_SCHEDULER_NO_TASK; - die_task = GNUNET_SCHEDULER_add_now (&finish_testing, NULL); - } - else - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from topology_callback (wrong number of failed connections)"); - } - } - else - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Have %d total connections, %d failed connections, Want %d (failed) and %d (successful)\n", - total_connections, failed_connections, - expected_failed_connections, - expected_connections - expected_failed_connections); -#endif - } -} - -static void -connect_topology () -{ - expected_connections = -1; - if ((pg != NULL) && (peers_left == 0)) - { - expected_connections = - GNUNET_TESTING_connect_topology (pg, connection_topology, - connect_topology_option, - connect_topology_option_modifier, - connect_timeout, connect_attempts, - NULL, NULL); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have %d expected connections\n", - expected_connections); -#endif - } - - GNUNET_SCHEDULER_cancel (die_task); - if (expected_connections == GNUNET_SYSERR) - { - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from connect topology (bad return)"); - } - - die_task = - GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, &end_badly, - "from connect topology (timeout)"); -} - -static void -create_topology () -{ - peers_left = num_peers; /* Reset counter */ - if (GNUNET_TESTING_create_topology - (pg, topology, blacklist_topology, blacklist_transports) != GNUNET_SYSERR) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Topology set up, now starting peers!\n"); -#endif - GNUNET_TESTING_daemons_continue_startup (pg); - } - else - { - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_now (&end_badly, - "from create topology (bad return)"); - } - GNUNET_SCHEDULER_cancel (die_task); - die_task = - GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, &end_badly, - "from continue startup (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) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to start daemon with error: `%s'\n", emsg); - return; - } - GNUNET_assert (id != NULL); -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n", - (num_peers - peers_left) + 1, num_peers); -#endif - peers_left--; - if (peers_left == 0) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All %d daemons started, now creating topology!\n", num_peers); -#endif - 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 (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MINUTES, 5), &end_badly, - "from peers_started_callback"); - connect_topology (); - ok = 0; - } -} - -/** - * Callback indicating that the hostkey was created for a peer. - * - * @param cls NULL - * @param id the peer identity - * @param d the daemon handle (pretty useless at this point, remove?) - * @param emsg non-null on failure - */ -void -hostkey_callback (void *cls, const struct GNUNET_PeerIdentity *id, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Hostkey callback received error: %s\n", emsg); - } - -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostkey created for peer `%s'\n", - GNUNET_i2s (id)); -#endif - peers_left--; - if (peers_left == 0) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All %d hostkeys created, now creating topology!\n", num_peers); -#endif - 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 (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MINUTES, 5), &end_badly, - "from hostkey_callback"); - GNUNET_SCHEDULER_add_now (&create_topology, NULL); - ok = 0; - } -} - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - unsigned long long topology_num; - unsigned long long connect_topology_num; - unsigned long long blacklist_topology_num; - unsigned long long connect_topology_option_num; - char *connect_topology_option_modifier_string; - - ok = 1; - - dotOutFile = FOPEN (dotOutFileName, "w"); - if (dotOutFile != NULL) - { - FPRINTF (dotOutFile, "%s", "strict graph G {\n"); - } - -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting daemons based on config file %s\n", cfgfile); -#endif - - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", - &test_directory)) - { - ok = 404; - if (dotOutFile != NULL) - { - FCLOSE (dotOutFile); - } - return; - } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "topology", - &topology_num)) - topology = topology_num; - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "connect_topology", - &connect_topology_num)) - connection_topology = connect_topology_num; - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", - "connect_topology_option", - &connect_topology_option_num)) - connect_topology_option = connect_topology_option_num; - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "connect_topology_option_modifier", - &connect_topology_option_modifier_string)) - { - if (SSCANF - (connect_topology_option_modifier_string, "%lf", - &connect_topology_option_modifier) != 1) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), - connect_topology_option_modifier_string, - "connect_topology_option_modifier", "TESTING"); - GNUNET_free (connect_topology_option_modifier_string); - ok = 707; - if (dotOutFile != NULL) - { - FCLOSE (dotOutFile); - } - return; - } - GNUNET_free (connect_topology_option_modifier_string); - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "blacklist_transports", - &blacklist_transports)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "No transports specified for blacklisting in blacklist testcase (this shouldn't happen!)\n"); - ok = 808; - if (dotOutFile != NULL) - { - FCLOSE (dotOutFile); - } - return; - } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", - "blacklist_topology", - &blacklist_topology_num)) - blacklist_topology = blacklist_topology_num; - - if (GNUNET_SYSERR == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers", - &num_peers)) - num_peers = DEFAULT_NUM_PEERS; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "CONNECT_TIMEOUT", - &connect_timeout)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "CONNECT_TIMEOUT"); - return; - } - - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "connect_attempts", - &connect_attempts)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "connect_attempts"); - return; - } - - main_cfg = cfg; - - GNUNET_assert (num_peers > 0 && num_peers < (unsigned int) -1); - peers_left = num_peers; - - /* For this specific test we only really want a CLIQUE topology as the - * overlay allowed topology, and a RING topology as the underlying connection - * allowed topology. So we will expect only num_peers * 2 connections to - * work, and (num_peers * (num_peers - 1)) - (num_peers * 2) to fail. - */ - expected_connections = num_peers * (num_peers - 1); - expected_failed_connections = expected_connections - (num_peers * 2); - - - /* Set up a task to end testing if peer start fails */ - die_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MINUTES, 5), &end_badly, - "didn't start all daemons in reasonable amount of time!!!"); - - pg = GNUNET_TESTING_daemons_start (cfg, peers_left, peers_left, peers_left, - TIMEOUT, &hostkey_callback, NULL, - &peers_started_callback, NULL, - &topology_callback, NULL, NULL); - -} - -static int -check () -{ - int ret; - - char *const argv[] = { "test-testing-topology-blacklist", - "-c", - "test_testing_data_topology_blacklist.conf", -#if VERBOSE - "-L", "DEBUG", -#endif - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - ret = - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-testing-topology-blacklist", "nohelp", options, - &run, &ok); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "`test-testing-topology-blacklist': Failed with error code %d\n", - ret); - } - - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test_testing_topology_blacklist", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - ret = check (); - - /** - * Need to remove base directory, subdirectories taken care - * of by the testing framework. - */ - if (test_directory != NULL) - { - 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_testing_topology_blacklist.c */ diff --git a/src/testing/test_testing_topology_churn.c b/src/testing/test_testing_topology_churn.c deleted file mode 100644 index 9c0bbf2..0000000 --- a/src/testing/test_testing_topology_churn.c +++ /dev/null @@ -1,322 +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 testing/test_testing_topology_churn.c - * @brief base testcase for testing simple churn functionality - */ -#include "platform.h" -#include "gnunet_testing_lib.h" -#include "gnunet_core_service.h" - - -/** - * How long until we fail the whole testcase? - */ -#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600) - -/** - * How long until we give up on starting the peers? (Must be longer than the connect timeout!) - */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) - -#define DEFAULT_NUM_PEERS 4 - -static int ok; - -static unsigned long long num_peers; - -static unsigned int expected_connections; - -static unsigned int expected_failed_connections; - -static unsigned long long peers_left; - -static struct GNUNET_TESTING_PeerGroup *pg; - -const struct GNUNET_CONFIGURATION_Handle *main_cfg; - -GNUNET_SCHEDULER_TaskIdentifier die_task; - -static char *test_directory; - -#define MTYPE 12345 - -GNUNET_NETWORK_STRUCT_BEGIN - -struct GNUNET_TestMessage -{ - /** - * Header of the message - */ - struct GNUNET_MessageHeader header; - - /** - * Unique identifier for this message. - */ - uint32_t uid; -}; -GNUNET_NETWORK_STRUCT_END - -/** - * Check whether peers successfully shut down. - */ -void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown of peers failed!\n"); - if (ok == 0) - ok = 666; - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "All peers successfully shut down!\n"); - } -} - -static void -finish_testing () -{ - GNUNET_assert (pg != NULL); - - if (die_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (die_task); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Called finish testing, stopping daemons.\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Calling daemons_stop\n"); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "daemons_stop finished\n"); - ok = 0; -} - -static void -end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - char *msg = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "End badly was called (%s)... stopping daemons.\n", msg); - - if (pg != NULL) - { - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - ok = 7331; /* Opposite of leet */ - } - else - ok = 401; /* Never got peers started */ - -} - -struct ChurnTestContext -{ - GNUNET_SCHEDULER_Task next_task; - -}; - -static struct ChurnTestContext churn_ctx; - -/** - * Churn callback, report on success or failure of churn operation. - * - * @param cls closure - * @param emsg NULL on success - */ -void -churn_callback (void *cls, const char *emsg) -{ - if (emsg == NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Successfully churned peers!\n", - emsg); - GNUNET_SCHEDULER_add_now (churn_ctx.next_task, NULL); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to churn peers with error `%s'\n", emsg); - GNUNET_SCHEDULER_cancel (die_task); - die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL); - } -} - - -static void -churn_peers_both () -{ - churn_ctx.next_task = &finish_testing; - GNUNET_TESTING_daemons_churn (pg, NULL, 1, 1, TIMEOUT, &churn_callback, NULL); -} - -static void -churn_peers_off_again () -{ - churn_ctx.next_task = &churn_peers_both; - GNUNET_TESTING_daemons_churn (pg, NULL, 2, 0, TIMEOUT, &churn_callback, NULL); -} - -static void -churn_peers_on () -{ - churn_ctx.next_task = &churn_peers_off_again; - GNUNET_TESTING_daemons_churn (pg, NULL, 0, 2, TIMEOUT, &churn_callback, NULL); -} - -static void -churn_peers_off () -{ - churn_ctx.next_task = &churn_peers_on; - GNUNET_TESTING_daemons_churn (pg, NULL, 2, 0, TIMEOUT, &churn_callback, NULL); -} - -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_DEBUG, - "Failed to start daemon with error: `%s'\n", emsg); - return; - } - GNUNET_assert (id != NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n", - (num_peers - peers_left) + 1, num_peers); - peers_left--; - if (peers_left == 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All %d daemons started, now testing churn!\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 (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MINUTES, 5), &end_badly, - "from peers_started_callback"); - churn_peers_off (); - ok = 0; - } -} - - -static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - ok = 1; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting daemons based on config file %s\n", cfgfile); - 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; - - main_cfg = cfg; - - peers_left = num_peers; - GNUNET_assert (num_peers > 0 && num_peers < (unsigned int) -1); - - /* For this specific test we only really want a CLIQUE topology as the - * overlay allowed topology, and a RING topology as the underlying connection - * allowed topology. So we will expect only num_peers * 2 connections to - * work, and (num_peers * (num_peers - 1)) - (num_peers * 2) to fail. - */ - expected_connections = num_peers * (num_peers - 1); - expected_failed_connections = expected_connections - (num_peers * 2); - - - /* Set up a task to end testing if peer start fails */ - die_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MINUTES, 5), &end_badly, - "didn't start all daemons in reasonable amount of time!!!"); - - pg = GNUNET_TESTING_daemons_start (cfg, peers_left, peers_left, peers_left, - TIMEOUT, NULL, NULL, - &peers_started_callback, NULL, NULL, NULL, - NULL); - -} - -static int -check () -{ - int ret; - - char *const argv[] = { "test-testing-topology-churn", - "-c", - "test_testing_data_topology_churn.conf", - NULL - }; - struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - ret = - GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, - "test-testing-topology-churn", "nohelp", options, - &run, &ok); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "`test-testing-topology-churn': Failed with error code %d\n", - ret); - } - - return ok; -} - -int -main (int argc, char *argv[]) -{ - int ret; - - GNUNET_log_setup ("test_testing_topology_churn", - "WARNING", - NULL); - ret = check (); - - /** - * Need to remove base directory, subdirectories taken care - * of by the testing framework. - */ - if (test_directory != NULL) - { - 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_testing_topology_churn.c */ diff --git a/src/testing/testing.c b/src/testing/testing.c index 31bea06..dd80f6e 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet - (C) 2008, 2009 Christian Grothoff (and other contributing authors) + (C) 2008, 2009, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -21,2183 +21,1286 @@ /** * @file testing/testing.c * @brief convenience API for writing testcases for GNUnet - * Many testcases need to start and stop gnunetd, + * Many testcases need to start and stop a peer/service * and this library is supposed to make that easier * for TESTCASES. Normal programs should always * use functions from gnunet_{util,arm}_lib.h. This API is - * ONLY for writing testcases! + * ONLY for writing testcases (or internal use of the testbed). * @author Christian Grothoff * */ #include "platform.h" -#include "gnunet_arm_service.h" -#include "gnunet_core_service.h" -#include "gnunet_constants.h" +#include "gnunet_util_lib.h" #include "gnunet_testing_lib.h" -#include "gnunet_transport_service.h" -#include "gnunet_hello_lib.h" + +#define LOG(kind,...) \ + GNUNET_log_from (kind, "testing-api", __VA_ARGS__) + /** - * Hack to deal with initial HELLO's being often devoid of addresses. - * This hack causes 'process_hello' to ignore HELLOs without addresses. - * The correct implementation would continue with 'process_hello' until - * the connection could be established... + * We need pipe control only on WINDOWS */ -#define EMPTY_HACK GNUNET_YES +#if WINDOWS +#define PIPE_CONTROL GNUNET_YES +#else +#define PIPE_CONTROL GNUNET_NO +#endif + /** - * How long do we wait after starting gnunet-service-arm - * for the core service to be alive? + * Lowest port used for GNUnet testing. Should be high enough to not + * conflict with other applications running on the hosts but be low + * enough to not conflict with client-ports (typically starting around + * 32k). */ -#define ARM_START_WAIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) +#define LOW_PORT 12000 /** - * How many times are we willing to try to wait for "scp" or - * "gnunet-service-arm" to complete (waitpid) before giving up? + * Highest port used for GNUnet testing. Should be low enough to not + * conflict with the port range for "local" ports (client apps; see + * /proc/sys/net/ipv4/ip_local_port_range on Linux for example). */ -#define MAX_EXEC_WAIT_RUNS 250 - -static struct GNUNET_CORE_MessageHandler no_handlers[] = { {NULL, 0, 0} }; +#define HIGH_PORT 56000 -#if EMPTY_HACK -static int -test_address (void *cls, const struct GNUNET_HELLO_Address *address, - struct GNUNET_TIME_Absolute expiration) -{ - int *empty = cls; - - *empty = GNUNET_NO; - return GNUNET_OK; -} -#endif /** - * Receive the HELLO from one peer, give it to the other - * and ask them to connect. - * - * @param cls Closure (daemon whose hello is this). - * @param message HELLO message of peer + * Handle for a system on which GNUnet peers are executed; + * a system is used for reserving unique paths and ports. */ -static void -process_hello (void *cls, const struct GNUNET_MessageHeader *message) +struct GNUNET_TESTING_System { - struct GNUNET_TESTING_Daemon *daemon = cls; - int msize; + /** + * Prefix (i.e. "/tmp/gnunet-testing/") we prepend to each + * SERVICEHOME. */ + char *tmppath; -#if EMPTY_HACK - int empty; + /** + * The trusted ip. Can either be a single ip address or a network address in + * CIDR notation. + */ + char *trusted_ip; - empty = GNUNET_YES; - GNUNET_assert (message != NULL); - GNUNET_HELLO_iterate_addresses ((const struct GNUNET_HELLO_Message *) message, - GNUNET_NO, &test_address, &empty); - if (GNUNET_YES == empty) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Skipping empty HELLO address of peer %s\n", - GNUNET_i2s (&daemon->id)); - return; - } -#endif - GNUNET_assert (daemon->phase == SP_GET_HELLO || - daemon->phase == SP_START_DONE); - daemon->cb = NULL; // FIXME: why??? (see fsm:SP_START_CORE, notify_daemon_started) - if (daemon->task != GNUNET_SCHEDULER_NO_TASK) /* Assertion here instead? */ - GNUNET_SCHEDULER_cancel (daemon->task); + /** + * our hostname + */ + char *hostname; - if (daemon->server != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' from transport service of `%4s', disconnecting core!\n", - "HELLO", GNUNET_i2s (&daemon->id)); - GNUNET_CORE_disconnect (daemon->server); - daemon->server = NULL; - } + /** + * Hostkeys data, contains "GNUNET_TESTING_HOSTKEYFILESIZE * total_hostkeys" bytes. + */ + char *hostkeys_data; - msize = ntohs (message->size); - if (msize < 1) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "HELLO message of peer %s is of size 0\n", - GNUNET_i2s (&daemon->id)); - return; - } - if (daemon->ghh != NULL) - { - GNUNET_TRANSPORT_get_hello_cancel (daemon->ghh); - daemon->ghh = NULL; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' from transport service of `%4s'\n", "HELLO", - GNUNET_i2s (&daemon->id)); - GNUNET_free_non_null (daemon->hello); - daemon->hello = GNUNET_malloc (msize); - memcpy (daemon->hello, message, msize); - - if (daemon->th != NULL) - { - GNUNET_TRANSPORT_disconnect (daemon->th); - daemon->th = NULL; - } - daemon->phase = SP_START_DONE; -} + /** + * memory map for 'hostkeys_data'. + */ + struct GNUNET_DISK_MapHandle *map; + /** + * File descriptor for the map. + */ + struct GNUNET_DISK_FileHandle *map_fd; -/** - * Notify of a peer being up and running. Scheduled as a task - * so that variables which may need to be set are set before - * the connect callback can set up new operations. - * FIXME: what variables?????? where from???? - * - * @param cls the testing daemon - * @param tc task scheduler context - */ -static void -notify_daemon_started (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_TESTING_Daemon *d = cls; - GNUNET_TESTING_NotifyDaemonRunning cb; + /** + * Bitmap where each TCP port that has already been reserved for + * some GNUnet peer is recorded. Note that we additionally need to + * test if a port is already in use by non-GNUnet components before + * assigning it to a peer/service. If we detect that a port is + * already in use, we also mark it in this bitmap. So all the bits + * that are zero merely indicate ports that MIGHT be available for + * peers. + */ + uint32_t reserved_tcp_ports[65536 / 32]; - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, &d->id, d->cfg, d, NULL); -} + /** + * Bitmap where each UDP port that has already been reserved for + * some GNUnet peer is recorded. Note that we additionally need to + * test if a port is already in use by non-GNUnet components before + * assigning it to a peer/service. If we detect that a port is + * already in use, we also mark it in this bitmap. So all the bits + * that are zero merely indicate ports that MIGHT be available for + * peers. + */ + uint32_t reserved_udp_ports[65536 / 32]; + /** + * Counter we use to make service home paths unique on this system; + * the full path consists of the tmppath and this number. Each + * UNIXPATH for a peer is also modified to include the respective + * path counter to ensure uniqueness. This field is incremented + * by one for each configured peer. Even if peers are destroyed, + * we never re-use path counters. + */ + uint32_t path_counter; -/** - * Finite-state machine for starting GNUnet. - * - * @param cls our "struct GNUNET_TESTING_Daemon" - * @param tc unused - */ -static void -start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_TESTING_Daemon *d = cls; - GNUNET_TESTING_NotifyDaemonRunning cb; - enum GNUNET_OS_ProcessStatusType type; - unsigned long code; - char *dst; - int bytes_read; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %s FSM is in phase %u.\n", - GNUNET_i2s (&d->id), d->phase); - d->task = GNUNET_SCHEDULER_NO_TASK; - switch (d->phase) - { - case SP_COPYING: - /* confirm copying complete */ - if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_copying, &type, &code)) - { - if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) - { - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, - _ - ("`scp' does not seem to terminate (timeout copying config).\n")); - return; - } - /* wait some more */ - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, - d); - return; - } - if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0)) - { - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, _("`scp' did not complete cleanly.\n")); - return; - } - GNUNET_OS_process_destroy (d->proc_arm_copying); - d->proc_arm_copying = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Successfully copied configuration file.\n"); - d->phase = SP_COPIED; - /* fall-through */ - case SP_COPIED: - /* Start create hostkey process if we don't already know the peer identity! */ - if (GNUNET_NO == d->have_hostkey) - { - GNUNET_assert (NULL == d->proc_arm_peerinfo); - d->pipe_stdout = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_YES); - if (d->pipe_stdout == NULL) - { - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, - (NULL == - d->hostname) ? - _("Failed to create pipe for `gnunet-peerinfo' process.\n") : - _("Failed to create pipe for `ssh' process.\n")); - return; - } - if (NULL == d->hostname) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting `%s', with command `%s %s %s %s'.\n", - "gnunet-peerinfo", "gnunet-peerinfo", "-c", d->cfgfile, - "-sq"); - d->proc_arm_peerinfo = - GNUNET_OS_start_process (GNUNET_YES, NULL, d->pipe_stdout, "gnunet-peerinfo", - "gnunet-peerinfo", "-c", d->cfgfile, "-sq", - NULL); - GNUNET_DISK_pipe_close_end (d->pipe_stdout, GNUNET_DISK_PIPE_END_WRITE); - } - else - { - if (d->username != NULL) - GNUNET_asprintf (&dst, "%s@%s", d->username, d->hostname); - else - dst = GNUNET_strdup (d->hostname); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting `%s', with command `%s %s %s %s %s %s'.\n", - "gnunet-peerinfo", "ssh", dst, "gnunet-peerinfo", "-c", - d->cfgfile, "-sq"); - if (d->ssh_port_str == NULL) - { - d->proc_arm_peerinfo = GNUNET_OS_start_process (GNUNET_NO, NULL, d->pipe_stdout, "ssh", "ssh", - "-q", - dst, "gnunet-peerinfo", "-c", - d->cfgfile, "-sq", NULL); - } - else - { - d->proc_arm_peerinfo = - GNUNET_OS_start_process (GNUNET_NO, NULL, d->pipe_stdout, "ssh", "ssh", "-p", - d->ssh_port_str, - "-q", - dst, "gnunet-peerinfo", "-c", d->cfgfile, - "-sq", NULL); - } - GNUNET_DISK_pipe_close_end (d->pipe_stdout, GNUNET_DISK_PIPE_END_WRITE); - GNUNET_free (dst); - } - if (NULL == d->proc_arm_peerinfo) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Could not start `%s' process to create hostkey.\n"), - (NULL == d->hostname) ? "gnunet-peerinfo" : "ssh"); - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, - (NULL == - d->hostname) ? _("Failed to start `gnunet-peerinfo' process.\n") - : _("Failed to start `ssh' process.\n")); - GNUNET_DISK_pipe_close (d->pipe_stdout); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Started `%s', waiting for hostkey.\n", "gnunet-peerinfo"); - d->phase = SP_HOSTKEY_CREATE; - d->task = - GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining - (d->max_timeout), - GNUNET_DISK_pipe_handle - (d->pipe_stdout, - GNUNET_DISK_PIPE_END_READ), - &start_fsm, d); - } - else /* Already have a hostkey! */ - { - if (d->hostkey_callback != NULL) - { - d->hostkey_callback (d->hostkey_cls, &d->id, d, NULL); - d->hostkey_callback = NULL; - d->phase = SP_HOSTKEY_CREATED; - } - else - d->phase = SP_TOPOLOGY_SETUP; + /** + * The number of hostkeys + */ + uint32_t total_hostkeys; - /* wait some more */ - d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d); - } - break; - case SP_HOSTKEY_CREATE: - bytes_read = - GNUNET_DISK_file_read (GNUNET_DISK_pipe_handle - (d->pipe_stdout, GNUNET_DISK_PIPE_END_READ), - &d->hostkeybuf[d->hostkeybufpos], - sizeof (d->hostkeybuf) - d->hostkeybufpos); - if (bytes_read > 0) - d->hostkeybufpos += bytes_read; - - if ((d->hostkeybufpos < 104) && (bytes_read > 0)) - { - /* keep reading */ - d->task = - GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_absolute_get_remaining - (d->max_timeout), - GNUNET_DISK_pipe_handle - (d->pipe_stdout, - GNUNET_DISK_PIPE_END_READ), - &start_fsm, d); - return; - } - d->hostkeybuf[103] = '\0'; + /** + * Lowest port we are allowed to use. + */ + uint16_t lowport; - if ((bytes_read < 0) || - (GNUNET_OK != - GNUNET_CRYPTO_hash_from_string (d->hostkeybuf, &d->id.hashPubKey))) - { - /* error */ - if (bytes_read < 0) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Error reading from gnunet-peerinfo: %s\n"), - STRERROR (errno)); - else - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Malformed output from gnunet-peerinfo!\n")); - cb = d->cb; - d->cb = NULL; - GNUNET_DISK_pipe_close (d->pipe_stdout); - d->pipe_stdout = NULL; - (void) GNUNET_OS_process_kill (d->proc_arm_peerinfo, SIGKILL); - GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc_arm_peerinfo)); - GNUNET_OS_process_destroy (d->proc_arm_peerinfo); - d->proc_arm_peerinfo = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, _("Failed to get hostkey!\n")); - return; - } - d->shortname = GNUNET_strdup (GNUNET_i2s (&d->id)); - GNUNET_DISK_pipe_close (d->pipe_stdout); - d->pipe_stdout = NULL; - (void) GNUNET_OS_process_kill (d->proc_arm_peerinfo, SIGKILL); - GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (d->proc_arm_peerinfo)); - GNUNET_OS_process_destroy (d->proc_arm_peerinfo); - d->proc_arm_peerinfo = NULL; - d->have_hostkey = GNUNET_YES; - if (d->hostkey_callback != NULL) - { - d->hostkey_callback (d->hostkey_cls, &d->id, d, NULL); - d->hostkey_callback = NULL; - d->phase = SP_HOSTKEY_CREATED; - } - else - { - d->phase = SP_TOPOLOGY_SETUP; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully got hostkey!\n"); - /* Fall through */ - case SP_HOSTKEY_CREATED: - /* wait for topology finished */ - if ((GNUNET_YES == d->dead) || - (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0)) - { - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, - _("`Failed while waiting for topology setup!\n")); - return; - } + /** + * Highest port we are allowed to use. + */ + uint16_t highport; +}; - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, - d); - break; - case SP_TOPOLOGY_SETUP: /* Indicates topology setup has completed! */ - /* start GNUnet on remote host */ - if (NULL == d->hostname) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting `%s', with command `%s %s %s %s'.\n", - "gnunet-arm", "gnunet-arm", "-c", d->cfgfile, - "-s"); - d->proc_arm_start = - GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", "-c", - d->cfgfile, - "-s", "-q", "-T", - GNUNET_TIME_relative_to_string - (GNUNET_TIME_absolute_get_remaining - (d->max_timeout)), NULL); - } - else - { - if (d->username != NULL) - GNUNET_asprintf (&dst, "%s@%s", d->username, d->hostname); - else - dst = GNUNET_strdup (d->hostname); - - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Starting `%s', with command `%s %s %s %s %s %s %s'.\n", - "gnunet-arm", "ssh", dst, "gnunet-arm", "-c", d->cfgfile, - "-s", "-q"); - if (d->ssh_port_str == NULL) - { - d->proc_arm_start = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", - "-q", - dst, "gnunet-arm", - "-c", d->cfgfile, "-s", "-q", "-T", - GNUNET_TIME_relative_to_string - (GNUNET_TIME_absolute_get_remaining - (d->max_timeout)), NULL); - } - else - { - d->proc_arm_start = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-p", - d->ssh_port_str, - "-q", - dst, "gnunet-arm", - "-c", d->cfgfile, "-s", "-q", "-T", - GNUNET_TIME_relative_to_string - (GNUNET_TIME_absolute_get_remaining - (d->max_timeout)), NULL); - } - GNUNET_free (dst); - } - if (NULL == d->proc_arm_start) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Could not start `%s' process to start GNUnet.\n"), - (NULL == d->hostname) ? "gnunet-arm" : "ssh"); - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, - (NULL == - d->hostname) ? _("Failed to start `gnunet-arm' process.\n") : - _("Failed to start `ssh' process.\n")); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Started `%s', waiting for `%s' to be up.\n", "gnunet-arm", - "gnunet-service-core"); - d->phase = SP_START_ARMING; - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, - d); - // FIXME: busy wait? - break; - case SP_START_ARMING: - if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_start, &type, &code)) - { - if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) - { - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, - (NULL == - d->hostname) ? _("`gnunet-arm' does not seem to terminate.\n") : - _("`ssh' does not seem to terminate.\n")); - if (d->cfg != NULL) - { - GNUNET_CONFIGURATION_destroy (d->cfg); - d->cfg = NULL; - } - if (d->cfgfile != NULL) - { - GNUNET_free (d->cfgfile); - d->cfgfile = NULL; - } - GNUNET_free_non_null (d->hostname); - GNUNET_free_non_null (d->username); - GNUNET_OS_process_destroy (d->proc_arm_start); - d->proc_arm_start = NULL; - d->username = NULL; - d->hostname = NULL; // Quick hack to avoid crashing (testing need to be - d->cfg = NULL; // overhauled anyway, and the error managing is - // GNUNET_free (d); // FIXME (could this leak) - // pretty broken anyway. - return; - } - /* wait some more */ - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, - d); - // FIXME: busy wait? - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully started `%s'.\n", - "gnunet-arm"); - GNUNET_OS_process_destroy (d->proc_arm_start); - d->proc_arm_start = NULL; - d->phase = SP_START_CORE; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Calling CORE_connect\n"); - /* Fall through */ - case SP_START_CORE: - if (d->server != NULL) - GNUNET_CORE_disconnect (d->server); - - d->th = GNUNET_TRANSPORT_connect (d->cfg, &d->id, d, NULL, NULL, NULL); - if (d->th == NULL) - { - if (GNUNET_YES == d->dead) - GNUNET_TESTING_daemon_stop (d, - GNUNET_TIME_absolute_get_remaining - (d->max_timeout), d->dead_cb, - d->dead_cb_cls, GNUNET_YES, GNUNET_NO); - else if (NULL != d->cb) - d->cb (d->cb_cls, &d->id, d->cfg, d, - _("Failed to connect to transport service!\n")); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connected to transport service `%s', getting HELLO\n", - GNUNET_i2s (&d->id)); - d->ghh = GNUNET_TRANSPORT_get_hello (d->th, &process_hello, d); - /* FIXME: store task ID somewhere! */ - GNUNET_SCHEDULER_add_now (¬ify_daemon_started, d); - /*cb = d->cb; - * d->cb = NULL; - * if (NULL != cb) - * cb (d->cb_cls, &d->id, d->cfg, d, NULL); */ - d->running = GNUNET_YES; - d->phase = SP_GET_HELLO; - break; - case SP_GET_HELLO: - if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) - { - if (d->server != NULL) - GNUNET_CORE_disconnect (d->server); - if (d->th != NULL) - GNUNET_TRANSPORT_disconnect (d->th); - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, _("Unable to get HELLO for peer!\n")); - GNUNET_CONFIGURATION_destroy (d->cfg); - GNUNET_free (d->cfgfile); - GNUNET_free_non_null (d->hostname); - GNUNET_free_non_null (d->username); - GNUNET_free (d); - return; - } - if (d->hello != NULL) - return; - GNUNET_assert (d->task == GNUNET_SCHEDULER_NO_TASK); - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_CONSTANTS_SERVICE_RETRY, 2), - &start_fsm, d); - break; - case SP_START_DONE: - GNUNET_break (0); - break; - case SP_SERVICE_START: - /* confirm gnunet-arm exited */ - if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_srv_start, &type, &code)) - { - if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) - { - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, - (NULL == - d->hostname) ? _("`gnunet-arm' does not seem to terminate.\n") : - _("`ssh' does not seem to terminate.\n")); - return; - } - /* wait some more */ - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, - d); - return; - } -#if EXTRA_CHECKS - if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0)) - { - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, - (NULL == - d->hostname) ? - _ - ("`gnunet-arm' terminated with non-zero exit status (or timed out)!\n") - : _("`ssh' does not seem to terminate.\n")); - return; - } -#endif - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service startup complete!\n"); - cb = d->cb; - d->cb = NULL; - d->phase = SP_START_DONE; - if (NULL != cb) - cb (d->cb_cls, &d->id, d->cfg, d, NULL); - GNUNET_OS_process_destroy (d->proc_arm_srv_start); - d->proc_arm_srv_start = NULL; - break; - case SP_SERVICE_SHUTDOWN_START: - /* confirm copying complete */ - if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_srv_stop, &type, &code)) - { - if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) - { - if (NULL != d->dead_cb) - d->dead_cb (d->dead_cb_cls, - _ - ("either `gnunet-arm' or `ssh' does not seem to terminate.\n")); - return; - } - /* wait some more */ - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, - d); - return; - } -#if EXTRA_CHECKS - if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0)) - { - if (NULL != d->dead_cb) - d->dead_cb (d->dead_cb_cls, - _ - ("shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n")); - return; - } -#endif - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service shutdown complete.\n"); - if (NULL != d->dead_cb) - d->dead_cb (d->dead_cb_cls, NULL); - break; - case SP_SHUTDOWN_START: - /* confirm copying complete !??? */ - if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_stop, &type, &code)) - { - if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) - { - if (NULL != d->dead_cb) - d->dead_cb (d->dead_cb_cls, - _ - ("either `gnunet-arm' or `ssh' does not seem to terminate.\n")); - if (d->th != NULL) - { - GNUNET_TRANSPORT_get_hello_cancel (d->ghh); - d->ghh = NULL; - GNUNET_TRANSPORT_disconnect (d->th); - d->th = NULL; - } - if (d->cfg != NULL) - { - GNUNET_CONFIGURATION_destroy (d->cfg); - d->cfg = NULL; - } - if (d->cfgfile != NULL) - { - GNUNET_free (d->cfgfile); - d->cfgfile = NULL; - } - GNUNET_free_non_null (d->hello); - GNUNET_free_non_null (d->hostname); - GNUNET_free_non_null (d->username); - GNUNET_free_non_null (d->shortname); - GNUNET_OS_process_destroy (d->proc_arm_stop); - d->proc_arm_stop = NULL; - GNUNET_free (d); - return; - } - /* wait some more */ - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, - d); - return; - } - if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0)) - { - if (NULL != d->dead_cb) - d->dead_cb (d->dead_cb_cls, - _ - ("shutdown (either `gnunet-arm' or `ssh') did not complete cleanly.\n")); - if (d->th != NULL) - { - GNUNET_TRANSPORT_get_hello_cancel (d->ghh); - d->ghh = NULL; - GNUNET_TRANSPORT_disconnect (d->th); - d->th = NULL; - } - if (d->server != NULL) - { - GNUNET_CORE_disconnect (d->server); - d->server = NULL; - } - GNUNET_CONFIGURATION_destroy (d->cfg); - d->cfg = NULL; - GNUNET_free (d->cfgfile); - GNUNET_free_non_null (d->hello); - GNUNET_free_non_null (d->hostname); - GNUNET_free_non_null (d->username); - GNUNET_free_non_null (d->shortname); - GNUNET_OS_process_destroy (d->proc_arm_stop); - d->proc_arm_stop = NULL; - GNUNET_free (d); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer shutdown complete.\n"); - if (d->server != NULL) - { - GNUNET_CORE_disconnect (d->server); - d->server = NULL; - } +/** + * Handle for a GNUnet peer controlled by testing. + */ +struct GNUNET_TESTING_Peer +{ + /** + * The TESTING system associated with this peer + */ + struct GNUNET_TESTING_System *system; - if (d->th != NULL) - { - GNUNET_TRANSPORT_get_hello_cancel (d->ghh); - d->ghh = NULL; - GNUNET_TRANSPORT_disconnect (d->th); - d->th = NULL; - } + /** + * Path to the configuration file for this peer. + */ + char *cfgfile; - if (NULL != d->dead_cb) - d->dead_cb (d->dead_cb_cls, NULL); + /** + * Binary to be executed during 'GNUNET_TESTING_peer_start'. + * Typically 'gnunet-service-arm' (but can be set to a + * specific service by 'GNUNET_TESTING_service_run' if + * necessary). + */ + char *main_binary; + char *args; + + /** + * Handle to the running binary of the service, NULL if the + * peer/service is currently not running. + */ + struct GNUNET_OS_Process *main_process; - /* state clean up and notifications */ - if (d->churn == GNUNET_NO) - { - GNUNET_CONFIGURATION_destroy (d->cfg); - d->cfg = NULL; - GNUNET_free (d->cfgfile); - GNUNET_free_non_null (d->hostname); - GNUNET_free_non_null (d->username); - } + /** + * The keynumber of this peer's hostkey + */ + uint32_t key_number; +}; - GNUNET_free_non_null (d->hello); - d->hello = NULL; - GNUNET_free_non_null (d->shortname); - GNUNET_OS_process_destroy (d->proc_arm_stop); - d->proc_arm_stop = NULL; - d->shortname = NULL; - if (d->churn == GNUNET_NO) - GNUNET_free (d); - - break; - case SP_CONFIG_UPDATE: - /* confirm copying complete */ - if (GNUNET_OK != GNUNET_OS_process_status (d->proc_arm_copying, &type, &code)) - { - if (GNUNET_TIME_absolute_get_remaining (d->max_timeout).rel_value == 0) /* FIXME: config update should take timeout parameter! */ - { - cb = d->cb; - d->cb = NULL; - if (NULL != cb) - cb (d->cb_cls, NULL, d->cfg, d, - _("`scp' does not seem to terminate.\n")); - return; - } - /* wait some more */ - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, - d); - return; - } - if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0)) - { - if (NULL != d->update_cb) - d->update_cb (d->update_cb_cls, _("`scp' did not complete cleanly.\n")); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Successfully copied configuration file.\n"); - if (NULL != d->update_cb) - d->update_cb (d->update_cb_cls, NULL); - d->phase = SP_START_DONE; - break; - } -} /** - * Continues GNUnet daemon startup when user wanted to be notified - * once a hostkey was generated (for creating friends files, blacklists, - * etc.). + * Testing includes a number of pre-created hostkeys for faster peer + * startup. This function loads such keys into memory from a file. * - * @param daemon the daemon to finish starting + * @param system the testing system handle + * @return GNUNET_OK on success; GNUNET_SYSERR on error */ -void -GNUNET_TESTING_daemon_continue_startup (struct GNUNET_TESTING_Daemon *daemon) +static int +hostkeys_load (struct GNUNET_TESTING_System *system) { - GNUNET_assert (daemon->phase == SP_HOSTKEY_CREATED); - daemon->phase = SP_TOPOLOGY_SETUP; + uint64_t fs; + char *data_dir; + char *filename; + + GNUNET_assert (NULL == system->hostkeys_data); + data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); + GNUNET_asprintf (&filename, "%s/testing_hostkeys.dat", data_dir); + GNUNET_free (data_dir); + + if (GNUNET_YES != GNUNET_DISK_file_test (filename)) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Hostkeys file not found: %s\n"), filename); + GNUNET_free (filename); + return GNUNET_SYSERR; + } + /* Check hostkey file size, read entire thing into memory */ + if (GNUNET_OK != + GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) + fs = 0; + if (0 == fs) + { + GNUNET_free (filename); + return GNUNET_SYSERR; /* File is empty */ + } + if (0 != (fs % GNUNET_TESTING_HOSTKEYFILESIZE)) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Incorrect hostkey file format: %s\n"), filename); + GNUNET_free (filename); + return GNUNET_SYSERR; + } + system->map_fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, + GNUNET_DISK_PERM_NONE); + if (NULL == system->map_fd) + { + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", filename); + GNUNET_free (filename); + return GNUNET_SYSERR; + } + system->total_hostkeys = fs / GNUNET_TESTING_HOSTKEYFILESIZE; + system->hostkeys_data = GNUNET_DISK_file_map (system->map_fd, + &system->map, + GNUNET_DISK_MAP_TYPE_READ, + fs); + GNUNET_free (filename); + return GNUNET_OK; } + /** - * Check whether the given daemon is running. - * - * @param daemon the daemon to check + * Function to remove the loaded hostkeys * - * @return GNUNET_YES if the daemon is up, GNUNET_NO if the - * daemon is down, GNUNET_SYSERR on error. + * @param system the testing system handle */ -int -GNUNET_TESTING_test_daemon_running (struct GNUNET_TESTING_Daemon *daemon) +static void +hostkeys_unload (struct GNUNET_TESTING_System *system) { - if (daemon == NULL) - return GNUNET_SYSERR; - - if (daemon->running == GNUNET_YES) - return GNUNET_YES; - return GNUNET_NO; + GNUNET_break (NULL != system->hostkeys_data); + system->hostkeys_data = NULL; + GNUNET_DISK_file_unmap (system->map); + system->map = NULL; + GNUNET_DISK_file_close (system->map_fd); + system->map_fd = NULL; + system->hostkeys_data = NULL; + system->total_hostkeys = 0; } /** - * Starts a GNUnet daemon service which has been previously stopped. + * Create a system handle. There must only be one system + * handle per operating system. * - * @param d the daemon for which the service should be started - * @param service the name of the service to start - * @param timeout how long to wait for process for shutdown to complete - * @param cb function called once the service starts - * @param cb_cls closure for cb + * @param testdir only the directory name without any path. This is used for + * all service homes; the directory will be created in a temporary + * location depending on the underlying OS + * @param trusted_ip the ip address which will be set as TRUSTED HOST in all + * service configurations generated to allow control connections from + * this ip. This can either be a single ip address or a network address + * in CIDR notation. + * @param hostname the hostname of the system we are using for testing; NULL for + * localhost + * @param lowport lowest port number this system is allowed to allocate (inclusive) + * @param highport highest port number this system is allowed to allocate (exclusive) + * @return handle to this system, NULL on error */ -void -GNUNET_TESTING_daemon_start_stopped_service (struct GNUNET_TESTING_Daemon *d, - char *service, - struct GNUNET_TIME_Relative - timeout, - GNUNET_TESTING_NotifyDaemonRunning - cb, void *cb_cls) +struct GNUNET_TESTING_System * +GNUNET_TESTING_system_create_with_portrange (const char *testdir, + const char *trusted_ip, + const char *hostname, + uint16_t lowport, + uint16_t highport) { - char *arg; - - d->cb = cb; - d->cb_cls = cb_cls; - - GNUNET_assert (d->running == GNUNET_YES); + struct GNUNET_TESTING_System *system; - if (d->phase == SP_CONFIG_UPDATE) + GNUNET_assert (NULL != testdir); + system = GNUNET_malloc (sizeof (struct GNUNET_TESTING_System)); + system->tmppath = GNUNET_DISK_mkdtemp (testdir); + system->lowport = lowport; + system->highport = highport; + if (NULL == system->tmppath) { - GNUNET_SCHEDULER_cancel (d->task); - d->phase = SP_START_DONE; - } - - if (d->churned_services == NULL) - { - d->cb (d->cb_cls, &d->id, d->cfg, d, - "No service has been churned off yet!!"); - return; - } - d->phase = SP_SERVICE_START; - GNUNET_free (d->churned_services); - d->churned_services = NULL; - d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); - /* Check if this is a local or remote process */ - if (NULL != d->hostname) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting gnunet-arm with config `%s' on host `%s'.\n", - d->cfgfile, d->hostname); - if (d->username != NULL) - GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname); - else - arg = GNUNET_strdup (d->hostname); - - d->proc_arm_srv_start = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", - "-q", - arg, "gnunet-arm", - "-c", d->cfgfile, "-i", service, "-q", - "-T", - GNUNET_TIME_relative_to_string (timeout), - NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting gnunet-arm with command ssh %s gnunet-arm -c %s -i %s -q\n", - arg, "gnunet-arm", d->cfgfile, service); - GNUNET_free (arg); + GNUNET_free (system); + return NULL; } - else + if (NULL != trusted_ip) + system->trusted_ip = GNUNET_strdup (trusted_ip); + if (NULL != hostname) + system->hostname = GNUNET_strdup (hostname); + if (GNUNET_OK != hostkeys_load (system)) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting gnunet-arm with config `%s' locally.\n", d->cfgfile); - d->proc_arm_srv_start = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", - "-c", d->cfgfile, "-i", service, "-q", - "-T", - GNUNET_TIME_relative_to_string (timeout), - NULL); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return NULL; } - - d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); - d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d); + return system; } + /** - * Starts a GNUnet daemon's service. + * Create a system handle. There must only be one system handle per operating + * system. Uses a default range for allowed ports. Ports are still tested for + * availability. * - * @param d the daemon for which the service should be started - * @param service the name of the service to start - * @param timeout how long to wait for process for startup - * @param cb function called once gnunet-arm returns - * @param cb_cls closure for cb + * @param testdir only the directory name without any path. This is used for all + * service homes; the directory will be created in a temporary location + * depending on the underlying OS + * @param trusted_ip the ip address which will be set as TRUSTED HOST in all + * service configurations generated to allow control connections from + * this ip. This can either be a single ip address or a network address + * in CIDR notation. + * @param hostname the hostname of the system we are using for testing; NULL for + * localhost + * @return handle to this system, NULL on error */ -void -GNUNET_TESTING_daemon_start_service (struct GNUNET_TESTING_Daemon *d, - const char *service, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTING_NotifyDaemonRunning cb, - void *cb_cls) +struct GNUNET_TESTING_System * +GNUNET_TESTING_system_create (const char *testdir, + const char *trusted_ip, + const char *hostname) { - char *arg; - - d->cb = cb; - d->cb_cls = cb_cls; - - GNUNET_assert (service != NULL); - GNUNET_assert (d->running == GNUNET_YES); - GNUNET_assert (d->phase == SP_START_DONE); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Starting service %s for peer `%4s'\n"), service, - GNUNET_i2s (&d->id)); - d->phase = SP_SERVICE_START; - d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); - /* Check if this is a local or remote process */ - if (NULL != d->hostname) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting gnunet-arm with config `%s' on host `%s'.\n", - d->cfgfile, d->hostname); - if (d->username != NULL) - GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname); - else - arg = GNUNET_strdup (d->hostname); - - d->proc_arm_srv_start = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", - "-q", - arg, "gnunet-arm", - "-c", d->cfgfile, "-i", service, "-q", - "-T", - GNUNET_TIME_relative_to_string (timeout), - NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting gnunet-arm with command ssh %s gnunet-arm -c %s -i %s -q -T %s\n", - arg, "gnunet-arm", d->cfgfile, service, - GNUNET_TIME_relative_to_string (timeout)); - GNUNET_free (arg); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting gnunet-arm with config `%s' locally.\n", d->cfgfile); - d->proc_arm_srv_start = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", - "-c", d->cfgfile, "-i", service, "-q", - "-T", - GNUNET_TIME_relative_to_string (timeout), - NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting gnunet-arm with command %s -c %s -i %s -q -T %s\n", - "gnunet-arm", d->cfgfile, service, - GNUNET_TIME_relative_to_string (timeout)); - } - - d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); - d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d); + return GNUNET_TESTING_system_create_with_portrange (testdir, + trusted_ip, + hostname, + LOW_PORT, + HIGH_PORT); } + /** - * Start a peer that has previously been stopped using the daemon_stop - * call (and files weren't deleted and the allow restart flag) + * Free system resources. * - * @param daemon the daemon to start (has been previously stopped) - * @param timeout how long to wait for restart - * @param cb the callback for notification when the peer is running - * @param cb_cls closure for the callback + * @param system system to be freed + * @param remove_paths should the 'testdir' and all subdirectories + * be removed (clean up on shutdown)? */ void -GNUNET_TESTING_daemon_start_stopped (struct GNUNET_TESTING_Daemon *daemon, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTING_NotifyDaemonRunning cb, - void *cb_cls) +GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system, + int remove_paths) { - if (daemon->running == GNUNET_YES) - { - cb (cb_cls, &daemon->id, daemon->cfg, daemon, - "Daemon already running, can't restart!"); - return; - } - - daemon->cb = cb; - daemon->cb_cls = cb_cls; - daemon->phase = SP_TOPOLOGY_SETUP; - daemon->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); - /* FIXME: why add_continuation? */ - GNUNET_SCHEDULER_add_continuation (&start_fsm, daemon, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); + if (NULL != system->hostkeys_data) + hostkeys_unload (system); + if (GNUNET_YES == remove_paths) + GNUNET_DISK_directory_remove (system->tmppath); + GNUNET_free (system->tmppath); + GNUNET_free_non_null (system->trusted_ip); + GNUNET_free_non_null (system->hostname); + GNUNET_free (system); } + /** - * Starts a GNUnet daemon. GNUnet must be installed on the target - * system and available in the PATH. The machine must furthermore be - * reachable via "ssh" (unless the hostname is "NULL") without the - * need to enter a password. + * Reserve a TCP or UDP port for a peer. * - * @param cfg configuration to use - * @param timeout how long to wait starting up peers - * @param pretend GNUNET_YES to set up files but not start peer GNUNET_NO - * to really start the peer (default) - * @param hostname name of the machine where to run GNUnet - * (use NULL for localhost). - * @param ssh_username ssh username to use when connecting to hostname - * @param sshport port to pass to ssh process when connecting to hostname - * @param hostkey pointer to a hostkey to be written to disk (instead of being generated) - * @param hostkey_callback function to call once the hostkey has been - * generated for this peer, but it hasn't yet been started - * (NULL to start immediately, otherwise waits on GNUNET_TESTING_daemon_continue_start) - * @param hostkey_cls closure for hostkey callback - * @param cb function to call once peer is up, or failed to start - * @param cb_cls closure for cb - * @return handle to the daemon (actual start will be completed asynchronously) + * @param system system to use for reservation tracking + * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP + * @return 0 if no free port was available */ -struct GNUNET_TESTING_Daemon * -GNUNET_TESTING_daemon_start (const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TIME_Relative timeout, int pretend, - const char *hostname, const char *ssh_username, - uint16_t sshport, const char *hostkey, - GNUNET_TESTING_NotifyHostkeyCreated - hostkey_callback, void *hostkey_cls, - GNUNET_TESTING_NotifyDaemonRunning cb, - void *cb_cls) +uint16_t +GNUNET_TESTING_reserve_port (struct GNUNET_TESTING_System *system, + int is_tcp) { - struct GNUNET_TESTING_Daemon *ret; - char *arg; - char *username; - char *servicehome; - char *baseservicehome; - char *slash; - char *hostkeyfile; - char *temp_file_name; - struct GNUNET_DISK_FileHandle *fn; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; - struct GNUNET_CRYPTO_RsaPrivateKey *private_key; - - ret = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Daemon)); - ret->hostname = (hostname == NULL) ? NULL : GNUNET_strdup (hostname); - if (sshport != 0) - { - GNUNET_asprintf (&ret->ssh_port_str, "%d", sshport); - } - else - ret->ssh_port_str = NULL; - - /* Find service home and base service home directories, create it if it doesn't exist */ - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", - "SERVICEHOME", - &servicehome)); - - GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_create (servicehome)); - GNUNET_asprintf (&temp_file_name, "%s/gnunet-testing-config", servicehome); - ret->cfgfile = GNUNET_DISK_mktemp (temp_file_name); - GNUNET_free (temp_file_name); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Setting up peer with configuration file `%s'.\n", ret->cfgfile); - if (NULL == ret->cfgfile) - { - GNUNET_free_non_null (ret->ssh_port_str); - GNUNET_free_non_null (ret->hostname); - GNUNET_free (ret); - return NULL; - } - ret->hostkey_callback = hostkey_callback; - ret->hostkey_cls = hostkey_cls; - ret->cb = cb; - ret->cb_cls = cb_cls; - ret->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); - ret->cfg = GNUNET_CONFIGURATION_dup (cfg); - GNUNET_CONFIGURATION_set_value_string (ret->cfg, "PATHS", "DEFAULTCONFIG", - ret->cfgfile); - - if (hostkey != NULL) /* Get the peer identity from the hostkey */ - { - private_key = GNUNET_CRYPTO_rsa_decode_key (hostkey, HOSTKEYFILESIZE); - GNUNET_assert (private_key != NULL); - GNUNET_CRYPTO_rsa_key_get_public (private_key, &public_key); - GNUNET_CRYPTO_hash (&public_key, - sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &ret->id.hashPubKey); - ret->shortname = GNUNET_strdup (GNUNET_i2s (&ret->id)); - ret->have_hostkey = GNUNET_YES; - GNUNET_CRYPTO_rsa_key_free (private_key); - } - - /* Write hostkey to file, if we were given one */ - hostkeyfile = NULL; - if (hostkey != NULL) - { - GNUNET_asprintf (&hostkeyfile, "%s/.hostkey", servicehome); - fn = GNUNET_DISK_file_open (hostkeyfile, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - GNUNET_assert (fn != NULL); - GNUNET_assert (HOSTKEYFILESIZE == - GNUNET_DISK_file_write (fn, hostkey, HOSTKEYFILESIZE)); - GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fn)); - } - - /* write configuration to temporary file */ - if (GNUNET_OK != GNUNET_CONFIGURATION_write (ret->cfg, ret->cfgfile)) - { - if (0 != UNLINK (ret->cfgfile)) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", - ret->cfgfile); - GNUNET_CONFIGURATION_destroy (ret->cfg); - GNUNET_free_non_null (ret->hostname); - GNUNET_free (ret->cfgfile); - GNUNET_free (ret); - return NULL; - } - if (ssh_username != NULL) - username = GNUNET_strdup (ssh_username); - if ((ssh_username == NULL) && - (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, "TESTING", "USERNAME", - &username))) - { - if (NULL != getenv ("USER")) - username = GNUNET_strdup (getenv ("USER")); - else - username = NULL; - } - ret->username = username; - - if (GNUNET_NO == pretend) /* Copy files, enter finite state machine */ - { - /* copy directory to remote host */ - if (NULL != hostname) + struct GNUNET_NETWORK_Handle *socket; + struct addrinfo hint; + struct addrinfo *ret; + struct addrinfo *ai; + uint32_t *port_buckets; + char *open_port_str; + int bind_status; + uint32_t xor_image; + uint16_t index; + uint16_t open_port; + uint16_t pos; + + /* + FIXME: Instead of using getaddrinfo we should try to determine the port + status by the following heurestics. + + On systems which support both IPv4 and IPv6, only ports open on both + address families are considered open. + On system with either IPv4 or IPv6. A port is considered open if it's + open in the respective address family + */ + hint.ai_family = AF_UNSPEC; /* IPv4 and IPv6 */ + hint.ai_socktype = (GNUNET_YES == is_tcp)? SOCK_STREAM : SOCK_DGRAM; + hint.ai_protocol = 0; + hint.ai_addrlen = 0; + hint.ai_addr = NULL; + hint.ai_canonname = NULL; + hint.ai_next = NULL; + hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */ + port_buckets = (GNUNET_YES == is_tcp) ? + system->reserved_tcp_ports : system->reserved_udp_ports; + for (index = (system->lowport / 32) + 1; index < (system->highport / 32); index++) + { + xor_image = (UINT32_MAX ^ port_buckets[index]); + if (0 == xor_image) /* Ports in the bucket are full */ + continue; + pos = system->lowport % 32; + while (pos < 32) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Copying configuration directory to host `%s'.\n", hostname); - baseservicehome = GNUNET_strdup (servicehome); - /* Remove trailing /'s */ - while (baseservicehome[strlen (baseservicehome) - 1] == '/') - baseservicehome[strlen (baseservicehome) - 1] = '\0'; - /* Find next directory /, jump one ahead */ - slash = strrchr (baseservicehome, '/'); - if (slash != NULL) - *(++slash) = '\0'; - - ret->phase = SP_COPYING; - if (NULL != username) - GNUNET_asprintf (&arg, "%s@%s:%s", username, hostname, baseservicehome); - else - GNUNET_asprintf (&arg, "%s:%s", hostname, baseservicehome); - GNUNET_free (baseservicehome); - if (ret->ssh_port_str == NULL) + if (0 == ((xor_image >> pos) & 1U)) { - ret->proc_arm_copying = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", "-r", - "-q", - servicehome, arg, NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "copying directory with command scp -r %s %s\n", - servicehome, arg); + pos++; + continue; } - else + open_port = (index * 32) + pos; + if (open_port >= system->highport) + return 0; + GNUNET_asprintf (&open_port_str, "%u", (unsigned int) open_port); + ret = NULL; + GNUNET_assert (0 == getaddrinfo (NULL, open_port_str, &hint, &ret)); + GNUNET_free (open_port_str); + bind_status = GNUNET_NO; + for (ai = ret; NULL != ai; ai = ai->ai_next) { - ret->proc_arm_copying = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", "-r", "-P", - ret->ssh_port_str, - "-q", - servicehome, arg, NULL); + socket = GNUNET_NETWORK_socket_create (ai->ai_family, + (GNUNET_YES == is_tcp) ? + SOCK_STREAM : SOCK_DGRAM, + 0); + if (NULL == socket) + continue; + bind_status = GNUNET_NETWORK_socket_bind (socket, + ai->ai_addr, + ai->ai_addrlen); + GNUNET_NETWORK_socket_close (socket); + if (GNUNET_OK != bind_status) + break; } - GNUNET_free (arg); - if (NULL == ret->proc_arm_copying) + port_buckets[index] |= (1U << pos); /* Set the port bit */ + freeaddrinfo (ret); + if (GNUNET_OK == bind_status) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ - ("Could not start `%s' process to copy configuration directory.\n"), - "scp"); - if (0 != UNLINK (ret->cfgfile)) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", - ret->cfgfile); - GNUNET_CONFIGURATION_destroy (ret->cfg); - GNUNET_free_non_null (ret->hostname); - GNUNET_free_non_null (ret->username); - GNUNET_free (ret->cfgfile); - GNUNET_free (ret); - if ((hostkey != NULL) && (0 != UNLINK (hostkeyfile))) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", - hostkeyfile); - GNUNET_free_non_null (hostkeyfile); - GNUNET_assert (GNUNET_OK == GNUNET_DISK_directory_remove (servicehome)); - GNUNET_free (servicehome); - return NULL; + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Found a free port %u\n", (unsigned int) open_port); + return open_port; } - - ret->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, - ret); - GNUNET_free_non_null (hostkeyfile); - GNUNET_free (servicehome); - return ret; + pos++; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No need to copy configuration file since we are running locally.\n"); - ret->phase = SP_COPIED; - /* FIXME: why add_cont? */ - GNUNET_SCHEDULER_add_continuation (&start_fsm, ret, - GNUNET_SCHEDULER_REASON_PREREQ_DONE); } - GNUNET_free_non_null (hostkeyfile); - GNUNET_free (servicehome); - return ret; + return 0; } /** - * Restart (stop and start) a GNUnet daemon. + * Release reservation of a TCP or UDP port for a peer + * (used during GNUNET_TESTING_peer_destroy). * - * @param d the daemon that should be restarted - * @param cb function called once the daemon is (re)started - * @param cb_cls closure for cb + * @param system system to use for reservation tracking + * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP + * @param port reserved port to release */ void -GNUNET_TESTING_daemon_restart (struct GNUNET_TESTING_Daemon *d, - GNUNET_TESTING_NotifyDaemonRunning cb, - void *cb_cls) +GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system, + int is_tcp, + uint16_t port) { - char *arg; - char *del_arg; - - del_arg = NULL; - if (NULL != d->cb) - { - d->dead = GNUNET_YES; + uint32_t *port_buckets; + uint16_t bucket; + uint16_t pos; + + port_buckets = (GNUNET_YES == is_tcp) ? + system->reserved_tcp_ports : system->reserved_udp_ports; + bucket = port / 32; + pos = port % 32; + LOG (GNUNET_ERROR_TYPE_DEBUG, "Releasing port %u\n", port); + if (0 == (port_buckets[bucket] & (1U << pos))) + { + GNUNET_break(0); /* Port was not reserved by us using reserve_port() */ return; } - - d->cb = cb; - d->cb_cls = cb_cls; - - if (d->phase == SP_CONFIG_UPDATE) - { - GNUNET_SCHEDULER_cancel (d->task); - d->phase = SP_START_DONE; - } - if (d->server != NULL) - { - GNUNET_CORE_disconnect (d->server); - d->server = NULL; - } - - if (d->th != NULL) - { - GNUNET_TRANSPORT_get_hello_cancel (d->ghh); - d->ghh = NULL; - GNUNET_TRANSPORT_disconnect (d->th); - d->th = NULL; - } - /* state clean up and notifications */ - GNUNET_free_non_null (d->hello); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Terminating peer `%4s'\n"), - GNUNET_i2s (&d->id)); - d->phase = SP_START_ARMING; - - /* Check if this is a local or remote process */ - if (NULL != d->hostname) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Stopping gnunet-arm with config `%s' on host `%s'.\n", - d->cfgfile, d->hostname); - if (d->username != NULL) - GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname); - else - arg = GNUNET_strdup (d->hostname); - - d->proc_arm_stop = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", - "-q", - arg, "gnunet-arm", - "-c", d->cfgfile, "-e", "-r", NULL); - /* Use -r to restart arm and all services */ - - GNUNET_free (arg); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile); - d->proc_arm_stop = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", - "-c", d->cfgfile, "-e", "-r", NULL); - } - - GNUNET_free_non_null (del_arg); - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, d); - + port_buckets[bucket] &= ~(1U << pos); } /** - * Stops a GNUnet daemon. + * Reserve a SERVICEHOME path for a peer. * - * @param d the daemon that should be stopped - * @param service the name of the service to stop - * @param timeout how long to wait for process for shutdown to complete - * @param cb function called once the daemon was stopped - * @param cb_cls closure for cb + * @param system system to use for reservation tracking + * @return NULL on error, otherwise fresh unique path to use + * as the servicehome for the peer; must be freed by the caller */ -void -GNUNET_TESTING_daemon_stop_service (struct GNUNET_TESTING_Daemon *d, - const char *service, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTING_NotifyCompletion cb, - void *cb_cls) +// static +char * +reserve_path (struct GNUNET_TESTING_System *system) { - char *arg; - - d->dead_cb = cb; - d->dead_cb_cls = cb_cls; + char *reserved_path; - GNUNET_assert (d->running == GNUNET_YES); + GNUNET_asprintf (&reserved_path, + "%s/%u", system->tmppath, system->path_counter++); + return reserved_path; +} - if (d->phase == SP_CONFIG_UPDATE) - { - GNUNET_SCHEDULER_cancel (d->task); - d->phase = SP_START_DONE; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Terminating peer `%4s'\n"), - GNUNET_i2s (&d->id)); - if (d->churned_services != NULL) - { - d->dead_cb (d->dead_cb_cls, "A service has already been turned off!!"); - return; - } - d->phase = SP_SERVICE_SHUTDOWN_START; - d->churned_services = GNUNET_strdup (service); - d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); - /* Check if this is a local or remote process */ - if (NULL != d->hostname) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Stopping gnunet-arm with config `%s' on host `%s'.\n", - d->cfgfile, d->hostname); - if (d->username != NULL) - GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname); - else - arg = GNUNET_strdup (d->hostname); - - d->proc_arm_srv_stop = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", - "-q", - arg, "gnunet-arm", - "-c", d->cfgfile, "-k", service, "-q", - "-T", - GNUNET_TIME_relative_to_string (timeout), - NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Stopping gnunet-arm with command ssh %s gnunet-arm -c %s -k %s -q\n", - arg, "gnunet-arm", d->cfgfile, service); - GNUNET_free (arg); - } - else +/** + * Testing includes a number of pre-created hostkeys for + * faster peer startup. This function can be used to + * access the n-th key of those pre-created hostkeys; note + * that these keys are ONLY useful for testing and not + * secure as the private keys are part of the public + * GNUnet source code. + * + * This is primarily a helper function used internally + * by 'GNUNET_TESTING_peer_configure'. + * + * @param system the testing system handle + * @param key_number desired pre-created hostkey to obtain + * @param id set to the peer's identity (hash of the public + * key; if NULL, GNUNET_SYSERR is returned immediately + * @return NULL on error (not enough keys) + */ +struct GNUNET_CRYPTO_RsaPrivateKey * +GNUNET_TESTING_hostkey_get (const struct GNUNET_TESTING_System *system, + uint32_t key_number, + struct GNUNET_PeerIdentity *id) +{ + struct GNUNET_CRYPTO_RsaPrivateKey *private_key; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; + + if ((NULL == id) || (NULL == system->hostkeys_data)) + return NULL; + if (key_number >= system->total_hostkeys) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile); - d->proc_arm_srv_stop = GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-arm", "gnunet-arm", - "-c", d->cfgfile, "-k", service, "-q", - "-T", - GNUNET_TIME_relative_to_string (timeout), - NULL); + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Key number %u does not exist\n"), key_number); + return NULL; + } + private_key = GNUNET_CRYPTO_rsa_decode_key (system->hostkeys_data + + (key_number * + GNUNET_TESTING_HOSTKEYFILESIZE), + GNUNET_TESTING_HOSTKEYFILESIZE); + if (NULL == private_key) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Error while decoding key %u\n"), key_number); + return NULL; } - - d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); - d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d); + GNUNET_CRYPTO_rsa_key_get_public (private_key, &public_key); + GNUNET_CRYPTO_hash (&public_key, + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &(id->hashPubKey)); + return private_key; } /** - * Forcefully terminate a process and clean up the child. - * - * @param proc handle to process to kill + * Structure for holding data to build new configurations from a configuration + * template */ -static void -kill_and_close_process (struct GNUNET_OS_Process *proc) +struct UpdateContext { - (void) GNUNET_OS_process_kill (proc, SIGKILL); - GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (proc)); - GNUNET_OS_process_destroy (proc); -} + /** + * The system for which we are building configurations + */ + struct GNUNET_TESTING_System *system; + + /** + * The configuration we are building + */ + struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * The customized service home path for this peer + */ + char *service_home; + + /** + * build status - to signal error while building a configuration + */ + int status; +}; /** - * Stops a GNUnet daemon. + * Function to iterate over options. Copies + * the options to the target configuration, + * updating PORT values as needed. * - * @param d the daemon that should be stopped - * @param timeout how long to wait for process for shutdown to complete - * @param cb function called once the daemon was stopped - * @param cb_cls closure for cb - * @param delete_files GNUNET_YES to remove files, GNUNET_NO - * to leave them - * @param allow_restart GNUNET_YES to restart peer later (using this API) - * GNUNET_NO to kill off and clean up for good + * @param cls the UpdateContext + * @param section name of the section + * @param option name of the option + * @param value value of the option */ -void -GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTING_NotifyCompletion cb, void *cb_cls, - int delete_files, int allow_restart) +static void +update_config (void *cls, const char *section, const char *option, + const char *value) { - char *arg; - char *del_arg; - - d->dead_cb = cb; - d->dead_cb_cls = cb_cls; - - if (NULL != d->cb) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Setting d->dead on peer `%4s'\n"), - GNUNET_i2s (&d->id)); - d->dead = GNUNET_YES; + struct UpdateContext *uc = cls; + unsigned int ival; + char cval[12]; + char uval[128]; + char *single_variable; + char *per_host_variable; + unsigned long long num_per_host; + uint16_t new_port; + + if (GNUNET_OK != uc->status) return; - } - if (NULL != d->proc_arm_start) - { - kill_and_close_process (d->proc_arm_start); - d->proc_arm_start = NULL; - } - if (NULL != d->proc_arm_srv_start) - { - kill_and_close_process (d->proc_arm_srv_start); - d->proc_arm_srv_start = NULL; - } - if (NULL != d->proc_arm_srv_stop) - { - kill_and_close_process (d->proc_arm_srv_stop); - d->proc_arm_srv_stop = NULL; - } - if (NULL != d->proc_arm_copying) - { - kill_and_close_process (d->proc_arm_copying); - d->proc_arm_copying = NULL; - } - if (NULL != d->proc_arm_peerinfo) - { - kill_and_close_process (d->proc_arm_peerinfo); - d->proc_arm_peerinfo = NULL; - } - if ((d->running == GNUNET_NO) && (d->churn == GNUNET_YES)) - { - /* Peer has already been stopped in churn context! - * Free what was left from churning! */ - GNUNET_assert (d->cfg != NULL); - GNUNET_CONFIGURATION_destroy (d->cfg); - if (delete_files == GNUNET_YES) + if (! ((0 == strcmp (option, "PORT")) + || (0 == strcmp (option, "UNIXPATH")) + || (0 == strcmp (option, "HOSTNAME")))) + return; + GNUNET_asprintf (&single_variable, "single_%s_per_host", section); + GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section); + if ((0 == strcmp (option, "PORT")) && (1 == SSCANF (value, "%u", &ival))) + { + if ((ival != 0) && + (GNUNET_YES != + GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, "testing", + single_variable))) { - if (0 != UNLINK (d->cfgfile)) + /* FIXME: What about UDP? */ + new_port = GNUNET_TESTING_reserve_port (uc->system, GNUNET_YES); + if (0 == new_port) { - GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "unlink"); + uc->status = GNUNET_SYSERR; + GNUNET_free (single_variable); + GNUNET_free (per_host_variable); + return; } + GNUNET_snprintf (cval, sizeof (cval), "%u", new_port); + value = cval; } - GNUNET_free (d->cfgfile); - GNUNET_free_non_null (d->hostname); - GNUNET_free_non_null (d->username); - if (NULL != d->dead_cb) - d->dead_cb (d->dead_cb_cls, NULL); - /* FIXME: this should be an assert and the test below - should not be required, but testing is broken... */ - GNUNET_break (NULL == d->proc_arm_stop); - if (NULL == d->proc_arm_stop) - GNUNET_free (d); - return; - } - - del_arg = NULL; - if (delete_files == GNUNET_YES) - { - GNUNET_asprintf (&del_arg, "-d"); - } - - if (d->phase == SP_CONFIG_UPDATE) - { - GNUNET_SCHEDULER_cancel (d->task); - d->phase = SP_START_DONE; - } - /** Move this call to scheduled shutdown as fix for CORE_connect calling daemon_stop? - if (d->server != NULL) + else if ((ival != 0) && + (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, "testing", + single_variable)) && + GNUNET_CONFIGURATION_get_value_number (uc->cfg, "testing", + per_host_variable, + &num_per_host)) { - GNUNET_CORE_disconnect (d->server); - d->server = NULL; + /* GNUNET_snprintf (cval, sizeof (cval), "%u", */ + /* ival + ctx->fdnum % num_per_host); */ + /* value = cval; */ + GNUNET_break (0); /* FIXME */ } - */ - /* shutdown ARM process (will terminate others) */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Terminating peer `%4s'\n" , - GNUNET_i2s (&d->id)); - d->phase = SP_SHUTDOWN_START; - d->running = GNUNET_NO; - if (allow_restart == GNUNET_YES) - d->churn = GNUNET_YES; - if (d->th != NULL) - { - GNUNET_TRANSPORT_get_hello_cancel (d->ghh); - d->ghh = NULL; - GNUNET_TRANSPORT_disconnect (d->th); - d->th = NULL; } - /* Check if this is a local or remote process */ - - - if (NULL != d->hostname) + if (0 == strcmp (option, "UNIXPATH")) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Stopping gnunet-arm with config `%s' on host `%s'.\n", - d->cfgfile, d->hostname); - if (d->username != NULL) - GNUNET_asprintf (&arg, "%s@%s", d->username, d->hostname); - else - arg = GNUNET_strdup (d->hostname); - - d->proc_arm_stop = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", - "-q", - arg, "gnunet-arm", - "-c", d->cfgfile, "-e", "-q", "-T", - GNUNET_TIME_relative_to_string (timeout), - del_arg, NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Stopping gnunet-arm with command ssh %s gnunet-arm -c %s -e -q %s\n", - arg, "gnunet-arm", d->cfgfile, del_arg); - /* Use -e to end arm, and -d to remove temp files */ - GNUNET_free (arg); + if (GNUNET_YES != + GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, "testing", + single_variable)) + { + GNUNET_snprintf (uval, sizeof (uval), "%s/%s.sock", + uc->service_home, section); + value = uval; + } + else if ((GNUNET_YES == + GNUNET_CONFIGURATION_get_value_number (uc->cfg, "testing", + per_host_variable, + &num_per_host)) && + (num_per_host > 0)) + { + GNUNET_break(0); /* FIXME */ + } } - else + if (0 == strcmp (option, "HOSTNAME")) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Stopping gnunet-arm with config `%s' locally.\n", d->cfgfile); - d->proc_arm_stop = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "gnunet-arm", "gnunet-arm", - "-c", d->cfgfile, "-e", "-q", "-T", - GNUNET_TIME_relative_to_string (timeout), - del_arg, NULL); - GNUNET_assert (NULL != d->proc_arm_stop); + value = (NULL == uc->system->hostname) ? "localhost" : uc->system->hostname; } - - GNUNET_free_non_null (del_arg); - d->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); - if (GNUNET_SCHEDULER_NO_TASK != d->task) - GNUNET_SCHEDULER_cancel(d->task); - d->task = GNUNET_SCHEDULER_add_now (&start_fsm, d); + GNUNET_free (single_variable); + GNUNET_free (per_host_variable); + GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, option, value); } /** - * Changes the configuration of a GNUnet daemon. + * Section iterator to set ACCEPT_FROM/ACCEPT_FROM6 to include the address of + * 'trusted_hosts' in all sections * - * @param d the daemon that should be modified - * @param cfg the new configuration for the daemon - * @param cb function called once the configuration was changed - * @param cb_cls closure for cb + * @param cls the UpdateContext + * @param section name of the section */ -void -GNUNET_TESTING_daemon_reconfigure (struct GNUNET_TESTING_Daemon *d, - struct GNUNET_CONFIGURATION_Handle *cfg, - GNUNET_TESTING_NotifyCompletion cb, - void *cb_cls) +static void +update_config_sections (void *cls, + const char *section) { - char *arg; - - if (d->phase != SP_START_DONE) - { - if (NULL != cb) - cb (cb_cls, - _ - ("Peer not yet running, can not change configuration at this point.")); - return; + struct UpdateContext *uc = cls; + char **ikeys; + char *val; + char *ptr; + char *orig_allowed_hosts; + char *allowed_hosts; + char *ACCEPT_FROM_key; + uint16_t ikeys_cnt; + uint16_t key; + + ikeys_cnt = 0; + val = NULL; + if (GNUNET_YES == GNUNET_CONFIGURATION_have_value (uc->cfg, section, + "TESTING_IGNORE_KEYS")) + { + GNUNET_assert + (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_string (uc->cfg, section, + "TESTING_IGNORE_KEYS", &val)); + ptr = val; + for (ikeys_cnt = 0; NULL != (ptr = strstr (ptr, ";")); ikeys_cnt++) + ptr++; + if (0 == ikeys_cnt) + GNUNET_break (0); + else + { + ikeys = GNUNET_malloc ((sizeof (char *)) * ikeys_cnt); + ptr = val; + for (key = 0; key < ikeys_cnt; key++) + { + ikeys[key] = ptr; + ptr = strstr (ptr, ";"); + *ptr = '\0'; + ptr++; + } + } } - - /* 1) write configuration to temporary file */ - if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, d->cfgfile)) + if (0 != ikeys_cnt) { - if (NULL != cb) - cb (cb_cls, _("Failed to write new configuration to disk.")); - return; + for (key = 0; key < ikeys_cnt; key++) + { + if (NULL != strstr (ikeys[key], "ADVERTISED_PORT")) + break; + } + if ((key == ikeys_cnt) && + (GNUNET_YES == GNUNET_CONFIGURATION_have_value (uc->cfg, section, + "ADVERTISED_PORT"))) + { + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (uc->cfg, section, "PORT", &ptr)) + { + GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, + "ADVERTISED_PORT", ptr); + GNUNET_free (ptr); + } + } + for (key = 0; key < ikeys_cnt; key++) + { + if (NULL != strstr (ikeys[key], "ACCEPT_FROM")) + { + GNUNET_free (ikeys); + GNUNET_free (val); + return; + } + } + GNUNET_free (ikeys); } - - /* 2) copy file to remote host (if necessary) */ - if (NULL == d->hostname) + GNUNET_free_non_null (val); + ACCEPT_FROM_key = "ACCEPT_FROM"; + if ((NULL != uc->system->trusted_ip) && + (NULL != strstr (uc->system->trusted_ip, ":"))) /* IPv6 in use */ + ACCEPT_FROM_key = "ACCEPT_FROM6"; + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (uc->cfg, section, ACCEPT_FROM_key, + &orig_allowed_hosts)) { - /* signal success */ - if (NULL != cb) - cb (cb_cls, NULL); - return; + orig_allowed_hosts = GNUNET_strdup ("127.0.0.1;"); } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Copying updated configuration file to remote host `%s'.\n", - d->hostname); - d->phase = SP_CONFIG_UPDATE; - if (NULL != d->username) - GNUNET_asprintf (&arg, "%s@%s:%s", d->username, d->hostname, d->cfgfile); + if (NULL == uc->system->trusted_ip) + allowed_hosts = GNUNET_strdup (orig_allowed_hosts); else - GNUNET_asprintf (&arg, "%s:%s", d->hostname, d->cfgfile); - d->proc_arm_copying = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", - "-q", - d->cfgfile, arg, NULL); - GNUNET_free (arg); - if (NULL == d->proc_arm_copying) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Could not start `%s' process to copy configuration file.\n"), - "scp"); - if (NULL != cb) - cb (cb_cls, _("Failed to copy new configuration to remote machine.")); - d->phase = SP_START_DONE; - return; - } - d->update_cb = cb; - d->update_cb_cls = cb_cls; - d->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, &start_fsm, d); + GNUNET_asprintf (&allowed_hosts, "%s%s;", orig_allowed_hosts, + uc->system->trusted_ip); + GNUNET_free (orig_allowed_hosts); + GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, ACCEPT_FROM_key, + allowed_hosts); + GNUNET_free (allowed_hosts); } /** - * Data kept for each pair of peers that we try - * to connect. + * Create a new configuration using the given configuration as a template; + * ports and paths will be modified to select available ports on the local + * system. The default configuration will be available in PATHS section under + * the option DEFAULTCONFIG after the call. SERVICE_HOME is also set in PATHS + * section to the temporary directory specific to this configuration. If we run + * out of "*port" numbers, return SYSERR. + * + * This is primarily a helper function used internally + * by 'GNUNET_TESTING_peer_configure'. + * + * @param system system to use to coordinate resource usage + * @param cfg template configuration to update + * @return GNUNET_OK on success, GNUNET_SYSERR on error - the configuration will + * be incomplete and should not be used there upon */ -struct GNUNET_TESTING_ConnectContext +int +GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system, + struct GNUNET_CONFIGURATION_Handle *cfg) { - /** - * Testing handle to the first daemon. - */ - struct GNUNET_TESTING_Daemon *d1; - - /** - * Handle to core of first daemon (to check connect) - */ - struct GNUNET_CORE_Handle *d1core; - - /** - * Have we actually connected to the core of the first daemon yet? - */ - int d1core_ready; - - /** - * Testing handle to the second daemon. - */ - struct GNUNET_TESTING_Daemon *d2; - - /** - * Transport handle to the first daemon (to offer the HELLO of the second daemon to). - */ - struct GNUNET_TRANSPORT_Handle *d1th; - - /** - * Function to call once we are done (or have timed out). - */ - GNUNET_TESTING_NotifyConnection cb; - - /** - * Closure for "nb". - */ - void *cb_cls; - - /** - * The relative timeout from whence this connect attempt was - * started. Allows for reconnect attempts. - */ - struct GNUNET_TIME_Relative relative_timeout; - - /** - * Maximum number of connect attempts, will retry connection - * this number of times on failures. - */ - unsigned int connect_attempts; - - /** - * Hello timeout task - */ - GNUNET_SCHEDULER_TaskIdentifier hello_send_task; - - /** - * Connect timeout task - */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; - - /** - * When should this operation be complete (or we must trigger - * a timeout). - */ - struct GNUNET_TIME_Relative timeout_hello; - - /** - * Was the connection attempt successful? - */ - int connected; - - /** - * When connecting, do we need to send the HELLO? - */ - int send_hello; - - /** - * The distance between the two connected peers - */ - uint32_t distance; -}; - - -/** Forward declaration **/ -static void -reattempt_daemons_connect (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); + struct UpdateContext uc; + char *default_config; + + uc.system = system; + uc.cfg = cfg; + uc.status = GNUNET_OK; + GNUNET_asprintf (&uc.service_home, "%s/%u", system->tmppath, + system->path_counter++); + GNUNET_asprintf (&default_config, "%s/config", uc.service_home); + GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "DEFAULTCONFIG", + default_config); + GNUNET_free (default_config); + GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "SERVICEHOME", + uc.service_home); + /* make PORTs and UNIXPATHs unique */ + GNUNET_CONFIGURATION_iterate (cfg, &update_config, &uc); + /* allow connections to services from system trusted_ip host */ + GNUNET_CONFIGURATION_iterate_sections (cfg, &update_config_sections, &uc); + /* enable loopback-based connections between peers */ + GNUNET_CONFIGURATION_set_value_string (cfg, + "nat", + "USE_LOCALADDR", "YES"); + GNUNET_free (uc.service_home); + return uc.status; +} /** - * Notify callback about success or failure of the attempt - * to connect the two peers + * Configure a GNUnet peer. GNUnet must be installed on the local + * system and available in the PATH. * - * @param cls our "struct GNUNET_TESTING_ConnectContext" (freed) - * @param tc reason tells us if we succeeded or failed + * @param system system to use to coordinate resource usage + * @param cfg configuration to use; will be UPDATED (to reflect needed + * changes in port numbers and paths) + * @param key_number number of the hostkey to use for the peer + * @param id identifier for the daemon, will be set, can be NULL + * @param emsg set to freshly allocated error message (set to NULL on success), + * can be NULL + * @return handle to the peer, NULL on error */ -static void -notify_connect_result (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +struct GNUNET_TESTING_Peer * +GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system, + struct GNUNET_CONFIGURATION_Handle *cfg, + uint32_t key_number, + struct GNUNET_PeerIdentity *id, + char **emsg) { - struct GNUNET_TESTING_ConnectContext *ctx = cls; - - ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK; - if (ctx->hello_send_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (ctx->hello_send_task); - ctx->hello_send_task = GNUNET_SCHEDULER_NO_TASK; + struct GNUNET_TESTING_Peer *peer; + struct GNUNET_DISK_FileHandle *fd; + char *service_home; + char hostkey_filename[128]; + char *config_filename; + char *libexec_binary; + char *emsg_; + struct GNUNET_CRYPTO_RsaPrivateKey *pk; + + if (NULL != emsg) + *emsg = NULL; + if (GNUNET_OK != GNUNET_TESTING_configuration_create (system, cfg)) + { + GNUNET_asprintf (&emsg_, + _("Failed to create configuration for peer (not enough free ports?)\n")); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", emsg_); + if (NULL != emsg) + *emsg = emsg_; + else + GNUNET_free (emsg_); + return NULL; } - - if (ctx->d1th != NULL) - GNUNET_TRANSPORT_disconnect (ctx->d1th); - ctx->d1th = NULL; - if (ctx->d1core != NULL) - GNUNET_CORE_disconnect (ctx->d1core); - ctx->d1core = NULL; - - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) + if (key_number >= system->total_hostkeys) { - GNUNET_free (ctx); - return; + GNUNET_asprintf (&emsg_, + _("You attempted to create a testbed with more than %u hosts. Please precompute more hostkeys first.\n"), + (unsigned int) system->total_hostkeys); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", emsg_); + if (NULL != emsg) + *emsg = emsg_; + else + GNUNET_free (emsg_); + return NULL; } - - if (ctx->connected == GNUNET_YES) + pk = NULL; + if ((NULL != id) && + (NULL == (pk = GNUNET_TESTING_hostkey_get (system, key_number, id)))) { - if (ctx->cb != NULL) - { - ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->distance, - ctx->d1->cfg, ctx->d2->cfg, ctx->d1, ctx->d2, NULL); - } + GNUNET_asprintf (&emsg_, + _("Failed to initialize hostkey for peer %u\n"), + (unsigned int) key_number); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", emsg_); + if (NULL != emsg) + *emsg = emsg_; + else + GNUNET_free (emsg_); + return NULL; } - else if (ctx->connect_attempts > 0) - { - ctx->d1core_ready = GNUNET_NO; - ctx->timeout_task = - GNUNET_SCHEDULER_add_now (&reattempt_daemons_connect, ctx); - return; + if (NULL != pk) + GNUNET_CRYPTO_rsa_key_free (pk); + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", + "SERVICEHOME", + &service_home)); + GNUNET_snprintf (hostkey_filename, sizeof (hostkey_filename), "%s/.hostkey", + service_home); + GNUNET_free (service_home); + fd = GNUNET_DISK_file_open (hostkey_filename, + GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, + GNUNET_DISK_PERM_USER_READ + | GNUNET_DISK_PERM_USER_WRITE); + if (NULL == fd) + { + GNUNET_break (0); + return NULL; } - else + if (GNUNET_TESTING_HOSTKEYFILESIZE != + GNUNET_DISK_file_write (fd, system->hostkeys_data + + (key_number * GNUNET_TESTING_HOSTKEYFILESIZE), + GNUNET_TESTING_HOSTKEYFILESIZE)) + { + GNUNET_asprintf (&emsg_, + _("Failed to write hostkey file for peer %u: %s\n"), + (unsigned int) key_number, + STRERROR (errno)); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", emsg_); + if (NULL != emsg) + *emsg = emsg_; + else + GNUNET_free (emsg_); + GNUNET_DISK_file_close (fd); + return NULL; + } + GNUNET_DISK_file_close (fd); + GNUNET_assert (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string + (cfg, "PATHS", "DEFAULTCONFIG", &config_filename)); + if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, config_filename)) + { + GNUNET_asprintf (&emsg_, + _("Failed to write configuration file `%s' for peer %u: %s\n"), + config_filename, + (unsigned int) key_number, + STRERROR (errno)); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", emsg_); + if (NULL != emsg) + *emsg = emsg_; + else + GNUNET_free (emsg_); + GNUNET_free (config_filename); + return NULL; + } + peer = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Peer)); + peer->cfgfile = config_filename; /* Free in peer_destroy */ + libexec_binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm"); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "arm", "PREFIX", &peer->main_binary)) { - if (ctx->cb != NULL) - { - ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg, - ctx->d2->cfg, ctx->d1, ctx->d2, _("Peers failed to connect")); - } + /* No prefix */ + GNUNET_asprintf(&peer->main_binary, "%s", libexec_binary); + peer->args = strdup (""); } - GNUNET_free (ctx); + else + peer->args = strdup (libexec_binary); + peer->system = system; + peer->key_number = key_number; + GNUNET_free (libexec_binary); + return peer; } /** - * Success, connection is up. Signal client our success. - * - * @param cls our "struct GNUNET_TESTING_ConnectContext" - * @param peer identity of the peer that has connected - * @param atsi performance information - * @param atsi_count number of records in 'atsi' + * Obtain the peer identity from a peer handle. * + * @param peer peer handle for which we want the peer's identity + * @param id identifier for the daemon, will be set */ -static void -connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_ATS_Information *atsi, - unsigned int atsi_count) +void +GNUNET_TESTING_peer_get_identity (const struct GNUNET_TESTING_Peer *peer, + struct GNUNET_PeerIdentity *id) { - struct GNUNET_TESTING_ConnectContext *ctx = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected peer %s to peer %s\n", - ctx->d1->shortname, GNUNET_i2s (peer)); - if (0 != memcmp (&ctx->d2->id, peer, sizeof (struct GNUNET_PeerIdentity))) - return; - ctx->connected = GNUNET_YES; - ctx->distance = 0; /* FIXME: distance */ - if (ctx->hello_send_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (ctx->hello_send_task); - ctx->hello_send_task = GNUNET_SCHEDULER_NO_TASK; - } - GNUNET_SCHEDULER_cancel (ctx->timeout_task); - ctx->timeout_task = GNUNET_SCHEDULER_add_now (¬ify_connect_result, ctx); + GNUNET_CRYPTO_rsa_key_free (GNUNET_TESTING_hostkey_get (peer->system, + peer->key_number, + id)); } -static void -send_hello (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +/** + * Start the peer. + * + * @param peer peer to start + * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer already running) + */ +int +GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer) { - struct GNUNET_TESTING_ConnectContext *ctx = cls; - struct GNUNET_MessageHeader *hello; - - ctx->hello_send_task = GNUNET_SCHEDULER_NO_TASK; - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) - return; - if ((ctx->d1core_ready == GNUNET_YES) && (ctx->d2->hello != NULL) && - (NULL != GNUNET_HELLO_get_header (ctx->d2->hello)) && - (ctx->d1->phase == SP_START_DONE) && (ctx->d2->phase == SP_START_DONE)) + if (NULL != peer->main_process) { - hello = GNUNET_HELLO_get_header (ctx->d2->hello); - GNUNET_assert (hello != NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Offering hello of %s to %s\n", - ctx->d2->shortname, ctx->d1->shortname); - GNUNET_TRANSPORT_offer_hello (ctx->d1th, hello, NULL, NULL); - GNUNET_assert (ctx->d1core != NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending connect request to TRANSPORT of %s for peer %s\n", - GNUNET_i2s (&ctx->d1->id), - GNUNET_h2s (&ctx->d2->id.hashPubKey)); - GNUNET_TRANSPORT_try_connect (ctx->d1th, &ctx->d2->id); - ctx->timeout_hello = - GNUNET_TIME_relative_add (ctx->timeout_hello, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 500)); + GNUNET_break (0); + return GNUNET_SYSERR; } - ctx->hello_send_task = - GNUNET_SCHEDULER_add_delayed (ctx->timeout_hello, &send_hello, ctx); + GNUNET_assert (NULL != peer->cfgfile); + peer->main_process = GNUNET_OS_start_process (PIPE_CONTROL, + GNUNET_OS_INHERIT_STD_OUT_AND_ERR, + NULL, NULL, + peer->main_binary, + peer->main_binary, + peer->args, + "-c", + peer->cfgfile, + NULL); + if (NULL == peer->main_process) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to start `%s': %s\n"), + peer->main_binary, + STRERROR (errno)); + return GNUNET_SYSERR; + } + return GNUNET_OK; } + /** - * Notify of a successful connection to the core service. + * Sends SIGTERM to the peer's main process * - * @param cls a ConnectContext - * @param server handle to the core service - * @param my_identity the peer identity of this peer + * @param peer the handle to the peer + * @return GNUNET_OK if successful; GNUNET_SYSERR if the main process is NULL + * or upon any error while sending SIGTERM */ -void -core_init_notify (void *cls, struct GNUNET_CORE_Handle *server, - const struct GNUNET_PeerIdentity *my_identity) +int +GNUNET_TESTING_peer_kill (struct GNUNET_TESTING_Peer *peer) { - struct GNUNET_TESTING_ConnectContext *connect_ctx = cls; - - connect_ctx->d1core_ready = GNUNET_YES; - - if (connect_ctx->send_hello == GNUNET_NO) + if (NULL == peer->main_process) { - GNUNET_TRANSPORT_try_connect (connect_ctx->d1th, &connect_ctx->d2->id); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending connect request to TRANSPORT of %s for peer %s\n", - connect_ctx->d1->shortname, connect_ctx->d2->shortname); + GNUNET_break (0); + return GNUNET_SYSERR; } + return (0 == GNUNET_OS_process_kill (peer->main_process, SIGTERM)) ? + GNUNET_OK : GNUNET_SYSERR; } /** - * Try to connect again some peers that failed in an earlier attempt. This will - * be tried as many times as connection_attempts in the configuration file. + * Waits for a peer to terminate. The peer's main process will also be destroyed. * - * @param cls Closure (connection context between the two peers). - * @param tc TaskContext. + * @param peer the handle to the peer + * @return GNUNET_OK if successful; GNUNET_SYSERR if the main process is NULL + * or upon any error while waiting */ -static void -reattempt_daemons_connect (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +int +GNUNET_TESTING_peer_wait (struct GNUNET_TESTING_Peer *peer) { - struct GNUNET_TESTING_ConnectContext *ctx = cls; + int ret; - ctx->timeout_task = GNUNET_SCHEDULER_NO_TASK; - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) - return; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "re-attempting connect of peer %s to peer %s\n", - ctx->d1->shortname, ctx->d2->shortname); - ctx->connect_attempts--; - GNUNET_assert (ctx->d1core == NULL); - ctx->d1core_ready = GNUNET_NO; - ctx->d1core = - GNUNET_CORE_connect (ctx->d1->cfg, 1, ctx, &core_init_notify, - &connect_notify, NULL, NULL, GNUNET_NO, NULL, - GNUNET_NO, no_handlers); - if (ctx->d1core == NULL) + if (NULL == peer->main_process) { - if (NULL != ctx->cb) - ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg, - ctx->d2->cfg, ctx->d1, ctx->d2, - _("Failed to connect to core service of first peer!\n")); - GNUNET_free (ctx); - return; + GNUNET_break (0); + return GNUNET_SYSERR; } + ret = GNUNET_OS_process_wait (peer->main_process); + GNUNET_OS_process_destroy (peer->main_process); + peer->main_process = NULL; + return ret; +} - /* Don't know reason for initial connect failure, update the HELLO for the second peer */ - if (NULL != ctx->d2->hello) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "updating %s's HELLO\n", - ctx->d2->shortname); - GNUNET_free (ctx->d2->hello); - ctx->d2->hello = NULL; - if (NULL != ctx->d2->th) - { - GNUNET_TRANSPORT_get_hello_cancel (ctx->d2->ghh); - ctx->d2->ghh = NULL; - GNUNET_TRANSPORT_disconnect (ctx->d2->th); - } - ctx->d2->th = - GNUNET_TRANSPORT_connect (ctx->d2->cfg, &ctx->d2->id, NULL, NULL, NULL, - NULL); - GNUNET_assert (ctx->d2->th != NULL); - ctx->d2->ghh = - GNUNET_TRANSPORT_get_hello (ctx->d2->th, &process_hello, ctx->d2); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "didn't have %s's HELLO\n", - ctx->d2->shortname); - } - if ((NULL == ctx->d2->hello) && (ctx->d2->th == NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "didn't have %s's HELLO, trying to get it now\n", - ctx->d2->shortname); - ctx->d2->th = - GNUNET_TRANSPORT_connect (ctx->d2->cfg, &ctx->d2->id, NULL, NULL, NULL, - NULL); - if (NULL == ctx->d2->th) - { - GNUNET_CORE_disconnect (ctx->d1core); - GNUNET_free (ctx); - if (NULL != ctx->cb) - ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg, - ctx->d2->cfg, ctx->d1, ctx->d2, - _("Failed to connect to transport service!\n")); - return; - } - ctx->d2->ghh = - GNUNET_TRANSPORT_get_hello (ctx->d2->th, &process_hello, ctx->d2); - } - else - { - if (NULL == ctx->d2->hello) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "didn't have %s's HELLO but th wasn't NULL, not trying!!\n", - ctx->d2->shortname); - } - } +/** + * Stop the peer. + * + * @param peer peer to stop + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer) +{ + if (GNUNET_SYSERR == GNUNET_TESTING_peer_kill (peer)) + return GNUNET_SYSERR; + if (GNUNET_SYSERR == GNUNET_TESTING_peer_wait (peer)) + return GNUNET_SYSERR; + return GNUNET_OK; +} - if (ctx->send_hello == GNUNET_YES) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending %s's HELLO to %s\n", - ctx->d1->shortname, ctx->d2->shortname); - ctx->d1th = - GNUNET_TRANSPORT_connect (ctx->d1->cfg, &ctx->d1->id, ctx->d1, NULL, - NULL, NULL); - if (ctx->d1th == NULL) - { - GNUNET_CORE_disconnect (ctx->d1core); - GNUNET_free (ctx); - if (NULL != ctx->cb) - ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, 0, ctx->d1->cfg, - ctx->d2->cfg, ctx->d1, ctx->d2, - _("Failed to connect to transport service!\n")); - return; - } - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == ctx->hello_send_task); - ctx->hello_send_task = GNUNET_SCHEDULER_add_now (&send_hello, ctx); - } - else + +/** + * Destroy the peer. Releases resources locked during peer configuration. + * If the peer is still running, it will be stopped AND a warning will be + * printed (users of the API should stop the peer explicitly first). + * + * @param peer peer to destroy + */ +void +GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer) +{ + if (NULL != peer->main_process) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to reconnect %s to %s\n", - ctx->d1->shortname, ctx->d2->shortname); - GNUNET_TRANSPORT_try_connect (ctx->d1th, &ctx->d2->id); + GNUNET_break (0); + GNUNET_TESTING_peer_stop (peer); } - ctx->timeout_task = - GNUNET_SCHEDULER_add_delayed (ctx->relative_timeout, - ¬ify_connect_result, ctx); + GNUNET_free (peer->cfgfile); + GNUNET_free (peer->main_binary); + GNUNET_free (peer->args); + GNUNET_free (peer); } + /** - * Iterator for currently known peers, to ensure - * that we don't try to send duplicate connect - * requests to core. - * - * @param cls our "struct GNUNET_TESTING_ConnectContext" - * @param peer identity of the peer that has connected, - * NULL when iteration has finished - * @param atsi performance information - * @param atsi_count number of records in 'atsi' + * Start a single peer and run a test using the testing library. + * Starts a peer using the given configuration and then invokes the + * given callback. This function ALSO initializes the scheduler loop + * and should thus be called directly from "main". The testcase + * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'. * + * @param testdir only the directory name without any path. This is used for + * all service homes; the directory will be created in a temporary + * location depending on the underlying OS + * @param cfgfilename name of the configuration file to use; + * use NULL to only run with defaults + * @param tm main function of the testcase + * @param tm_cls closure for 'tm' + * @return 0 on success, 1 on error */ -static void -core_initial_iteration (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_ATS_Information *atsi, - unsigned int atsi_count) +int +GNUNET_TESTING_peer_run (const char *testdir, + const char *cfgfilename, + GNUNET_TESTING_TestMain tm, + void *tm_cls) { - struct GNUNET_TESTING_ConnectContext *ctx = cls; - - if ((peer != NULL) && - (0 == memcmp (&ctx->d2->id, peer, sizeof (struct GNUNET_PeerIdentity)))) - { - ctx->connected = GNUNET_YES; - ctx->distance = 0; /* FIXME: distance */ - return; - } - if (peer != NULL) - return; /* ignore other peers */ - /* peer == NULL: End of iteration over peers */ + return GNUNET_TESTING_service_run (testdir, "arm", + cfgfilename, tm, tm_cls); +} - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == ctx->timeout_task); - if (ctx->connected == GNUNET_YES) - { - ctx->timeout_task = GNUNET_SCHEDULER_add_now (¬ify_connect_result, ctx); - return; - } - /* Peer not already connected, need to schedule connect request! */ - if (ctx->d1core == NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peers are NOT connected, connecting to core!\n"); - ctx->d1core = - GNUNET_CORE_connect (ctx->d1->cfg, 1, ctx, &core_init_notify, - &connect_notify, NULL, NULL, GNUNET_NO, NULL, - GNUNET_NO, no_handlers); - } +/** + * Structure for holding service data + */ +struct ServiceContext +{ + /** + * The configuration of the peer in which the service is run + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; - if (ctx->d1core == NULL) - { - ctx->timeout_task = GNUNET_SCHEDULER_add_now (¬ify_connect_result, ctx); - return; - } + /** + * Callback to signal service startup + */ + GNUNET_TESTING_TestMain tm; + + /** + * The peer in which the service is run. + */ + struct GNUNET_TESTING_Peer *peer; - if ((NULL == ctx->d2->hello) && (ctx->d2->th == NULL)) /* Do not yet have the second peer's hello, set up a task to get it */ - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Don't have d2's HELLO, trying to get it!\n"); - ctx->d2->th = - GNUNET_TRANSPORT_connect (ctx->d2->cfg, &ctx->d2->id, NULL, NULL, NULL, - NULL); - if (ctx->d2->th == NULL) - { - GNUNET_CORE_disconnect (ctx->d1core); - ctx->d1core = NULL; - ctx->timeout_task = - GNUNET_SCHEDULER_add_now (¬ify_connect_result, ctx); - return; - } - ctx->d2->ghh = - GNUNET_TRANSPORT_get_hello (ctx->d2->th, &process_hello, ctx->d2); - } + /** + * Closure for the above callback + */ + void *tm_cls; +}; - if (ctx->send_hello == GNUNET_YES) - { - ctx->d1th = - GNUNET_TRANSPORT_connect (ctx->d1->cfg, &ctx->d1->id, ctx->d1, NULL, - NULL, NULL); - if (ctx->d1th == NULL) - { - GNUNET_CORE_disconnect (ctx->d1core); - ctx->d1core = NULL; - ctx->timeout_task = - GNUNET_SCHEDULER_add_now (¬ify_connect_result, ctx); - return; - } - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == ctx->hello_send_task); - ctx->hello_send_task = GNUNET_SCHEDULER_add_now (&send_hello, ctx); - } - ctx->timeout_task = - GNUNET_SCHEDULER_add_delayed (ctx->relative_timeout, - ¬ify_connect_result, ctx); +/** + * Callback to be called when SCHEDULER has been started + * + * @param cls the ServiceContext + * @param tc the TaskContext + */ +static void +service_run_main (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct ServiceContext *sc = cls; + sc->tm (sc->tm_cls, sc->cfg, sc->peer); } /** - * Establish a connection between two GNUnet daemons. The daemons - * must both be running and not be stopped until either the - * 'cb' callback is called OR the connection request has been - * explicitly cancelled. + * Start a single service (no ARM, except of course if the given + * service name is 'arm') and run a test using the testing library. + * Starts a service using the given configuration and then invokes the + * given callback. This function ALSO initializes the scheduler loop + * and should thus be called directly from "main". The testcase + * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'. * - * @param d1 handle for the first daemon - * @param d2 handle for the second daemon - * @param timeout how long is the connection attempt - * allowed to take? - * @param max_connect_attempts how many times should we try to reconnect - * (within timeout) - * @param send_hello GNUNET_YES to send the HELLO, GNUNET_NO to assume - * the HELLO has already been exchanged - * @param cb function to call at the end - * @param cb_cls closure for cb - * @return handle to cancel the request + * This function is useful if the testcase is for a single service + * and if that service doesn't itself depend on other services. + * + * @param testdir only the directory name without any path. This is used for + * all service homes; the directory will be created in a temporary + * location depending on the underlying OS + * @param service_name name of the service to run + * @param cfgfilename name of the configuration file to use; + * use NULL to only run with defaults + * @param tm main function of the testcase + * @param tm_cls closure for 'tm' + * @return 0 on success, 1 on error */ -struct GNUNET_TESTING_ConnectContext * -GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1, - struct GNUNET_TESTING_Daemon *d2, - struct GNUNET_TIME_Relative timeout, - unsigned int max_connect_attempts, - int send_hello, - GNUNET_TESTING_NotifyConnection cb, - void *cb_cls) +int +GNUNET_TESTING_service_run (const char *testdir, + const char *service_name, + const char *cfgfilename, + GNUNET_TESTING_TestMain tm, + void *tm_cls) { - struct GNUNET_TESTING_ConnectContext *ctx; - - if ((d1->running == GNUNET_NO) || (d2->running == GNUNET_NO)) - { - if (NULL != cb) - cb (cb_cls, &d1->id, &d2->id, 0, d1->cfg, d2->cfg, d1, d2, - _("Peers are not fully running yet, can not connect!\n")); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Peers are not up!\n"); - return NULL; + struct ServiceContext sc; + struct GNUNET_TESTING_System *system; + struct GNUNET_TESTING_Peer *peer; + struct GNUNET_CONFIGURATION_Handle *cfg; + char *binary; + char *libexec_binary; + + GNUNET_log_setup (testdir, "WARNING", NULL); + system = GNUNET_TESTING_system_create (testdir, "127.0.0.1", NULL); + if (NULL == system) + return 1; + cfg = GNUNET_CONFIGURATION_create (); + if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cfgfilename)) + { + LOG (GNUNET_ERROR_TYPE_ERROR, + _("Failed to load configuration from %s\n"), cfgfilename); + GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 1; + } + peer = GNUNET_TESTING_peer_configure (system, cfg, 0, NULL, NULL); + if (NULL == peer) + { + GNUNET_CONFIGURATION_destroy (cfg); + hostkeys_unload (system); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 1; + } + GNUNET_free (peer->main_binary); + GNUNET_free (peer->args); + GNUNET_asprintf (&binary, "gnunet-service-%s", service_name); + libexec_binary = GNUNET_OS_get_libexec_binary_path (binary); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, service_name, "PREFIX", &peer->main_binary)) + { + /* No prefix */ + GNUNET_asprintf(&peer->main_binary, "%s", libexec_binary); + peer->args = strdup (""); } - - ctx = GNUNET_malloc (sizeof (struct GNUNET_TESTING_ConnectContext)); - ctx->d1 = d1; - ctx->d2 = d2; - ctx->timeout_hello = - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500); - ctx->relative_timeout = - GNUNET_TIME_relative_divide (timeout, max_connect_attempts); - ctx->cb = cb; - ctx->cb_cls = cb_cls; - ctx->connect_attempts = max_connect_attempts; - ctx->connected = GNUNET_NO; - ctx->send_hello = send_hello; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asked to connect peer %s to peer %s\n", - d1->shortname, d2->shortname); - /* Core is up! Iterate over all _known_ peers first to check if we are already connected to the peer! */ - GNUNET_assert (NULL != - GNUNET_CORE_is_peer_connected (ctx->d1->cfg, &ctx->d2->id, - &core_initial_iteration, ctx)); - return ctx; + else + peer->args = strdup (libexec_binary); + + GNUNET_free (libexec_binary); + GNUNET_free (binary); + if (GNUNET_OK != GNUNET_TESTING_peer_start (peer)) + { + GNUNET_TESTING_peer_destroy (peer); + GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 1; + } + sc.cfg = cfg; + sc.tm = tm; + sc.tm_cls = tm_cls; + sc.peer = peer; + GNUNET_SCHEDULER_run (&service_run_main, &sc); /* Scheduler loop */ + if ((NULL != peer->main_process) && + (GNUNET_OK != GNUNET_TESTING_peer_stop (peer))) + { + GNUNET_TESTING_peer_destroy (peer); + GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 1; + } + GNUNET_TESTING_peer_destroy (peer); + GNUNET_CONFIGURATION_destroy (cfg); + GNUNET_TESTING_system_destroy (system, GNUNET_YES); + return 0; } /** - * Cancel an attempt to connect two daemons. + * Sometimes we use the binary name to determine which specific + * test to run. In those cases, the string after the last "_" + * in 'argv[0]' specifies a string that determines the configuration + * file or plugin to use. * - * @param cc connect context + * This function returns the respective substring, taking care + * of issues such as binaries ending in '.exe' on W32. + * + * @param argv0 the name of the binary + * @return string between the last '_' and the '.exe' (or the end of the string), + * NULL if argv0 has no '_' */ -void -GNUNET_TESTING_daemons_connect_cancel (struct GNUNET_TESTING_ConnectContext *cc) +char * +GNUNET_TESTING_get_testname_from_underscore (const char *argv0) { - if (GNUNET_SCHEDULER_NO_TASK != cc->timeout_task) - { - GNUNET_SCHEDULER_cancel (cc->timeout_task); - cc->timeout_task = GNUNET_SCHEDULER_NO_TASK; - } - if (GNUNET_SCHEDULER_NO_TASK != cc->hello_send_task) - { - GNUNET_SCHEDULER_cancel (cc->hello_send_task); - cc->hello_send_task = GNUNET_SCHEDULER_NO_TASK; - } - if (NULL != cc->d1core) - { - GNUNET_CORE_disconnect (cc->d1core); - cc->d1core = NULL; - } - if (NULL != cc->d1th) - { - GNUNET_TRANSPORT_disconnect (cc->d1th); - cc->d1th = NULL; - } - GNUNET_free (cc); + size_t slen = strlen (argv0) + 1; + char sbuf[slen]; + char *ret; + char *dot; + + memcpy (sbuf, argv0, slen); + ret = strrchr (sbuf, '_'); + if (NULL == ret) + return NULL; + ret++; /* skip underscore */ + dot = strchr (ret, '.'); + if (NULL != dot) + *dot = '\0'; + return GNUNET_strdup (ret); } diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c deleted file mode 100644 index 75c0e61..0000000 --- a/src/testing/testing_group.c +++ /dev/null @@ -1,7038 +0,0 @@ -/* - This file is part of GNUnet - (C) 2008, 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 testing/testing_group.c - * @brief convenience API for writing testcases for GNUnet - * @author Nathan Evans - * @author Christian Grothoff - */ -#include "platform.h" -#include "gnunet_constants.h" -#include "gnunet_arm_service.h" -#include "gnunet_testing_lib.h" -#include "gnunet_core_service.h" - -#define USE_START_HELPER GNUNET_YES - -#define OLD 1 - -/* Before connecting peers, send all of the HELLOs */ -#define USE_SEND_HELLOS GNUNET_NO - -#define TOPOLOGY_HACK GNUNET_YES - - -/** - * Lowest port used for GNUnet testing. Should be high enough to not - * conflict with other applications running on the hosts but be low - * enough to not conflict with client-ports (typically starting around - * 32k). - */ -#define LOW_PORT 12000 - -/** - * Highest port used for GNUnet testing. Should be low enough to not - * conflict with the port range for "local" ports (client apps; see - * /proc/sys/net/ipv4/ip_local_port_range on Linux for example). - */ -#define HIGH_PORT 56000 - -/* Maximum time to delay connect attempt */ -#define MAX_CONNECT_DELAY 300 - -/** - * Which list of peers do we need to modify? - */ -enum PeerLists -{ - /** Modify allowed peers */ - ALLOWED, - - /** Modify connect peers */ - CONNECT, - - /** Modify blacklist peers */ - BLACKLIST, - - /** Modify workingset peers */ - WORKING_SET -}; - -/** - * Prototype of a function called whenever two peers would be connected - * in a certain topology. - */ -typedef unsigned int (*GNUNET_TESTING_ConnectionProcessor) (struct - GNUNET_TESTING_PeerGroup - * pg, - unsigned int first, - unsigned int second, - enum PeerLists list, - unsigned int check); - -/** - * Context for handling churning a peer group - */ -struct ChurnContext -{ - /** - * The peergroup we are dealing with. - */ - struct GNUNET_TESTING_PeerGroup *pg; - - /** - * Name of the service to churn on/off, NULL - * to churn entire peer. - */ - char *service; - - /** - * Callback used to notify of churning finished - */ - GNUNET_TESTING_NotifyCompletion cb; - - /** - * Closure for callback - */ - void *cb_cls; - - /** - * Number of peers that still need to be started - */ - unsigned int num_to_start; - - /** - * Number of peers that still need to be stopped - */ - unsigned int num_to_stop; - - /** - * Number of peers that failed to start - */ - unsigned int num_failed_start; - - /** - * Number of peers that failed to stop - */ - unsigned int num_failed_stop; -}; - -struct RestartContext -{ - /** - * The group of peers being restarted - */ - struct GNUNET_TESTING_PeerGroup *peer_group; - - /** - * How many peers have been restarted thus far - */ - unsigned int peers_restarted; - - /** - * How many peers got an error when restarting - */ - unsigned int peers_restart_failed; - - /** - * The function to call once all peers have been restarted - */ - GNUNET_TESTING_NotifyCompletion callback; - - /** - * Closure for callback function - */ - void *callback_cls; - -}; - -struct SendHelloContext -{ - /** - * Global handle to the peer group. - */ - struct GNUNET_TESTING_PeerGroup *pg; - - /** - * The data about this specific peer. - */ - struct PeerData *peer; - - /** - * The next HELLO that needs sent to this peer. - */ - struct PeerConnection *peer_pos; - - /** - * Are we connected to CORE yet? - */ - unsigned int core_ready; - - /** - * How many attempts should we make for failed connections? - */ - unsigned int connect_attempts; - - /** - * Task for scheduling core connect requests to be sent. - */ - GNUNET_SCHEDULER_TaskIdentifier core_connect_task; -}; - -struct ShutdownContext -{ - struct GNUNET_TESTING_PeerGroup *pg; - /** - * Total peers to wait for - */ - unsigned int total_peers; - - /** - * Number of peers successfully shut down - */ - unsigned int peers_down; - - /** - * Number of peers failed to shut down - */ - unsigned int peers_failed; - - /** - * Number of peers we have started shutting - * down. If too many, wait on them. - */ - unsigned int outstanding; - - /** - * Timeout for shutdown. - */ - struct GNUNET_TIME_Relative timeout; - - /** - * Callback to call when all peers either - * shutdown or failed to shutdown - */ - GNUNET_TESTING_NotifyCompletion cb; - - /** - * Closure for cb - */ - void *cb_cls; - - /** - * Should we delete all of the files from the peers? - */ - int delete_files; -}; - -/** - * Individual shutdown context for a particular peer. - */ -struct PeerShutdownContext -{ - /** - * Pointer to the high level shutdown context. - */ - struct ShutdownContext *shutdown_ctx; - - /** - * The daemon handle for the peer to shut down. - */ - struct GNUNET_TESTING_Daemon *daemon; -}; - -/** - * Individual shutdown context for a particular peer. - */ -struct PeerRestartContext -{ - /** - * Pointer to the high level restart context. - */ - struct ChurnRestartContext *churn_restart_ctx; - - /** - * The daemon handle for the peer to shut down. - */ - struct GNUNET_TESTING_Daemon *daemon; -}; - -struct ServiceStartContext -{ - struct GNUNET_TESTING_PeerGroup *pg; - unsigned int remaining; - GNUNET_TESTING_NotifyCompletion cb; - unsigned int outstanding; - char *service; - struct GNUNET_TIME_Relative timeout; - void *cb_cls; -}; - -/** - * Individual shutdown context for a particular peer. - */ -struct PeerServiceStartContext -{ - /** - * Pointer to the high level start context. - */ - struct ServiceStartContext *start_ctx; - - /** - * The daemon handle for the peer to start the service on. - */ - struct GNUNET_TESTING_Daemon *daemon; -}; - -struct CreateTopologyContext -{ - - /** - * Function to call with number of connections - */ - GNUNET_TESTING_NotifyConnections cont; - - /** - * Closure for connection notification - */ - void *cls; -}; - -enum States -{ - /** Waiting to read number of peers */ - NUM_PEERS, - - /** Should find next peer index */ - PEER_INDEX, - - /** Should find colon */ - COLON, - - /** Should read other peer index, space, or endline */ - OTHER_PEER_INDEX -}; - -#if OLD -struct PeerConnection -{ - /** - * Doubly Linked list - */ - struct PeerConnection *prev; - - /* - * Doubly Linked list - */ - struct PeerConnection *next; - - /* - * Index of daemon in pg->peers - */ - uint32_t index; - -}; -#endif - -struct InternalStartContext -{ - /** - * Pointer to peerdata - */ - struct PeerData *peer; - - /** - * Timeout for peer startup - */ - struct GNUNET_TIME_Relative timeout; - - /** - * Client callback for hostkey notification - */ - GNUNET_TESTING_NotifyHostkeyCreated hostkey_callback; - - /** - * Closure for hostkey_callback - */ - void *hostkey_cls; - - /** - * Client callback for peer start notification - */ - GNUNET_TESTING_NotifyDaemonRunning start_cb; - - /** - * Closure for cb - */ - void *start_cb_cls; - - /** - * Hostname, where to start the peer - */ - const char *hostname; - - /** - * Username to use when connecting to the - * host via ssh. - */ - const char *username; - - /** - * Pointer to starting memory location of a hostkey - */ - const char *hostkey; - - /** - * Port to use for ssh. - */ - uint16_t sshport; - -}; - -struct ChurnRestartContext -{ - /** - * PeerGroup that we are working with. - */ - struct GNUNET_TESTING_PeerGroup *pg; - - /** - * Number of restarts currently in flight. - */ - unsigned int outstanding; - - /** - * Handle to the underlying churn context. - */ - struct ChurnContext *churn_ctx; - - /** - * How long to allow the operation to take. - */ - struct GNUNET_TIME_Relative timeout; -}; - -struct OutstandingSSH -{ - struct OutstandingSSH *next; - - struct OutstandingSSH *prev; - - /** - * Number of current ssh connections. - */ - uint32_t outstanding; - - /** - * The hostname of this peer. - */ - const char *hostname; -}; - -/** - * Data we keep per peer. - */ -struct PeerData -{ - /** - * (Initial) configuration of the host. - * (initial because clients could change - * it and we would not know about those - * updates). - */ - struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * Handle for controlling the daemon. - */ - struct GNUNET_TESTING_Daemon *daemon; - - /** - * The peergroup this peer belongs to. - */ - struct GNUNET_TESTING_PeerGroup *pg; - -#if OLD - /** - * Linked list of allowed peer connections. - */ - struct PeerConnection *allowed_peers_head; - - /** - * Linked list of allowed peer connections. - */ - struct PeerConnection *allowed_peers_tail; - - /** - * Linked list of blacklisted peer connections. - */ - struct PeerConnection *blacklisted_peers_head; - - /** - * Linked list of blacklisted peer connections. - */ - struct PeerConnection *blacklisted_peers_tail; - - /** - * Linked list of connect peer connections. - */ - struct PeerConnection *connect_peers_head; - - /** - * Linked list of connect peer connections. - */ - struct PeerConnection *connect_peers_tail; - - /** - * Linked list of connect peer connections. - */ - struct PeerConnection *connect_peers_working_set_head; - - /** - * Linked list of connect peer connections. - */ - struct PeerConnection *connect_peers_working_set_tail; - -#else - /** - * Hash map of allowed peer connections (F2F created topology) - */ - struct GNUNET_CONTAINER_MultiHashMap *allowed_peers; - - /** - * Hash map of blacklisted peers - */ - struct GNUNET_CONTAINER_MultiHashMap *blacklisted_peers; - - /** - * Hash map of peer connections - */ - struct GNUNET_CONTAINER_MultiHashMap *connect_peers; - - /** - * Temporary hash map of peer connections - */ - struct GNUNET_CONTAINER_MultiHashMap *connect_peers_working_set; -#endif - - /** - * Temporary variable for topology creation, should be reset before - * creating any topology so the count is valid once finished. - */ - int num_connections; - - /** - * Context to keep track of peers being started, to - * stagger hostkey generation and peer startup. - */ - struct InternalStartContext internal_context; - - /** - * Task ID for the queued internal_continue_startup task - */ - GNUNET_SCHEDULER_TaskIdentifier startup_task; - -}; - -/** - * Linked list of per-host data. - */ -struct HostData -{ - /** - * Name of the host. - */ - char *hostname; - - /** - * SSH username to use when connecting to this host. - */ - char *username; - - /** - * SSH port to use when connecting to this host. - */ - uint16_t sshport; - - /** - * Lowest port that we have not yet used - * for GNUnet. - */ - uint16_t minport; -}; - -struct TopologyIterateContext -{ - /** - * The peergroup we are working with. - */ - struct GNUNET_TESTING_PeerGroup *pg; - - /** - * Callback for notifying of two connected peers. - */ - GNUNET_TESTING_NotifyTopology topology_cb; - - /** - * Closure for topology_cb - */ - void *cls; - - /** - * Number of peers currently connected to. - */ - unsigned int connected; - - /** - * Number of peers we have finished iterating. - */ - unsigned int completed; - - /** - * Number of peers total. - */ - unsigned int total; -}; - -struct StatsIterateContext -{ - /** - * The peergroup that we are dealing with. - */ - struct GNUNET_TESTING_PeerGroup *pg; - - /** - * Continuation to call once all stats information has been retrieved. - */ - GNUNET_STATISTICS_Callback cont; - - /** - * Proc function to call on each value received. - */ - GNUNET_TESTING_STATISTICS_Iterator proc; - - /** - * Closure for topology_cb - */ - void *cls; - - /** - * Number of peers currently connected to. - */ - unsigned int connected; - - /** - * Number of peers we have finished iterating. - */ - unsigned int completed; - - /** - * Number of peers total. - */ - unsigned int total; -}; - -struct CoreContext -{ - void *iter_context; - struct GNUNET_TESTING_Daemon *daemon; -}; - -struct StatsCoreContext -{ - void *iter_context; - struct GNUNET_TESTING_Daemon *daemon; - /** - * Handle to the statistics service. - */ - struct GNUNET_STATISTICS_Handle *stats_handle; - - /** - * Handle for getting statistics. - */ - struct GNUNET_STATISTICS_GetHandle *stats_get_handle; -}; - -struct ConnectTopologyContext -{ - /** - * How many connections are left to create. - */ - unsigned int remaining_connections; - - /** - * Handle to group of peers. - */ - struct GNUNET_TESTING_PeerGroup *pg; - - /** - * How long to try this connection before timing out. - */ - struct GNUNET_TIME_Relative connect_timeout; - - /** - * How many times to retry connecting the two peers. - */ - unsigned int connect_attempts; - - /** - * Temp value set for each iteration. - */ - //struct PeerData *first; - - /** - * Notification that all peers are connected. - */ - GNUNET_TESTING_NotifyCompletion notify_connections_done; - - /** - * Closure for notify. - */ - void *notify_cls; -}; - -struct ConnectContext; - -/** - * Handle to a group of GNUnet peers. - */ -struct GNUNET_TESTING_PeerGroup -{ - /** - * Configuration template. - */ - const struct GNUNET_CONFIGURATION_Handle *cfg; - - struct ConnectContext *cc_head; - - struct ConnectContext *cc_tail; - - /** - * Function to call on each started daemon. - */ - //GNUNET_TESTING_NotifyDaemonRunning cb; - - /** - * Closure for cb. - */ - //void *cb_cls; - - /* - * Function to call on each topology connection created - */ - GNUNET_TESTING_NotifyConnection notify_connection; - - /* - * Callback for notify_connection - */ - void *notify_connection_cls; - - /** - * Array of information about hosts. - */ - struct HostData *hosts; - - /** - * Number of hosts (size of HostData) - */ - unsigned int num_hosts; - - /** - * Array of "total" peers. - */ - struct PeerData *peers; - - /** - * Number of peers in this group. - */ - unsigned int total; - - /** - * At what time should we fail the peer startup process? - */ - struct GNUNET_TIME_Absolute max_timeout; - - /** - * How many peers are being started right now? - */ - unsigned int starting; - - /** - * How many peers have already been started? - */ - unsigned int started; - - /** - * Number of possible connections to peers - * at a time. - */ - unsigned int max_outstanding_connections; - - /** - * Number of ssh connections to peers (max). - */ - unsigned int max_concurrent_ssh; - - /** - * Number of connects we are waiting on, allows us to rate limit - * connect attempts. - */ - unsigned int outstanding_connects; - - /** - * Number of HELLOs we have yet to send. - */ - unsigned int remaining_hellos; - - /** - * How many connects have already been scheduled? - */ - unsigned int total_connects_scheduled; - - /** - * Hostkeys loaded from a file. - */ - char *hostkey_data; - - /** - * Head of DLL to keep track of the number of outstanding - * ssh connections per peer. - */ - struct OutstandingSSH *ssh_head; - - /** - * Tail of DLL to keep track of the number of outstanding - * ssh connections per peer. - */ - struct OutstandingSSH *ssh_tail; - - /** - * Stop scheduling peers connecting. - */ - unsigned int stop_connects; - - /** - * Connection context for peer group. - */ - struct ConnectTopologyContext ct_ctx; -}; - -struct UpdateContext -{ - /** - * The altered configuration. - */ - struct GNUNET_CONFIGURATION_Handle *ret; - - /** - * The original configuration to alter. - */ - const struct GNUNET_CONFIGURATION_Handle *orig; - - /** - * The hostname that this peer will run on. - */ - const char *hostname; - - /** - * The next possible port to assign. - */ - unsigned int nport; - - /** - * Unique number for unix domain sockets. - */ - unsigned int upnum; - - /** - * Unique number for this peer/host to offset - * things that are grouped by host. - */ - unsigned int fdnum; -}; - -struct ConnectContext -{ - - struct ConnectContext *next; - - struct ConnectContext *prev; - - /** - * Index of peer to connect second to. - */ - uint32_t first_index; - - /** - * Index of peer to connect first to. - */ - uint32_t second_index; - - /** - * Task associated with the attempt to connect. - */ - GNUNET_SCHEDULER_TaskIdentifier task; - - /** - * Context in 'testing.c', to cancel connection attempt. - */ - struct GNUNET_TESTING_ConnectContext *cc; - - /** - * Higher level topology connection context. - */ - struct ConnectTopologyContext *ct_ctx; - - /** - * Whether this connection has been accounted for in the schedule_connect call. - */ - int counted; -}; - -struct UnblacklistContext -{ - /** - * The peergroup - */ - struct GNUNET_TESTING_PeerGroup *pg; - - /** - * uid of the first peer - */ - uint32_t first_uid; -}; - -struct RandomContext -{ - /** - * The peergroup - */ - struct GNUNET_TESTING_PeerGroup *pg; - - /** - * uid of the first peer - */ - uint32_t first_uid; - - /** - * Peer data for first peer. - */ - struct PeerData *first; - - /** - * Random percentage to use - */ - double percentage; -}; - -struct MinimumContext -{ - /** - * The peergroup - */ - struct GNUNET_TESTING_PeerGroup *pg; - - /** - * uid of the first peer - */ - uint32_t first_uid; - - /** - * Peer data for first peer. - */ - struct PeerData *first; - - /** - * Number of conns per peer - */ - unsigned int num_to_add; - - /** - * Permuted array of all possible connections. Only add the Nth - * peer if it's in the Nth position. - */ - unsigned int *pg_array; - - /** - * What number is the current element we are iterating over? - */ - unsigned int current; -}; - -struct DFSContext -{ - /** - * The peergroup - */ - struct GNUNET_TESTING_PeerGroup *pg; - - /** - * uid of the first peer - */ - uint32_t first_uid; - - /** - * uid of the second peer - */ - uint32_t second_uid; - - /** - * Peer data for first peer. - */ - struct PeerData *first; - - /** - * Which peer has been chosen as the one to add? - */ - unsigned int chosen; - - /** - * What number is the current element we are iterating over? - */ - unsigned int current; -}; - -/** - * Simple struct to keep track of progress, and print a - * nice little percentage meter for long running tasks. - */ -struct ProgressMeter -{ - unsigned int total; - - unsigned int modnum; - - unsigned int dotnum; - - unsigned int completed; - - int print; - - char *startup_string; -}; - -#if !OLD -/** - * Convert unique ID to hash code. - * - * @param uid unique ID to convert - * @param hash set to uid (extended with zeros) - */ -static void -hash_from_uid (uint32_t uid, GNUNET_HashCode * hash) -{ - memset (hash, 0, sizeof (GNUNET_HashCode)); - *((uint32_t *) hash) = uid; -} - -/** - * Convert hash code to unique ID. - * - * @param uid unique ID to convert - * @param hash set to uid (extended with zeros) - */ -static void -uid_from_hash (const GNUNET_HashCode * hash, uint32_t * uid) -{ - memcpy (uid, hash, sizeof (uint32_t)); -} -#endif - -#if USE_SEND_HELLOS -static struct GNUNET_CORE_MessageHandler no_handlers[] = { - {NULL, 0, 0} -}; -#endif - -/** - * Create a meter to keep track of the progress of some task. - * - * @param total the total number of items to complete - * @param start_string a string to prefix the meter with (if printing) - * @param print GNUNET_YES to print the meter, GNUNET_NO to count - * internally only - * - * @return the progress meter - */ -static struct ProgressMeter * -create_meter (unsigned int total, char *start_string, int print) -{ - struct ProgressMeter *ret; - - ret = GNUNET_malloc (sizeof (struct ProgressMeter)); - ret->print = print; - ret->total = total; - ret->modnum = total / 4; - if (ret->modnum == 0) /* Divide by zero check */ - ret->modnum = 1; - ret->dotnum = (total / 50) + 1; - if (start_string != NULL) - ret->startup_string = GNUNET_strdup (start_string); - else - ret->startup_string = GNUNET_strdup (""); - - return ret; -} - -/** - * Update progress meter (increment by one). - * - * @param meter the meter to update and print info for - * - * @return GNUNET_YES if called the total requested, - * GNUNET_NO if more items expected - */ -static int -update_meter (struct ProgressMeter *meter) -{ - if (meter->print == GNUNET_YES) - { - if (meter->completed % meter->modnum == 0) - { - if (meter->completed == 0) - { - FPRINTF (stdout, "%sProgress: [0%%", meter->startup_string); - } - else - FPRINTF (stdout, "%d%%", - (int) (((float) meter->completed / meter->total) * 100)); - } - else if (meter->completed % meter->dotnum == 0) - FPRINTF (stdout, "%s", "."); - - if (meter->completed + 1 == meter->total) - FPRINTF (stdout, "%d%%]\n", 100); - fflush (stdout); - } - meter->completed++; - - if (meter->completed == meter->total) - return GNUNET_YES; - if (meter->completed > meter->total) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Progress meter overflow!!\n"); - return GNUNET_NO; -} - -/** - * Reset progress meter. - * - * @param meter the meter to reset - * - * @return GNUNET_YES if meter reset, - * GNUNET_SYSERR on error - */ -static int -reset_meter (struct ProgressMeter *meter) -{ - if (meter == NULL) - return GNUNET_SYSERR; - - meter->completed = 0; - return GNUNET_YES; -} - -/** - * Release resources for meter - * - * @param meter the meter to free - */ -static void -free_meter (struct ProgressMeter *meter) -{ - GNUNET_free_non_null (meter->startup_string); - GNUNET_free (meter); -} - -/** - * Get a topology from a string input. - * - * @param topology where to write the retrieved topology - * @param topology_string The string to attempt to - * get a configuration value from - * @return GNUNET_YES if topology string matched a - * known topology, GNUNET_NO if not - */ -int -GNUNET_TESTING_topology_get (enum GNUNET_TESTING_Topology *topology, - const char *topology_string) -{ - /** - * Strings representing topologies in enum - */ - static const char *topology_strings[] = { - /** - * A clique (everyone connected to everyone else). - */ - "CLIQUE", - - /** - * Small-world network (2d torus plus random links). - */ - "SMALL_WORLD", - - /** - * Small-world network (ring plus random links). - */ - "SMALL_WORLD_RING", - - /** - * Ring topology. - */ - "RING", - - /** - * 2-d torus. - */ - "2D_TORUS", - - /** - * Random graph. - */ - "ERDOS_RENYI", - - /** - * Certain percentage of peers are unable to communicate directly - * replicating NAT conditions - */ - "INTERNAT", - - /** - * Scale free topology. - */ - "SCALE_FREE", - - /** - * Straight line topology. - */ - "LINE", - - /** - * All peers are disconnected. - */ - "NONE", - - /** - * Read the topology from a file. - */ - "FROM_FILE", - - NULL - }; - - int curr = 0; - - if (topology_string == NULL) - return GNUNET_NO; - while (topology_strings[curr] != NULL) - { - if (strcasecmp (topology_strings[curr], topology_string) == 0) - { - *topology = curr; - return GNUNET_YES; - } - curr++; - } - *topology = GNUNET_TESTING_TOPOLOGY_NONE; - return GNUNET_NO; -} - -/** - * Get connect topology option from string input. - * - * @param topology_option where to write the retrieved topology - * @param topology_string The string to attempt to - * get a configuration value from - * @return GNUNET_YES if string matched a known - * topology option, GNUNET_NO if not - */ -int -GNUNET_TESTING_topology_option_get (enum GNUNET_TESTING_TopologyOption - *topology_option, - const char *topology_string) -{ - /** - * Options for connecting a topology as strings. - */ - static const char *topology_option_strings[] = { - /** - * Try to connect all peers specified in the topology. - */ - "CONNECT_ALL", - - /** - * Choose a random subset of connections to create. - */ - "CONNECT_RANDOM_SUBSET", - - /** - * Create at least X connections for each peer. - */ - "CONNECT_MINIMUM", - - /** - * Using a depth first search, create one connection - * per peer. If any are missed (graph disconnected) - * start over at those peers until all have at least one - * connection. - */ - "CONNECT_DFS", - - /** - * Find the N closest peers to each allowed peer in the - * topology and make sure a connection to those peers - * exists in the connect topology. - */ - "CONNECT_CLOSEST", - - /** - * No options specified. - */ - "CONNECT_NONE", - - NULL - }; - int curr = 0; - - if (topology_string == NULL) - return GNUNET_NO; - while (NULL != topology_option_strings[curr]) - { - if (strcasecmp (topology_option_strings[curr], topology_string) == 0) - { - *topology_option = curr; - return GNUNET_YES; - } - curr++; - } - *topology_option = GNUNET_TESTING_TOPOLOGY_OPTION_NONE; - return GNUNET_NO; -} - -/** - * Function to iterate over options. Copies - * the options to the target configuration, - * updating PORT values as needed. - * - * @param cls closure - * @param section name of the section - * @param option name of the option - * @param value value of the option - */ -static void -update_config (void *cls, const char *section, const char *option, - const char *value) -{ - struct UpdateContext *ctx = cls; - unsigned int ival; - char cval[12]; - char uval[128]; - char *single_variable; - char *per_host_variable; - unsigned long long num_per_host; - - GNUNET_asprintf (&single_variable, "single_%s_per_host", section); - GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section); - - if ((0 == strcmp (option, "PORT")) && (1 == SSCANF (value, "%u", &ival))) - { - if ((ival != 0) && - (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_yesno (ctx->orig, "testing", - single_variable))) - { - GNUNET_snprintf (cval, sizeof (cval), "%u", ctx->nport++); - value = cval; - } - else if ((ival != 0) && - (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno (ctx->orig, "testing", - single_variable)) && - GNUNET_CONFIGURATION_get_value_number (ctx->orig, "testing", - per_host_variable, - &num_per_host)) - { - GNUNET_snprintf (cval, sizeof (cval), "%u", - ival + ctx->fdnum % num_per_host); - value = cval; - } - - /* FIXME: REMOVE FOREVER HACK HACK HACK */ - if (0 == strcasecmp (section, "transport-tcp")) - GNUNET_CONFIGURATION_set_value_string (ctx->ret, section, - "ADVERTISED_PORT", value); - } - - if (0 == strcmp (option, "UNIXPATH")) - { - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_yesno (ctx->orig, "testing", - single_variable)) - { - GNUNET_snprintf (uval, sizeof (uval), "/tmp/test-service-%s-%u", section, - ctx->upnum++); - value = uval; - } - else if ((GNUNET_YES == - GNUNET_CONFIGURATION_get_value_number (ctx->orig, "testing", - per_host_variable, - &num_per_host)) && - (num_per_host > 0)) - - { - GNUNET_snprintf (uval, sizeof (uval), "/tmp/test-service-%s-%u", section, - ctx->fdnum % num_per_host); - value = uval; - } - } - - if ((0 == strcmp (option, "HOSTNAME")) && (ctx->hostname != NULL)) - { - value = ctx->hostname; - } - GNUNET_free (single_variable); - GNUNET_free (per_host_variable); - GNUNET_CONFIGURATION_set_value_string (ctx->ret, section, option, value); -} - -/** - * Create a new configuration using the given configuration - * as a template; however, each PORT in the existing cfg - * must be renumbered by incrementing "*port". If we run - * out of "*port" numbers, return NULL. - * - * @param cfg template configuration - * @param off the current peer offset - * @param port port numbers to use, update to reflect - * port numbers that were used - * @param upnum number to make unix domain socket names unique - * @param hostname hostname of the controlling host, to allow control connections from - * @param fdnum number used to offset the unix domain socket for grouped processes - * (such as statistics or peerinfo, which can be shared among others) - * - * @return new configuration, NULL on error - */ -struct GNUNET_CONFIGURATION_Handle * -GNUNET_TESTING_create_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, uint32_t off, - uint16_t * port, uint32_t * upnum, const char *hostname, - uint32_t * fdnum) -{ - struct UpdateContext uc; - uint16_t orig; - char *control_host; - char *allowed_hosts; - unsigned long long skew_variance; - unsigned long long skew_offset; - long long actual_offset; - - orig = *port; - uc.nport = *port; - uc.upnum = *upnum; - uc.fdnum = *fdnum; - uc.ret = GNUNET_CONFIGURATION_create (); - uc.hostname = hostname; - uc.orig = cfg; - - GNUNET_CONFIGURATION_iterate (cfg, &update_config, &uc); - if (uc.nport >= HIGH_PORT) - { - *port = orig; - GNUNET_CONFIGURATION_destroy (uc.ret); - return NULL; - } - - if ((GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "skew_variance", - &skew_variance)) && - (skew_variance > 0)) - { - skew_offset = - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - skew_variance + 1); - actual_offset = - skew_offset - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - skew_variance + 1); - /* Min is -skew_variance, Max is skew_variance */ - skew_offset = skew_variance + actual_offset; /* Normal distribution around 0 */ - GNUNET_CONFIGURATION_set_value_number (uc.ret, "testing", "skew_offset", - skew_offset); - } - - if (GNUNET_CONFIGURATION_get_value_string - (cfg, "testing", "control_host", &control_host) == GNUNET_OK) - { - if (hostname != NULL) - GNUNET_asprintf (&allowed_hosts, "%s; 127.0.0.1; %s;", control_host, - hostname); - else - GNUNET_asprintf (&allowed_hosts, "%s; 127.0.0.1;", control_host); - - GNUNET_CONFIGURATION_set_value_string (uc.ret, "core", "ACCEPT_FROM", - allowed_hosts); - - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nse", "ACCEPT_FROM", - allowed_hosts); - - GNUNET_CONFIGURATION_set_value_string (uc.ret, "transport", "ACCEPT_FROM", - allowed_hosts); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "dht", "ACCEPT_FROM", - allowed_hosts); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "statistics", "ACCEPT_FROM", - allowed_hosts); - - GNUNET_CONFIGURATION_set_value_string (uc.ret, "core", "UNIXPATH", ""); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "transport", "UNIXPATH", ""); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "dht", "UNIXPATH", ""); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "statistics", "UNIXPATH", - ""); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nse", "UNIXPATH", ""); - - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", - "USE_LOCALADDR", "YES"); - GNUNET_free_non_null (control_host); - GNUNET_free (allowed_hosts); - } - - /* arm needs to know to allow connections from the host on which it is running, - * otherwise gnunet-arm is unable to connect to it in some instances */ - if (hostname != NULL) - { - GNUNET_asprintf (&allowed_hosts, "%s; 127.0.0.1;", hostname); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", "BINDTO", hostname); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", "INTERNAL_ADDRESS", - hostname); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", "EXTERNAL_ADDRESS", - hostname); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "disablev6", "BINDTO", - "YES"); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "transport-tcp", - "USE_LOCALADDR", "YES"); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "transport-udp", - "USE_LOCALADDR", "YES"); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "arm", "ACCEPT_FROM", - allowed_hosts); - GNUNET_free (allowed_hosts); - } - else - { - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", - "USE_LOCALADDR", "YES"); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", "BINDTO", - "127.0.0.1"); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", "INTERNAL_ADDRESS", - "127.0.0.1"); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", "EXTERNAL_ADDRESS", - "127.0.0.1"); - GNUNET_CONFIGURATION_set_value_string (uc.ret, "nat", "disablev6", - "YES"); - } - - *port = (uint16_t) uc.nport; - *upnum = uc.upnum; - uc.fdnum++; - *fdnum = uc.fdnum; - return uc.ret; -} - -/* - * Remove entries from the peer connection list - * - * @param pg the peer group we are working with - * @param first index of the first peer - * @param second index of the second peer - * @param list the peer list to use - * @param check UNUSED - * - * @return the number of connections added (can be 0, 1 or 2) - * - */ -static unsigned int -remove_connections (struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, - unsigned int second, enum PeerLists list, - unsigned int check) -{ - int removed; - -#if OLD - struct PeerConnection **first_list; - struct PeerConnection **second_list; - struct PeerConnection *first_iter; - struct PeerConnection *second_iter; - struct PeerConnection **first_tail; - struct PeerConnection **second_tail; - -#else - GNUNET_HashCode hash_first; - GNUNET_HashCode hash_second; - - hash_from_uid (first, &hash_first); - hash_from_uid (second, &hash_second); -#endif - - removed = 0; -#if OLD - switch (list) - { - case ALLOWED: - first_list = &pg->peers[first].allowed_peers_head; - second_list = &pg->peers[second].allowed_peers_head; - first_tail = &pg->peers[first].allowed_peers_tail; - second_tail = &pg->peers[second].allowed_peers_tail; - break; - case CONNECT: - first_list = &pg->peers[first].connect_peers_head; - second_list = &pg->peers[second].connect_peers_head; - first_tail = &pg->peers[first].connect_peers_tail; - second_tail = &pg->peers[second].connect_peers_tail; - break; - case BLACKLIST: - first_list = &pg->peers[first].blacklisted_peers_head; - second_list = &pg->peers[second].blacklisted_peers_head; - first_tail = &pg->peers[first].blacklisted_peers_tail; - second_tail = &pg->peers[second].blacklisted_peers_tail; - break; - case WORKING_SET: - first_list = &pg->peers[first].connect_peers_working_set_head; - second_list = &pg->peers[second].connect_peers_working_set_head; - first_tail = &pg->peers[first].connect_peers_working_set_tail; - second_tail = &pg->peers[second].connect_peers_working_set_tail; - break; - default: - GNUNET_break (0); - return 0; - } - - first_iter = *first_list; - while (first_iter != NULL) - { - if (first_iter->index == second) - { - GNUNET_CONTAINER_DLL_remove (*first_list, *first_tail, first_iter); - GNUNET_free (first_iter); - removed++; - break; - } - first_iter = first_iter->next; - } - - second_iter = *second_list; - while (second_iter != NULL) - { - if (second_iter->index == first) - { - GNUNET_CONTAINER_DLL_remove (*second_list, *second_tail, second_iter); - GNUNET_free (second_iter); - removed++; - break; - } - second_iter = second_iter->next; - } -#else - if (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_contains (pg-> - peers[first].blacklisted_peers, - &hash_second)) - { - GNUNET_CONTAINER_multihashmap_remove_all (pg-> - peers[first].blacklisted_peers, - &hash_second); - } - - if (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_contains (pg-> - peers[second].blacklisted_peers, - &hash_first)) - { - GNUNET_CONTAINER_multihashmap_remove_all (pg-> - peers[second].blacklisted_peers, - &hash_first); - } -#endif - - return removed; -} - -/** - * Add entries to the some list - * - * @param pg the peer group we are working with - * @param first index of the first peer - * @param second index of the second peer - * @param list the list type that we should modify - * @param check GNUNET_YES to check lists before adding - * GNUNET_NO to force add - * - * @return the number of connections added (can be 0, 1 or 2) - * - */ -static unsigned int -add_connections (struct GNUNET_TESTING_PeerGroup *pg, unsigned int first, - unsigned int second, enum PeerLists list, unsigned int check) -{ - int added; - int add_first; - int add_second; - - struct PeerConnection **first_list; - struct PeerConnection **second_list; - struct PeerConnection *first_iter; - struct PeerConnection *second_iter; - struct PeerConnection *new_first; - struct PeerConnection *new_second; - struct PeerConnection **first_tail; - struct PeerConnection **second_tail; - - switch (list) - { - case ALLOWED: - first_list = &pg->peers[first].allowed_peers_head; - second_list = &pg->peers[second].allowed_peers_head; - first_tail = &pg->peers[first].allowed_peers_tail; - second_tail = &pg->peers[second].allowed_peers_tail; - break; - case CONNECT: - first_list = &pg->peers[first].connect_peers_head; - second_list = &pg->peers[second].connect_peers_head; - first_tail = &pg->peers[first].connect_peers_tail; - second_tail = &pg->peers[second].connect_peers_tail; - break; - case BLACKLIST: - first_list = &pg->peers[first].blacklisted_peers_head; - second_list = &pg->peers[second].blacklisted_peers_head; - first_tail = &pg->peers[first].blacklisted_peers_tail; - second_tail = &pg->peers[second].blacklisted_peers_tail; - break; - case WORKING_SET: - first_list = &pg->peers[first].connect_peers_working_set_head; - second_list = &pg->peers[second].connect_peers_working_set_head; - first_tail = &pg->peers[first].connect_peers_working_set_tail; - second_tail = &pg->peers[second].connect_peers_working_set_tail; - break; - default: - GNUNET_break (0); - return 0; - } - - add_first = GNUNET_YES; - add_second = GNUNET_YES; - - if (check == GNUNET_YES) - { - first_iter = *first_list; - while (first_iter != NULL) - { - if (first_iter->index == second) - { - add_first = GNUNET_NO; - break; - } - first_iter = first_iter->next; - } - - second_iter = *second_list; - while (second_iter != NULL) - { - if (second_iter->index == first) - { - add_second = GNUNET_NO; - break; - } - second_iter = second_iter->next; - } - } - - added = 0; - if (add_first) - { - new_first = GNUNET_malloc (sizeof (struct PeerConnection)); - new_first->index = second; - GNUNET_CONTAINER_DLL_insert (*first_list, *first_tail, new_first); - pg->peers[first].num_connections++; - added++; - } - - if (add_second) - { - new_second = GNUNET_malloc (sizeof (struct PeerConnection)); - new_second->index = first; - GNUNET_CONTAINER_DLL_insert (*second_list, *second_tail, new_second); - pg->peers[second].num_connections++; - added++; - } - - return added; -} - -/** - * Scale free network construction as described in: - * - * "Emergence of Scaling in Random Networks." Science 286, 509-512, 1999. - * - * Start with a network of "one" peer, then progressively add - * peers up to the total number. At each step, iterate over - * all possible peers and connect new peer based on number of - * existing connections of the target peer. - * - * @param pg the peer group we are dealing with - * @param proc the connection processor to use - * @param list the peer list to use - * - * @return the number of connections created - */ -static unsigned int -create_scale_free (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc, enum PeerLists list) -{ - - unsigned int total_connections; - unsigned int outer_count; - unsigned int i; - unsigned int previous_total_connections; - double random; - double probability; - - GNUNET_assert (pg->total > 1); - - /* Add a connection between the first two nodes */ - total_connections = proc (pg, 0, 1, list, GNUNET_YES); - - for (outer_count = 1; outer_count < pg->total; outer_count++) - { - previous_total_connections = total_connections; - for (i = 0; i < outer_count; i++) - { - probability = - pg->peers[i].num_connections / (double) previous_total_connections; - random = - ((double) - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - UINT64_MAX)) / ((double) UINT64_MAX); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Considering connecting peer %d to peer %d\n", outer_count, - i); - if (random < probability) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", - outer_count, i); - total_connections += proc (pg, outer_count, i, list, GNUNET_YES); - } - } - } - - return total_connections; -} - -/** - * Create a topology given a peer group (set of running peers) - * and a connection processor. Creates a small world topology - * according to the rewired ring construction. The basic - * behavior is that a ring topology is created, but with some - * probability instead of connecting a peer to the next - * neighbor in the ring a connection will be created to a peer - * selected uniformly at random. We use the TESTING - * PERCENTAGE option to specify what number of - * connections each peer should have. Default is 2, - * which makes the ring, any given number is multiplied by - * the log of the network size; i.e. a PERCENTAGE of 2 makes - * each peer have on average 2logn connections. The additional - * connections are made at increasing distance around the ring - * from the original peer, or to random peers based on the re- - * wiring probability. The TESTING - * PROBABILITY option is used as the probability that a given - * connection is rewired. - * - * @param pg the peergroup to create the topology on - * @param proc the connection processor to call to actually set - * up connections between two peers - * @param list the peer list to use - * - * @return the number of connections that were set up - * - */ -static unsigned int -create_small_world_ring (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc, - enum PeerLists list) -{ - unsigned int i, j; - int nodeToConnect; - unsigned int natLog; - unsigned int randomPeer; - double random, logNModifier, probability; - unsigned int smallWorldConnections; - int connsPerPeer; - char *p_string; - int max; - int min; - unsigned int useAnd; - int connect_attempts; - - logNModifier = 0.5; /* FIXME: default value? */ - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PERCENTAGE", - &p_string)) - { - if (SSCANF (p_string, "%lf", &logNModifier) != 1) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), - p_string, "LOGNMODIFIER", "TESTING"); - GNUNET_free (p_string); - } - probability = 0.5; /* FIXME: default percentage? */ - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PROBABILITY", - &p_string)) - { - if (SSCANF (p_string, "%lf", &probability) != 1) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), - p_string, "PERCENTAGE", "TESTING"); - GNUNET_free (p_string); - } - natLog = log (pg->total); - connsPerPeer = ceil (natLog * logNModifier); - - if (connsPerPeer % 2 == 1) - connsPerPeer += 1; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Target is %d connections per peer.", - connsPerPeer); - - smallWorldConnections = 0; - connect_attempts = 0; - for (i = 0; i < pg->total; i++) - { - useAnd = 0; - max = i + connsPerPeer / 2; - min = i - connsPerPeer / 2; - - if (max > pg->total - 1) - { - max = max - pg->total; - useAnd = 1; - } - - if (min < 0) - { - min = pg->total - 1 + min; - useAnd = 1; - } - - for (j = 0; j < connsPerPeer / 2; j++) - { - random = - ((double) - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - UINT64_MAX) / ((double) UINT64_MAX)); - if (random < probability) - { - /* Connect to uniformly selected random peer */ - randomPeer = - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, pg->total); - while ((((randomPeer < max) && (randomPeer > min)) && (useAnd == 0)) || - (((randomPeer > min) || (randomPeer < max)) && (useAnd == 1))) - { - randomPeer = - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, pg->total); - } - smallWorldConnections += proc (pg, i, randomPeer, list, GNUNET_YES); - } - else - { - nodeToConnect = i + j + 1; - if (nodeToConnect > pg->total - 1) - { - nodeToConnect = nodeToConnect - pg->total; - } - connect_attempts += proc (pg, i, nodeToConnect, list, GNUNET_YES); - } - } - - } - - connect_attempts += smallWorldConnections; - - return connect_attempts; -} - -/** - * Create a topology given a peer group (set of running peers) - * and a connection processor. - * - * @param pg the peergroup to create the topology on - * @param proc the connection processor to call to actually set - * up connections between two peers - * @param list the peer list to use - * - * @return the number of connections that were set up - * - */ -static unsigned int -create_nated_internet (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc, - enum PeerLists list) -{ - unsigned int outer_count, inner_count; - unsigned int cutoff; - int connect_attempts; - double nat_percentage; - char *p_string; - - nat_percentage = 0.6; /* FIXME: default percentage? */ - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PERCENTAGE", - &p_string)) - { - if (SSCANF (p_string, "%lf", &nat_percentage) != 1) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), - p_string, "PERCENTAGE", "TESTING"); - GNUNET_free (p_string); - } - - cutoff = (unsigned int) (nat_percentage * pg->total); - connect_attempts = 0; - for (outer_count = 0; outer_count < pg->total - 1; outer_count++) - { - for (inner_count = outer_count + 1; inner_count < pg->total; inner_count++) - { - if ((outer_count > cutoff) || (inner_count > cutoff)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", - outer_count, inner_count); - connect_attempts += - proc (pg, outer_count, inner_count, list, GNUNET_YES); - } - } - } - return connect_attempts; -} - -#if TOPOLOGY_HACK -/** - * Create a topology given a peer group (set of running peers) - * and a connection processor. - * - * @param pg the peergroup to create the topology on - * @param proc the connection processor to call to actually set - * up connections between two peers - * @param list the peer list to use - * - * @return the number of connections that were set up - * - */ -static unsigned int -create_nated_internet_copy (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc, - enum PeerLists list) -{ - unsigned int outer_count, inner_count; - unsigned int cutoff; - int connect_attempts; - double nat_percentage; - char *p_string; - unsigned int count; - struct ProgressMeter *conn_meter; - - nat_percentage = 0.6; /* FIXME: default percentage? */ - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PERCENTAGE", - &p_string)) - { - if (SSCANF (p_string, "%lf", &nat_percentage) != 1) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), - p_string, "PERCENTAGE", "TESTING"); - GNUNET_free (p_string); - } - - cutoff = (unsigned int) (nat_percentage * pg->total); - count = 0; - for (outer_count = 0; outer_count < pg->total - 1; outer_count++) - { - for (inner_count = outer_count + 1; inner_count < pg->total; inner_count++) - { - if ((outer_count > cutoff) || (inner_count > cutoff)) - { - count++; - } - } - } - conn_meter = create_meter (count, "NAT COPY", GNUNET_YES); - connect_attempts = 0; - for (outer_count = 0; outer_count < pg->total - 1; outer_count++) - { - for (inner_count = outer_count + 1; inner_count < pg->total; inner_count++) - { - if ((outer_count > cutoff) || (inner_count > cutoff)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", - outer_count, inner_count); - connect_attempts += - proc (pg, outer_count, inner_count, list, GNUNET_YES); - add_connections (pg, outer_count, inner_count, ALLOWED, GNUNET_NO); - update_meter (conn_meter); - } - } - } - free_meter (conn_meter); - - return connect_attempts; -} -#endif - -/** - * Create a topology given a peer group (set of running peers) - * and a connection processor. - * - * @param pg the peergroup to create the topology on - * @param proc the connection processor to call to actually set - * up connections between two peers - * @param list the peer list to use - * - * @return the number of connections that were set up - * - */ -static unsigned int -create_small_world (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc, - enum PeerLists list) -{ - unsigned int i, j, k; - unsigned int square; - unsigned int rows; - unsigned int cols; - unsigned int toggle = 1; - unsigned int nodeToConnect; - unsigned int natLog; - unsigned int node1Row; - unsigned int node1Col; - unsigned int node2Row; - unsigned int node2Col; - unsigned int distance; - double probability, random, percentage; - unsigned int smallWorldConnections; - unsigned int small_world_it; - char *p_string; - int connect_attempts; - - square = floor (sqrt (pg->total)); - rows = square; - cols = square; - - percentage = 0.5; /* FIXME: default percentage? */ - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PERCENTAGE", - &p_string)) - { - if (SSCANF (p_string, "%lf", &percentage) != 1) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), - p_string, "PERCENTAGE", "TESTING"); - GNUNET_free (p_string); - } - if (percentage < 0.0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': got %f, needed value greater than 0\n"), - "PERCENTAGE", "TESTING", percentage); - percentage = 0.5; - } - probability = 0.5; /* FIXME: default percentage? */ - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PROBABILITY", - &p_string)) - { - if (SSCANF (p_string, "%lf", &probability) != 1) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), - p_string, "PROBABILITY", "TESTING"); - GNUNET_free (p_string); - } - if (square * square != pg->total) - { - while (rows * cols < pg->total) - { - if (toggle % 2 == 0) - rows++; - else - cols++; - - toggle++; - } - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connecting nodes in 2d torus topology: %u rows %u columns\n", - rows, cols); - connect_attempts = 0; - /* Rows and columns are all sorted out, now iterate over all nodes and connect each - * to the node to its right and above. Once this is over, we'll have our torus! - * Special case for the last node (if the rows and columns are not equal), connect - * to the first in the row to maintain topology. - */ - for (i = 0; i < pg->total; i++) - { - /* First connect to the node to the right */ - if (((i + 1) % cols != 0) && (i + 1 != pg->total)) - nodeToConnect = i + 1; - else if (i + 1 == pg->total) - nodeToConnect = rows * cols - cols; - else - nodeToConnect = i - cols + 1; - - connect_attempts += proc (pg, i, nodeToConnect, list, GNUNET_YES); - - if (i < cols) - { - nodeToConnect = (rows * cols) - cols + i; - if (nodeToConnect >= pg->total) - nodeToConnect -= cols; - } - else - nodeToConnect = i - cols; - - if (nodeToConnect < pg->total) - connect_attempts += proc (pg, i, nodeToConnect, list, GNUNET_YES); - } - natLog = log (pg->total); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "natural log of %d is %d, will run %d iterations\n", pg->total, - natLog, (int) (natLog * percentage)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Total connections added thus far: %u!\n", connect_attempts); - smallWorldConnections = 0; - small_world_it = (unsigned int) (natLog * percentage); - if (small_world_it < 1) - small_world_it = 1; - GNUNET_assert (small_world_it > 0 && small_world_it < (unsigned int) -1); - for (i = 0; i < small_world_it; i++) - { - for (j = 0; j < pg->total; j++) - { - /* Determine the row and column of node at position j on the 2d torus */ - node1Row = j / cols; - node1Col = j - (node1Row * cols); - for (k = 0; k < pg->total; k++) - { - /* Determine the row and column of node at position k on the 2d torus */ - node2Row = k / cols; - node2Col = k - (node2Row * cols); - /* Simple Cartesian distance */ - distance = abs (node1Row - node2Row) + abs (node1Col - node2Col); - if (distance > 1) - { - /* Calculate probability as 1 over the square of the distance */ - probability = 1.0 / (distance * distance); - /* Choose a random value between 0 and 1 */ - random = - ((double) - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - UINT64_MAX)) / ((double) UINT64_MAX); - /* If random < probability, then connect the two nodes */ - if (random < probability) - smallWorldConnections += proc (pg, j, k, list, GNUNET_YES); - - } - } - } - } - connect_attempts += smallWorldConnections; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Total connections added for small world: %d!\n", - smallWorldConnections); - return connect_attempts; -} - -/** - * Create a topology given a peer group (set of running peers) - * and a connection processor. - * - * @param pg the peergroup to create the topology on - * @param proc the connection processor to call to actually set - * up connections between two peers - * @param list the peer list to use - * - * @return the number of connections that were set up - * - */ -static unsigned int -create_erdos_renyi (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc, - enum PeerLists list) -{ - double temp_rand; - unsigned int outer_count; - unsigned int inner_count; - int connect_attempts; - double probability; - char *p_string; - - probability = 0.5; /* FIXME: default percentage? */ - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (pg->cfg, "TESTING", "PROBABILITY", - &p_string)) - { - if (SSCANF (p_string, "%lf", &probability) != 1) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), - p_string, "PROBABILITY", "TESTING"); - GNUNET_free (p_string); - } - connect_attempts = 0; - for (outer_count = 0; outer_count < pg->total - 1; outer_count++) - { - for (inner_count = outer_count + 1; inner_count < pg->total; inner_count++) - { - temp_rand = - ((double) - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - UINT64_MAX)) / ((double) UINT64_MAX); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "rand is %f probability is %f\n", - temp_rand, probability); - if (temp_rand < probability) - { - connect_attempts += - proc (pg, outer_count, inner_count, list, GNUNET_YES); - } - } - } - - return connect_attempts; -} - -/** - * Create a topology given a peer group (set of running peers) - * and a connection processor. This particular function creates - * the connections for a 2d-torus, plus additional "closest" - * connections per peer. - * - * @param pg the peergroup to create the topology on - * @param proc the connection processor to call to actually set - * up connections between two peers - * @param list the peer list to use - * - * @return the number of connections that were set up - * - */ -static unsigned int -create_2d_torus (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc, enum PeerLists list) -{ - unsigned int i; - unsigned int square; - unsigned int rows; - unsigned int cols; - unsigned int toggle = 1; - unsigned int nodeToConnect; - int connect_attempts; - - connect_attempts = 0; - - square = floor (sqrt (pg->total)); - rows = square; - cols = square; - - if (square * square != pg->total) - { - while (rows * cols < pg->total) - { - if (toggle % 2 == 0) - rows++; - else - cols++; - - toggle++; - } - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connecting nodes in 2d torus topology: %u rows %u columns\n", - rows, cols); - /* Rows and columns are all sorted out, now iterate over all nodes and connect each - * to the node to its right and above. Once this is over, we'll have our torus! - * Special case for the last node (if the rows and columns are not equal), connect - * to the first in the row to maintain topology. - */ - for (i = 0; i < pg->total; i++) - { - /* First connect to the node to the right */ - if (((i + 1) % cols != 0) && (i + 1 != pg->total)) - nodeToConnect = i + 1; - else if (i + 1 == pg->total) - nodeToConnect = rows * cols - cols; - else - nodeToConnect = i - cols + 1; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", i, - nodeToConnect); - connect_attempts += proc (pg, i, nodeToConnect, list, GNUNET_YES); - - /* Second connect to the node immediately above */ - if (i < cols) - { - nodeToConnect = (rows * cols) - cols + i; - if (nodeToConnect >= pg->total) - nodeToConnect -= cols; - } - else - nodeToConnect = i - cols; - - if (nodeToConnect < pg->total) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", i, - nodeToConnect); - connect_attempts += proc (pg, i, nodeToConnect, list, GNUNET_YES); - } - - } - - return connect_attempts; -} - -/** - * Create a topology given a peer group (set of running peers) - * and a connection processor. - * - * @param pg the peergroup to create the topology on - * @param proc the connection processor to call to actually set - * up connections between two peers - * @param list the peer list to use - * @param check does the connection processor need to check before - * performing an action on the list? - * - * @return the number of connections that were set up - * - */ -static unsigned int -create_clique (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc, enum PeerLists list, - unsigned int check) -{ - unsigned int outer_count; - unsigned int inner_count; - int connect_attempts; - struct ProgressMeter *conn_meter; - - connect_attempts = 0; - - conn_meter = - create_meter ((((pg->total * pg->total) + pg->total) / 2) - pg->total, - "Create Clique ", GNUNET_NO); - for (outer_count = 0; outer_count < pg->total - 1; outer_count++) - { - for (inner_count = outer_count + 1; inner_count < pg->total; inner_count++) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", - outer_count, inner_count); - connect_attempts += proc (pg, outer_count, inner_count, list, check); - update_meter (conn_meter); - } - } - reset_meter (conn_meter); - free_meter (conn_meter); - return connect_attempts; -} - -#if !OLD -/** - * Iterator over hash map entries. - * - * @param cls closure the peer group - * @param key the key stored in the hashmap is the - * index of the peer to connect to - * @param value value in the hash map, handle to the peer daemon - * @return GNUNET_YES if we should continue to - * iterate, - * GNUNET_NO if not. - */ -static int -unblacklist_iterator (void *cls, const GNUNET_HashCode * key, void *value) -{ - struct UnblacklistContext *un_ctx = cls; - uint32_t second_pos; - - uid_from_hash (key, &second_pos); - - unblacklist_connections (un_ctx->pg, un_ctx->first_uid, second_pos); - - return GNUNET_YES; -} -#endif - -#if !OLD -/** - * Create a blacklist topology based on the allowed topology - * which disallows any connections not in the allowed topology - * at the transport level. - * - * @param pg the peergroup to create the topology on - * @param proc the connection processor to call to allow - * up connections between two peers - * - * @return the number of connections that were set up - * - */ -static unsigned int -copy_allowed (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc) -{ - unsigned int count; - unsigned int total; - struct PeerConnection *iter; - -#if !OLD - struct UnblacklistContext un_ctx; - - un_ctx.pg = pg; -#endif - total = 0; - for (count = 0; count < pg->total - 1; count++) - { -#if OLD - iter = pg->peers[count].allowed_peers_head; - while (iter != NULL) - { - remove_connections (pg, count, iter->index, BLACKLIST, GNUNET_YES); - //unblacklist_connections(pg, count, iter->index); - iter = iter->next; - } -#else - un_ctx.first_uid = count; - total += - GNUNET_CONTAINER_multihashmap_iterate (pg->peers[count].allowed_peers, - &unblacklist_iterator, &un_ctx); -#endif - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Unblacklisted %u peers\n", total); - return total; -} -#endif - -/** - * Create a topology given a peer group (set of running peers) - * and a connection processor. - * - * @param pg the peergroup to create the topology on - * @param proc the connection processor to call to actually set - * up connections between two peers - * @param list which list should be modified - * - * @return the number of connections that were set up - * - */ -static unsigned int -create_line (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc, enum PeerLists list) -{ - unsigned int count; - unsigned int connect_attempts; - - connect_attempts = 0; - /* Connect each peer to the next highest numbered peer */ - for (count = 0; count < pg->total - 1; count++) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", - count, count + 1); - connect_attempts += proc (pg, count, count + 1, list, GNUNET_YES); - } - - return connect_attempts; -} - -/** - * Create a topology given a peer group (set of running peers) - * and a connection processor. - * - * @param pg the peergroup to create the topology on - * @param filename the file to read topology information from - * @param proc the connection processor to call to actually set - * up connections between two peers - * @param list the peer list to use - * - * @return the number of connections that were set up - * - */ -static unsigned int -create_from_file (struct GNUNET_TESTING_PeerGroup *pg, char *filename, - GNUNET_TESTING_ConnectionProcessor proc, enum PeerLists list) -{ - int connect_attempts; - unsigned int first_peer_index; - unsigned int second_peer_index; - struct stat frstat; - int count; - char *data; - const char *buf; - unsigned int total_peers; - enum States curr_state; - - connect_attempts = 0; - if (GNUNET_OK != GNUNET_DISK_file_test (filename)) - GNUNET_DISK_fn_write (filename, NULL, 0, GNUNET_DISK_PERM_USER_READ); - - if ((0 != STAT (filename, &frstat)) || (frstat.st_size == 0)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not open file `%s' specified for topology!", filename); - return connect_attempts; - } - - data = GNUNET_malloc_large (frstat.st_size); - GNUNET_assert (data != NULL); - if (frstat.st_size != GNUNET_DISK_fn_read (filename, data, frstat.st_size)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not read file %s specified for host list, ending test!", - filename); - GNUNET_free (data); - return connect_attempts; - } - - buf = data; - count = 0; - first_peer_index = 0; - /* First line should contain a single integer, specifying the number of peers */ - /* Each subsequent line should contain this format PEER_INDEX:OTHER_PEER_INDEX[,...] */ - curr_state = NUM_PEERS; - while (count < frstat.st_size - 1) - { - if ((buf[count] == '\n') || (buf[count] == ' ')) - { - count++; - continue; - } - - switch (curr_state) - { - case NUM_PEERS: - errno = 0; - total_peers = strtoul (&buf[count], NULL, 10); - if (errno != 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to read number of peers from topology file!\n"); - GNUNET_free (data); - return connect_attempts; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u total peers in topology\n", - total_peers); - GNUNET_assert (total_peers == pg->total); - curr_state = PEER_INDEX; - while ((buf[count] != '\n') && (count < frstat.st_size - 1)) - count++; - count++; - break; - case PEER_INDEX: - errno = 0; - first_peer_index = strtoul (&buf[count], NULL, 10); - if (errno != 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to read peer index from topology file!\n"); - GNUNET_free (data); - return connect_attempts; - } - while ((buf[count] != ':') && (count < frstat.st_size - 1)) - count++; - count++; - curr_state = OTHER_PEER_INDEX; - break; - case COLON: - if (1 == sscanf (&buf[count], ":")) - curr_state = OTHER_PEER_INDEX; - count++; - break; - case OTHER_PEER_INDEX: - errno = 0; - second_peer_index = strtoul (&buf[count], NULL, 10); - if (errno != 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to peer index from topology file!\n"); - GNUNET_free (data); - return connect_attempts; - } - /* Assume file is written with first peer 1, but array index is 0 */ - connect_attempts += - proc (pg, first_peer_index - 1, second_peer_index - 1, list, - GNUNET_YES); - while ((buf[count] != '\n') && (buf[count] != ',') && - (count < frstat.st_size - 1)) - count++; - if (buf[count] == '\n') - { - curr_state = PEER_INDEX; - } - else if (buf[count] != ',') - { - curr_state = OTHER_PEER_INDEX; - } - count++; - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Found bad data in topology file while in state %d!\n", - curr_state); - GNUNET_break (0); - GNUNET_free (data); - return connect_attempts; - } - } - GNUNET_free (data); - return connect_attempts; -} - -/** - * Create a topology given a peer group (set of running peers) - * and a connection processor. - * - * @param pg the peergroup to create the topology on - * @param proc the connection processor to call to actually set - * up connections between two peers - * @param list the peer list to use - * - * @return the number of connections that were set up - * - */ -static unsigned int -create_ring (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_ConnectionProcessor proc, enum PeerLists list) -{ - unsigned int count; - int connect_attempts; - - connect_attempts = 0; - - /* Connect each peer to the next highest numbered peer */ - for (count = 0; count < pg->total - 1; count++) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting peer %d to peer %d\n", - count, count + 1); - connect_attempts += proc (pg, count, count + 1, list, GNUNET_YES); - } - - /* Connect the last peer to the first peer */ - connect_attempts += proc (pg, pg->total - 1, 0, list, GNUNET_YES); - - return connect_attempts; -} - -#if !OLD -/** - * Iterator for writing friends of a peer to a file. - * - * @param cls closure, an open writable file handle - * @param key the key the daemon was stored under - * @param value the GNUNET_TESTING_Daemon that needs to be written. - * - * @return GNUNET_YES to continue iteration - * - * TODO: Could replace friend_file_iterator and blacklist_file_iterator - * with a single file_iterator that takes a closure which contains - * the prefix to write before the peer. Then this could be used - * for blacklisting multiple transports and writing the friend - * file. I'm sure *someone* will complain loudly about other - * things that negate these functions even existing so no point in - * "fixing" now. - */ -static int -friend_file_iterator (void *cls, const GNUNET_HashCode * key, void *value) -{ - FILE *temp_friend_handle = cls; - struct GNUNET_TESTING_Daemon *peer = value; - struct GNUNET_PeerIdentity *temppeer; - struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc; - - temppeer = &peer->id; - GNUNET_CRYPTO_hash_to_enc (&temppeer->hashPubKey, &peer_enc); - FPRINTF (temp_friend_handle, "%s\n", (char *) &peer_enc); - - return GNUNET_YES; -} - -struct BlacklistContext -{ - /* - * The (open) file handle to write to - */ - FILE *temp_file_handle; - - /* - * The transport that this peer will be blacklisted on. - */ - char *transport; -}; - -/** - * Iterator for writing blacklist data to appropriate files. - * - * @param cls closure, an open writable file handle - * @param key the key the daemon was stored under - * @param value the GNUNET_TESTING_Daemon that needs to be written. - * - * @return GNUNET_YES to continue iteration - */ -static int -blacklist_file_iterator (void *cls, const GNUNET_HashCode * key, void *value) -{ - struct BlacklistContext *blacklist_ctx = cls; - struct GNUNET_TESTING_Daemon *peer = value; - struct GNUNET_PeerIdentity *temppeer; - struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc; - - temppeer = &peer->id; - GNUNET_CRYPTO_hash_to_enc (&temppeer->hashPubKey, &peer_enc); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Writing entry %s:%s to file\n", - blacklist_ctx->transport, (char *) &peer_enc); - FPRINTF (blacklist_ctx->temp_file_handle, "%s:%s\n", blacklist_ctx->transport, - (char *) &peer_enc); - - return GNUNET_YES; -} -#endif - -/* - * Create the friend files based on the PeerConnection's - * of each peer in the peer group, and copy the files - * to the appropriate place - * - * @param pg the peer group we are dealing with - */ -static int -create_and_copy_friend_files (struct GNUNET_TESTING_PeerGroup *pg) -{ - FILE *temp_friend_handle; - unsigned int pg_iter; - char *temp_service_path; - struct GNUNET_OS_Process **procarr; - char *arg; - char *mytemp; - -#if NOT_STUPID - enum GNUNET_OS_ProcessStatusType type; - unsigned long return_code; - int count; - int max_wait = 10; -#endif - int ret; - - ret = GNUNET_OK; -#if OLD - struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc; - struct PeerConnection *conn_iter; -#endif - procarr = GNUNET_malloc (sizeof (struct GNUNET_OS_Process *) * pg->total); - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - mytemp = GNUNET_DISK_mktemp ("friends"); - GNUNET_assert (mytemp != NULL); - temp_friend_handle = FOPEN (mytemp, "wt"); - GNUNET_assert (temp_friend_handle != NULL); -#if OLD - conn_iter = pg->peers[pg_iter].allowed_peers_head; - while (conn_iter != NULL) - { - GNUNET_CRYPTO_hash_to_enc (&pg->peers[conn_iter->index].daemon-> - id.hashPubKey, &peer_enc); - FPRINTF (temp_friend_handle, "%s\n", (char *) &peer_enc); - conn_iter = conn_iter->next; - } -#else - GNUNET_CONTAINER_multihashmap_iterate (pg->peers[pg_iter].allowed_peers, - &friend_file_iterator, - temp_friend_handle); -#endif - FCLOSE (temp_friend_handle); - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (pg->peers[pg_iter].daemon->cfg, - "PATHS", "SERVICEHOME", - &temp_service_path)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("No `%s' specified in peer configuration in section `%s', cannot copy friends file!\n"), - "SERVICEHOME", "PATHS"); - if (UNLINK (mytemp) != 0) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", mytemp); - GNUNET_free (mytemp); - break; - } - - if (pg->peers[pg_iter].daemon->hostname == NULL) /* Local, just copy the file */ - { - GNUNET_asprintf (&arg, "%s/friends", temp_service_path); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Copying file with RENAME(%s,%s)\n", mytemp, arg); - RENAME (mytemp, arg); - procarr[pg_iter] = NULL; - GNUNET_free (arg); - } - else /* Remote, scp the file to the correct place */ - { - if (NULL != pg->peers[pg_iter].daemon->username) - GNUNET_asprintf (&arg, "%s@%s:%s/friends", - pg->peers[pg_iter].daemon->username, - pg->peers[pg_iter].daemon->hostname, - temp_service_path); - else - GNUNET_asprintf (&arg, "%s:%s/friends", - pg->peers[pg_iter].daemon->hostname, - temp_service_path); - procarr[pg_iter] = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", mytemp, arg, NULL); - GNUNET_assert (procarr[pg_iter] != NULL); - ret = GNUNET_OS_process_wait (procarr[pg_iter]); /* FIXME: schedule this, throttle! */ - GNUNET_OS_process_destroy (procarr[pg_iter]); - if (ret != GNUNET_OK) - { - /* FIXME: free contents of 'procarr' array */ - GNUNET_free (procarr); - GNUNET_free (temp_service_path); - GNUNET_free (mytemp); - GNUNET_free (arg); - return ret; - } - procarr[pg_iter] = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Copying file with command scp %s %s\n", mytemp, arg); - GNUNET_free (arg); - } - GNUNET_free (temp_service_path); - GNUNET_free (mytemp); - } - -#if NOT_STUPID - count = 0; - ret = GNUNET_SYSERR; - while ((count < max_wait) && (ret != GNUNET_OK)) - { - ret = GNUNET_OK; - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking copy status of file %d\n", - pg_iter); - if (procarr[pg_iter] != NULL) /* Check for already completed! */ - { - if (GNUNET_OS_process_status (procarr[pg_iter], &type, &return_code) != - GNUNET_OK) - { - ret = GNUNET_SYSERR; - } - else if ((type != GNUNET_OS_PROCESS_EXITED) || (return_code != 0)) - { - ret = GNUNET_SYSERR; - } - else - { - GNUNET_OS_process_destroy (procarr[pg_iter]); - procarr[pg_iter] = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "File %d copied\n", pg_iter); - } - } - } - count++; - if (ret == GNUNET_SYSERR) - { - /* FIXME: why sleep here? -CG */ - sleep (1); - } - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Finished copying all friend files!\n"); -#endif - GNUNET_free (procarr); - return ret; -} - -/* - * Create the blacklist files based on the PeerConnection's - * of each peer in the peer group, and copy the files - * to the appropriate place. - * - * @param pg the peer group we are dealing with - * @param transports space delimited list of transports to blacklist - */ -static int -create_and_copy_blacklist_files (struct GNUNET_TESTING_PeerGroup *pg, - const char *transports) -{ - FILE *temp_file_handle; - unsigned int pg_iter; - char *temp_service_path; - struct GNUNET_OS_Process **procarr; - char *arg; - char *mytemp; - enum GNUNET_OS_ProcessStatusType type; - unsigned long return_code; - int count; - int ret; - int max_wait = 10; - int transport_len; - unsigned int i; - char *pos; - char *temp_transports; - -#if OLD - struct GNUNET_CRYPTO_HashAsciiEncoded peer_enc; - struct PeerConnection *conn_iter; -#else - static struct BlacklistContext blacklist_ctx; -#endif - - procarr = GNUNET_malloc (sizeof (struct GNUNET_OS_Process *) * pg->total); - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - mytemp = GNUNET_DISK_mktemp ("blacklist"); - GNUNET_assert (mytemp != NULL); - temp_file_handle = FOPEN (mytemp, "wt"); - GNUNET_assert (temp_file_handle != NULL); - temp_transports = GNUNET_strdup (transports); -#if !OLD - blacklist_ctx.temp_file_handle = temp_file_handle; -#endif - transport_len = strlen (temp_transports) + 1; - pos = NULL; - - for (i = 0; i < transport_len; i++) - { - if ((temp_transports[i] == ' ') && (pos == NULL)) - continue; /* At start of string (whitespace) */ - else if ((temp_transports[i] == ' ') || (temp_transports[i] == '\0')) /* At end of string */ - { - temp_transports[i] = '\0'; -#if OLD - conn_iter = pg->peers[pg_iter].blacklisted_peers_head; - while (conn_iter != NULL) - { - GNUNET_CRYPTO_hash_to_enc (&pg->peers[conn_iter->index].daemon-> - id.hashPubKey, &peer_enc); - FPRINTF (temp_file_handle, "%s:%s\n", pos, (char *) &peer_enc); - conn_iter = conn_iter->next; - } -#else - blacklist_ctx.transport = pos; - (void) GNUNET_CONTAINER_multihashmap_iterate (pg-> - peers - [pg_iter].blacklisted_peers, - &blacklist_file_iterator, - &blacklist_ctx); -#endif - pos = NULL; - } /* At beginning of actual string */ - else if (pos == NULL) - { - pos = &temp_transports[i]; - } - } - - GNUNET_free (temp_transports); - FCLOSE (temp_file_handle); - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (pg->peers[pg_iter].daemon->cfg, - "PATHS", "SERVICEHOME", - &temp_service_path)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("No `%s' specified in peer configuration in section `%s', cannot copy friends file!\n"), - "SERVICEHOME", "PATHS"); - if (UNLINK (mytemp) != 0) - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", mytemp); - GNUNET_free (mytemp); - break; - } - - if (pg->peers[pg_iter].daemon->hostname == NULL) /* Local, just copy the file */ - { - GNUNET_asprintf (&arg, "%s/blacklist", temp_service_path); - RENAME (mytemp, arg); - procarr[pg_iter] = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Copying file with RENAME (%s,%s)\n", mytemp, arg); - GNUNET_free (arg); - } - else /* Remote, scp the file to the correct place */ - { - if (NULL != pg->peers[pg_iter].daemon->username) - GNUNET_asprintf (&arg, "%s@%s:%s/blacklist", - pg->peers[pg_iter].daemon->username, - pg->peers[pg_iter].daemon->hostname, - temp_service_path); - else - GNUNET_asprintf (&arg, "%s:%s/blacklist", - pg->peers[pg_iter].daemon->hostname, - temp_service_path); - procarr[pg_iter] = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "scp", "scp", mytemp, arg, NULL); - GNUNET_assert (procarr[pg_iter] != NULL); - GNUNET_OS_process_wait (procarr[pg_iter]); /* FIXME: add scheduled blacklist file copy that parallelizes file copying! */ - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Copying file with command scp %s %s\n", mytemp, arg); - GNUNET_free (arg); - } - GNUNET_free (temp_service_path); - GNUNET_free (mytemp); - } - - count = 0; - ret = GNUNET_SYSERR; - while ((count < max_wait) && (ret != GNUNET_OK)) - { - ret = GNUNET_OK; - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Checking copy status of file %d\n", pg_iter); - if (procarr[pg_iter] != NULL) /* Check for already completed! */ - { - if (GNUNET_OS_process_status (procarr[pg_iter], &type, &return_code) != - GNUNET_OK) - { - ret = GNUNET_SYSERR; - } - else if ((type != GNUNET_OS_PROCESS_EXITED) || (return_code != 0)) - { - ret = GNUNET_SYSERR; - } - else - { - GNUNET_OS_process_destroy (procarr[pg_iter]); - procarr[pg_iter] = NULL; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "File %d copied\n", pg_iter); - } - } - } - count++; - if (ret == GNUNET_SYSERR) - { - /* FIXME: why sleep here? -CG */ - sleep (1); - } - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Finished copying all blacklist files!\n"); - GNUNET_free (procarr); - return ret; -} - -/* Forward Declaration */ -static void -schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - -/** - * Choose a random peer's next connection to create, and - * call schedule_connect to set up the connect task. - * - * @param pg the peer group to connect - */ -static void -preschedule_connect (struct GNUNET_TESTING_PeerGroup *pg) -{ - struct ConnectTopologyContext *ct_ctx = &pg->ct_ctx; - struct PeerConnection *connection_iter; - struct ConnectContext *connect_context; - uint32_t random_peer; - - if (ct_ctx->remaining_connections == 0) - return; - random_peer = - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, pg->total); - while (pg->peers[random_peer].connect_peers_head == NULL) - random_peer = - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, pg->total); - - connection_iter = pg->peers[random_peer].connect_peers_head; - connect_context = GNUNET_malloc (sizeof (struct ConnectContext)); - connect_context->first_index = random_peer; - connect_context->second_index = connection_iter->index; - connect_context->ct_ctx = ct_ctx; - connect_context->task = - GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context); - GNUNET_CONTAINER_DLL_insert (pg->cc_head, pg->cc_tail, connect_context); - GNUNET_CONTAINER_DLL_remove (pg->peers[random_peer].connect_peers_head, - pg->peers[random_peer].connect_peers_tail, - connection_iter); - GNUNET_free (connection_iter); - ct_ctx->remaining_connections--; -} - -#if USE_SEND_HELLOS -/* Forward declaration */ -static void -schedule_send_hellos (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - -/** - * Close connections and free the hello context. - * - * @param cls the 'struct SendHelloContext *' - * @param tc scheduler context - */ -static void -free_hello_context (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct SendHelloContext *send_hello_context = cls; - - if (send_hello_context->peer->daemon->server != NULL) - { - GNUNET_CORE_disconnect (send_hello_context->peer->daemon->server); - send_hello_context->peer->daemon->server = NULL; - } - if (send_hello_context->peer->daemon->th != NULL) - { - GNUNET_TRANSPORT_disconnect (send_hello_context->peer->daemon->th); - send_hello_context->peer->daemon->th = NULL; - } - if (send_hello_context->core_connect_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (send_hello_context->core_connect_task); - send_hello_context->core_connect_task = GNUNET_SCHEDULER_NO_TASK; - } - send_hello_context->pg->outstanding_connects--; - GNUNET_free (send_hello_context); -} - -/** - * For peers that haven't yet connected, notify - * the caller that they have failed (timeout). - * - * @param cls the 'struct SendHelloContext *' - * @param tc scheduler context - */ -static void -notify_remaining_connections_failed (void *cls, - const struct GNUNET_SCHEDULER_TaskContext - *tc) -{ - struct SendHelloContext *send_hello_context = cls; - struct GNUNET_TESTING_PeerGroup *pg = send_hello_context->pg; - struct PeerConnection *connection; - - GNUNET_CORE_disconnect (send_hello_context->peer->daemon->server); - send_hello_context->peer->daemon->server = NULL; - - connection = send_hello_context->peer->connect_peers_head; - - while (connection != NULL) - { - if (pg->notify_connection != NULL) - { - pg->notify_connection (pg->notify_connection_cls, &send_hello_context->peer->daemon->id, &pg->peers[connection->index].daemon->id, 0, /* FIXME */ - send_hello_context->peer->daemon->cfg, - pg->peers[connection->index].daemon->cfg, - send_hello_context->peer->daemon, - pg->peers[connection->index].daemon, - "Peers failed to connect (timeout)"); - } - GNUNET_CONTAINER_DLL_remove (send_hello_context->peer->connect_peers_head, - send_hello_context->peer->connect_peers_tail, - connection); - GNUNET_free (connection); - connection = connection->next; - } - GNUNET_SCHEDULER_add_now (&free_hello_context, send_hello_context); -#if BAD - other_peer = &pg->peers[connection->index]; -#endif -} - -/** - * For peers that haven't yet connected, send - * CORE connect requests. - * - * @param cls the 'struct SendHelloContext *' - * @param tc scheduler context - */ -static void -send_core_connect_requests (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct SendHelloContext *send_hello_context = cls; - struct PeerConnection *conn; - - GNUNET_assert (send_hello_context->peer->daemon->server != NULL); - - send_hello_context->core_connect_task = GNUNET_SCHEDULER_NO_TASK; - - send_hello_context->connect_attempts++; - if (send_hello_context->connect_attempts < - send_hello_context->pg->ct_ctx.connect_attempts) - { - conn = send_hello_context->peer->connect_peers_head; - while (conn != NULL) - { - GNUNET_TRANSPORT_try_connect (send_hello_context->peer->daemon->th, - &send_hello_context->pg->peers[conn-> - index].daemon-> - id); - conn = conn->next; - } - send_hello_context->core_connect_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide - (send_hello_context->pg-> - ct_ctx.connect_timeout, - send_hello_context->pg-> - ct_ctx.connect_attempts), - &send_core_connect_requests, - send_hello_context); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Timeout before all connections created, marking rest as failed!\n"); - GNUNET_SCHEDULER_add_now (¬ify_remaining_connections_failed, - send_hello_context); - } - -} - -/** - * Success, connection is up. Signal client our success. - * - * @param cls our "struct SendHelloContext" - * @param peer identity of the peer that has connected - * @param atsi performance information - * - * FIXME: remove peers from BOTH lists, call notify twice, should - * double the speed of connections as long as the list iteration - * doesn't take too long! - */ -static void -core_connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_ATS_Information *atsi) -{ - struct SendHelloContext *send_hello_context = cls; - struct PeerConnection *connection; - struct GNUNET_TESTING_PeerGroup *pg = send_hello_context->pg; - -#if BAD - struct PeerData *other_peer; -#endif - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected peer %s to peer %s\n", - ctx->d1->shortname, GNUNET_i2s (peer)); - if (0 == - memcmp (&send_hello_context->peer->daemon->id, peer, - sizeof (struct GNUNET_PeerIdentity))) - return; - - connection = send_hello_context->peer->connect_peers_head; -#if BAD - other_peer = NULL; -#endif - - while ((connection != NULL) && - (0 != - memcmp (&pg->peers[connection->index].daemon->id, peer, - sizeof (struct GNUNET_PeerIdentity)))) - { - connection = connection->next; - } - - if (connection == NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connected peer %s to %s, not in list (no problem(?))\n", - GNUNET_i2s (peer), send_hello_context->peer->daemon->shortname); - } - else - { -#if BAD - other_peer = &pg->peers[connection->index]; -#endif - if (pg->notify_connection != NULL) - { - pg->notify_connection (pg->notify_connection_cls, &send_hello_context->peer->daemon->id, peer, 0, /* FIXME */ - send_hello_context->peer->daemon->cfg, - pg->peers[connection->index].daemon->cfg, - send_hello_context->peer->daemon, - pg->peers[connection->index].daemon, NULL); - } - GNUNET_CONTAINER_DLL_remove (send_hello_context->peer->connect_peers_head, - send_hello_context->peer->connect_peers_tail, - connection); - GNUNET_free (connection); - } - -#if BAD - /* Notify of reverse connection and remove from other peers list of outstanding */ - if (other_peer != NULL) - { - connection = other_peer->connect_peers_head; - while ((connection != NULL) && - (0 != - memcmp (&send_hello_context->peer->daemon->id, - &pg->peers[connection->index].daemon->id, - sizeof (struct GNUNET_PeerIdentity)))) - { - connection = connection->next; - } - if (connection != NULL) - { - if (pg->notify_connection != NULL) - { - pg->notify_connection (pg->notify_connection_cls, peer, &send_hello_context->peer->daemon->id, 0, /* FIXME */ - pg->peers[connection->index].daemon->cfg, - send_hello_context->peer->daemon->cfg, - pg->peers[connection->index].daemon, - send_hello_context->peer->daemon, NULL); - } - - GNUNET_CONTAINER_DLL_remove (other_peer->connect_peers_head, - other_peer->connect_peers_tail, connection); - GNUNET_free (connection); - } - } -#endif - - if (send_hello_context->peer->connect_peers_head == NULL) - { - GNUNET_SCHEDULER_add_now (&free_hello_context, send_hello_context); - } -} - -/** - * Notify of a successful connection to the core service. - * - * @param cls a struct SendHelloContext * - * @param server handle to the core service - * @param my_identity the peer identity of this peer - */ -void -core_init (void *cls, struct GNUNET_CORE_Handle *server, - struct GNUNET_PeerIdentity *my_identity) -{ - struct SendHelloContext *send_hello_context = cls; - - send_hello_context->core_ready = GNUNET_YES; -} - -/** - * Function called once a hello has been sent - * to the transport, move on to the next one - * or go away forever. - * - * @param cls the 'struct SendHelloContext *' - * @param tc scheduler context - */ -static void -hello_sent_callback (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct SendHelloContext *send_hello_context = cls; - - //unsigned int pg_iter; - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) - { - GNUNET_free (send_hello_context); - return; - } - - send_hello_context->pg->remaining_hellos--; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sent HELLO, have %d remaining!\n", - send_hello_context->pg->remaining_hellos); - if (send_hello_context->peer_pos == NULL) /* All HELLOs (for this peer!) have been transmitted! */ - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All hellos for this peer sent, disconnecting transport!\n"); - GNUNET_assert (send_hello_context->peer->daemon->th != NULL); - GNUNET_TRANSPORT_disconnect (send_hello_context->peer->daemon->th); - send_hello_context->peer->daemon->th = NULL; - GNUNET_assert (send_hello_context->peer->daemon->server == NULL); - send_hello_context->peer->daemon->server = - GNUNET_CORE_connect (send_hello_context->peer->cfg, 1, - send_hello_context, &core_init, - &core_connect_notify, NULL, NULL, NULL, GNUNET_NO, - NULL, GNUNET_NO, no_handlers); - - send_hello_context->core_connect_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide - (send_hello_context->pg-> - ct_ctx.connect_timeout, - send_hello_context->pg-> - ct_ctx.connect_attempts), - &send_core_connect_requests, - send_hello_context); - } - else - GNUNET_SCHEDULER_add_now (&schedule_send_hellos, send_hello_context); -} - -/** - * Connect to a peer, give it all the HELLO's of those peers - * we will later ask it to connect to. - * - * @param ct_ctx the overall connection context - */ -static void -schedule_send_hellos (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct SendHelloContext *send_hello_context = cls; - struct GNUNET_TESTING_PeerGroup *pg = send_hello_context->pg; - - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) - { - GNUNET_free (send_hello_context); - return; - } - - GNUNET_assert (send_hello_context->peer_pos != NULL); /* All of the HELLO sends to be scheduled have been scheduled! */ - - if (((send_hello_context->peer->daemon->th == NULL) && - (pg->outstanding_connects > pg->max_outstanding_connections)) || - (pg->stop_connects == GNUNET_YES)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Delaying connect, we have too many outstanding connections!\n"); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 100), - &schedule_send_hellos, send_hello_context); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating connection, outstanding_connections is %d\n", - outstanding_connects); - if (send_hello_context->peer->daemon->th == NULL) - { - pg->outstanding_connects++; /* Actual TRANSPORT, CORE connections! */ - send_hello_context->peer->daemon->th = - GNUNET_TRANSPORT_connect (send_hello_context->peer->cfg, NULL, - send_hello_context, NULL, NULL, NULL); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Offering HELLO of peer %s to peer %s\n", - send_hello_context->peer->daemon->shortname, - pg->peers[send_hello_context->peer_pos->index]. - daemon->shortname); - GNUNET_TRANSPORT_offer_hello (send_hello_context->peer->daemon->th, - (const struct GNUNET_MessageHeader *) - pg->peers[send_hello_context->peer_pos-> - index].daemon->hello, - &hello_sent_callback, send_hello_context); - send_hello_context->peer_pos = send_hello_context->peer_pos->next; - GNUNET_assert (send_hello_context->peer->daemon->th != NULL); - } -} -#endif - -/** - * Internal notification of a connection, kept so that we can ensure some connections - * happen instead of flooding all testing daemons with requests to connect. - */ -static void -internal_connect_notify (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) -{ - struct ConnectContext *connect_ctx = cls; - struct ConnectTopologyContext *ct_ctx = connect_ctx->ct_ctx; - struct GNUNET_TESTING_PeerGroup *pg = ct_ctx->pg; - struct PeerConnection *connection; - - GNUNET_assert (NULL != connect_ctx->cc); - connect_ctx->cc = NULL; - GNUNET_assert (0 < pg->outstanding_connects); - pg->outstanding_connects--; - GNUNET_CONTAINER_DLL_remove (pg->cc_head, pg->cc_tail, connect_ctx); - /* - * Check whether the inverse connection has been scheduled yet, - * if not, we can remove it from the other peers list and avoid - * even trying to connect them again! - */ - connection = pg->peers[connect_ctx->second_index].connect_peers_head; -#if BAD - other_peer = NULL; -#endif - - while ((connection != NULL) && - (0 != - memcmp (first, &pg->peers[connection->index].daemon->id, - sizeof (struct GNUNET_PeerIdentity)))) - connection = connection->next; - - if (connection != NULL) /* Can safely remove! */ - { - GNUNET_assert (0 < ct_ctx->remaining_connections); - ct_ctx->remaining_connections--; - if (pg->notify_connection != NULL) /* Notify of reverse connection */ - pg->notify_connection (pg->notify_connection_cls, second, first, distance, - second_cfg, first_cfg, second_daemon, first_daemon, - emsg); - - GNUNET_CONTAINER_DLL_remove (pg-> - peers[connect_ctx-> - second_index].connect_peers_head, - pg->peers[connect_ctx-> - second_index].connect_peers_tail, - connection); - GNUNET_free (connection); - } - - if (ct_ctx->remaining_connections == 0) - { - if (ct_ctx->notify_connections_done != NULL) - { - ct_ctx->notify_connections_done (ct_ctx->notify_cls, NULL); - ct_ctx->notify_connections_done = NULL; - } - } - else - preschedule_connect (pg); - - if (pg->notify_connection != NULL) - pg->notify_connection (pg->notify_connection_cls, first, second, distance, - first_cfg, second_cfg, first_daemon, second_daemon, - emsg); - GNUNET_free (connect_ctx); -} - -/** - * Either delay a connection (because there are too many outstanding) - * or schedule it for right now. - * - * @param cls a connection context - * @param tc the task runtime context - */ -static void -schedule_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct ConnectContext *connect_context = cls; - struct GNUNET_TESTING_PeerGroup *pg = connect_context->ct_ctx->pg; - - connect_context->task = GNUNET_SCHEDULER_NO_TASK; - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) - return; - - if ((pg->outstanding_connects > pg->max_outstanding_connections) || - (pg->stop_connects == GNUNET_YES)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Delaying connect, we have too many outstanding connections!\n"); - connect_context->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 100), - &schedule_connect, connect_context); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating connection, outstanding_connections is %d (max %d)\n", - pg->outstanding_connects, pg->max_outstanding_connections); - pg->outstanding_connects++; - pg->total_connects_scheduled++; - GNUNET_assert (NULL == connect_context->cc); - connect_context->cc = - GNUNET_TESTING_daemons_connect (pg-> - peers[connect_context-> - first_index].daemon, - pg->peers[connect_context-> - second_index].daemon, - connect_context->ct_ctx->connect_timeout, - connect_context->ct_ctx->connect_attempts, -#if USE_SEND_HELLOS - GNUNET_NO, -#else - GNUNET_YES, -#endif - &internal_connect_notify, - connect_context); - -} - -#if !OLD -/** - * Iterator for actually scheduling connections to be created - * between two peers. - * - * @param cls closure, a GNUNET_TESTING_Daemon - * @param key the key the second Daemon was stored under - * @param value the GNUNET_TESTING_Daemon that the first is to connect to - * - * @return GNUNET_YES to continue iteration - */ -static int -connect_iterator (void *cls, const GNUNET_HashCode * key, void *value) -{ - struct ConnectTopologyContext *ct_ctx = cls; - struct PeerData *first = ct_ctx->first; - struct GNUNET_TESTING_Daemon *second = value; - struct ConnectContext *connect_context; - - connect_context = GNUNET_malloc (sizeof (struct ConnectContext)); - connect_context->first = first->daemon; - connect_context->second = second; - connect_context->ct_ctx = ct_ctx; - connect_context->task = - GNUNET_SCHEDULER_add_now (&schedule_connect, connect_context); - GNUNET_CONTAINER_DLL_insert (ct_ctx->pg->cc_head, ct_ctx->pg->cc_tail, - connect_context); - return GNUNET_YES; -} -#endif - -#if !OLD -/** - * Iterator for copying all entries in the allowed hashmap to the - * connect hashmap. - * - * @param cls closure, a GNUNET_TESTING_Daemon - * @param key the key the second Daemon was stored under - * @param value the GNUNET_TESTING_Daemon that the first is to connect to - * - * @return GNUNET_YES to continue iteration - */ -static int -copy_topology_iterator (void *cls, const GNUNET_HashCode * key, void *value) -{ - struct PeerData *first = cls; - - GNUNET_assert (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (first->connect_peers, key, - value, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - - return GNUNET_YES; -} -#endif - -/** - * Make the peers to connect the same as those that are allowed to be - * connected. - * - * @param pg the peer group - */ -static int -copy_allowed_topology (struct GNUNET_TESTING_PeerGroup *pg) -{ - unsigned int pg_iter; - int ret; - int total; - -#if OLD - struct PeerConnection *iter; -#endif - total = 0; - ret = 0; - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { -#if OLD - iter = pg->peers[pg_iter].allowed_peers_head; - while (iter != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating connection between %d and %d\n", pg_iter, - iter->index); - total += add_connections (pg, pg_iter, iter->index, CONNECT, GNUNET_YES); - //total += add_actual_connections(pg, pg_iter, iter->index); - iter = iter->next; - } -#else - ret = - GNUNET_CONTAINER_multihashmap_iterate (pg->peers[pg_iter].allowed_peers, - ©_topology_iterator, - &pg->peers[pg_iter]); -#endif - if (GNUNET_SYSERR == ret) - return GNUNET_SYSERR; - - total = total + ret; - } - - return total; -} - -/** - * Connect the topology as specified by the PeerConnection's - * of each peer in the peer group - * - * @param pg the peer group we are dealing with - * @param connect_timeout how long try connecting two peers - * @param connect_attempts how many times (max) to attempt - * @param notify_callback callback to notify when finished - * @param notify_cls closure for notify callback - * - * @return the number of connections that will be attempted - */ -static int -connect_topology (struct GNUNET_TESTING_PeerGroup *pg, - struct GNUNET_TIME_Relative connect_timeout, - unsigned int connect_attempts, - GNUNET_TESTING_NotifyCompletion notify_callback, - void *notify_cls) -{ - unsigned int pg_iter; - unsigned int total; - -#if OLD - struct PeerConnection *connection_iter; -#endif -#if USE_SEND_HELLOS - struct SendHelloContext *send_hello_context; -#endif - - total = 0; - pg->ct_ctx.notify_connections_done = notify_callback; - pg->ct_ctx.notify_cls = notify_cls; - pg->ct_ctx.pg = pg; - - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { -#if OLD - connection_iter = pg->peers[pg_iter].connect_peers_head; - while (connection_iter != NULL) - { - connection_iter = connection_iter->next; - total++; - } -#else - total += - GNUNET_CONTAINER_multihashmap_size (pg->peers[pg_iter].connect_peers); -#endif - } - - if (total == 0) - return total; - - pg->ct_ctx.connect_timeout = connect_timeout; - pg->ct_ctx.connect_attempts = connect_attempts; - pg->ct_ctx.remaining_connections = total; - -#if USE_SEND_HELLOS - /* First give all peers the HELLO's of other peers (connect to first peer's transport service, give HELLO's of other peers, continue...) */ - pg->remaining_hellos = total; - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - send_hello_context = GNUNET_malloc (sizeof (struct SendHelloContext)); - send_hello_context->peer = &pg->peers[pg_iter]; - send_hello_context->peer_pos = pg->peers[pg_iter].connect_peers_head; - send_hello_context->pg = pg; - GNUNET_SCHEDULER_add_now (&schedule_send_hellos, send_hello_context); - } -#else - for (pg_iter = 0; pg_iter < pg->max_outstanding_connections; pg_iter++) - { - preschedule_connect (pg); - } -#endif - return total; - -} - -/** - * Takes a peer group and creates a topology based on the - * one specified. Creates a topology means generates friend - * files for the peers so they can only connect to those allowed - * by the topology. This will only have an effect once peers - * are started if the FRIENDS_ONLY option is set in the base - * config. Also takes an optional restrict topology which - * disallows connections based on particular transports - * UNLESS they are specified in the restricted topology. - * - * @param pg the peer group struct representing the running peers - * @param topology which topology to connect the peers in - * @param restrict_topology disallow restrict_transports transport - * connections to peers NOT in this topology - * use GNUNET_TESTING_TOPOLOGY_NONE for no restrictions - * @param restrict_transports space delimited list of transports to blacklist - * to create restricted topology - * - * @return the maximum number of connections were all allowed peers - * connected to each other - */ -unsigned int -GNUNET_TESTING_create_topology (struct GNUNET_TESTING_PeerGroup *pg, - enum GNUNET_TESTING_Topology topology, - enum GNUNET_TESTING_Topology restrict_topology, - const char *restrict_transports) -{ - int ret; - - unsigned int num_connections; - int unblacklisted_connections; - char *filename; - struct PeerConnection *conn_iter; - struct PeerConnection *temp_conn; - unsigned int off; - -#if !OLD - unsigned int i; - - for (i = 0; i < pg->total; i++) - { - pg->peers[i].allowed_peers = GNUNET_CONTAINER_multihashmap_create (100); - pg->peers[i].connect_peers = GNUNET_CONTAINER_multihashmap_create (100); - pg->peers[i].blacklisted_peers = GNUNET_CONTAINER_multihashmap_create (100); - pg->peers[i].pg = pg; - } -#endif - - switch (topology) - { - case GNUNET_TESTING_TOPOLOGY_CLIQUE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating clique topology\n"); - num_connections = create_clique (pg, &add_connections, ALLOWED, GNUNET_NO); - break; - case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating small world (ring) topology\n"); - num_connections = create_small_world_ring (pg, &add_connections, ALLOWED); - break; - case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating small world (2d-torus) topology\n"); - num_connections = create_small_world (pg, &add_connections, ALLOWED); - break; - case GNUNET_TESTING_TOPOLOGY_RING: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating ring topology\n"); - num_connections = create_ring (pg, &add_connections, ALLOWED); - break; - case GNUNET_TESTING_TOPOLOGY_2D_TORUS: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating 2d torus topology\n"); - num_connections = create_2d_torus (pg, &add_connections, ALLOWED); - break; - case GNUNET_TESTING_TOPOLOGY_ERDOS_RENYI: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating Erdos-Renyi topology\n"); - num_connections = create_erdos_renyi (pg, &add_connections, ALLOWED); - break; - case GNUNET_TESTING_TOPOLOGY_INTERNAT: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating InterNAT topology\n"); - num_connections = create_nated_internet (pg, &add_connections, ALLOWED); - break; - case GNUNET_TESTING_TOPOLOGY_SCALE_FREE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating Scale Free topology\n"); - num_connections = create_scale_free (pg, &add_connections, ALLOWED); - break; - case GNUNET_TESTING_TOPOLOGY_LINE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating straight line topology\n"); - num_connections = create_line (pg, &add_connections, ALLOWED); - break; - case GNUNET_TESTING_TOPOLOGY_FROM_FILE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating topology from file!\n"); - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (pg->cfg, "testing", - "topology_file", &filename)) - num_connections = - create_from_file (pg, filename, &add_connections, ALLOWED); - else - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Missing configuration option TESTING:TOPOLOGY_FILE for creating topology from file!\n"); - num_connections = 0; - } - break; - case GNUNET_TESTING_TOPOLOGY_NONE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _ - ("Creating no allowed topology (all peers can connect at core level)\n")); - num_connections = pg->total * pg->total; /* Clique is allowed! */ - break; - default: - num_connections = 0; - break; - } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno (pg->cfg, "TESTING", "F2F")) - { - ret = create_and_copy_friend_files (pg); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed during friend file copying!\n"); - return GNUNET_SYSERR; - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Friend files created/copied successfully!\n"); - } - } - - /* Use the create clique method to initially set all connections as blacklisted. */ - if ((restrict_topology != GNUNET_TESTING_TOPOLOGY_NONE) && - (restrict_topology != GNUNET_TESTING_TOPOLOGY_FROM_FILE)) - create_clique (pg, &add_connections, BLACKLIST, GNUNET_NO); - else - return num_connections; - - unblacklisted_connections = 0; - /* Un-blacklist connections as per the topology specified */ - switch (restrict_topology) - { - case GNUNET_TESTING_TOPOLOGY_CLIQUE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklisting all but clique topology\n"); - unblacklisted_connections = - create_clique (pg, &remove_connections, BLACKLIST, GNUNET_NO); - break; - case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklisting all but small world (ring) topology\n"); - unblacklisted_connections = - create_small_world_ring (pg, &remove_connections, BLACKLIST); - break; - case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklisting all but small world (2d-torus) topology\n"); - unblacklisted_connections = - create_small_world (pg, &remove_connections, BLACKLIST); - break; - case GNUNET_TESTING_TOPOLOGY_RING: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklisting all but ring topology\n"); - unblacklisted_connections = - create_ring (pg, &remove_connections, BLACKLIST); - break; - case GNUNET_TESTING_TOPOLOGY_2D_TORUS: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklisting all but 2d torus topology\n"); - unblacklisted_connections = - create_2d_torus (pg, &remove_connections, BLACKLIST); - break; - case GNUNET_TESTING_TOPOLOGY_ERDOS_RENYI: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklisting all but Erdos-Renyi topology\n"); - unblacklisted_connections = - create_erdos_renyi (pg, &remove_connections, BLACKLIST); - break; - case GNUNET_TESTING_TOPOLOGY_INTERNAT: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklisting all but InterNAT topology\n"); - -#if TOPOLOGY_HACK - for (off = 0; off < pg->total; off++) - { - conn_iter = pg->peers[off].allowed_peers_head; - while (conn_iter != NULL) - { - temp_conn = conn_iter->next; - GNUNET_free (conn_iter); - conn_iter = temp_conn; - } - pg->peers[off].allowed_peers_head = NULL; - pg->peers[off].allowed_peers_tail = NULL; - - conn_iter = pg->peers[off].connect_peers_head; - while (conn_iter != NULL) - { - temp_conn = conn_iter->next; - GNUNET_free (conn_iter); - conn_iter = temp_conn; - } - pg->peers[off].connect_peers_head = NULL; - pg->peers[off].connect_peers_tail = NULL; - } - unblacklisted_connections = - create_nated_internet_copy (pg, &remove_connections, BLACKLIST); -#else - unblacklisted_connections = - create_nated_internet (pg, &remove_connections, BLACKLIST); -#endif - - break; - case GNUNET_TESTING_TOPOLOGY_SCALE_FREE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklisting all but Scale Free topology\n"); - unblacklisted_connections = - create_scale_free (pg, &remove_connections, BLACKLIST); - break; - case GNUNET_TESTING_TOPOLOGY_LINE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklisting all but straight line topology\n"); - unblacklisted_connections = - create_line (pg, &remove_connections, BLACKLIST); - default: - break; - } - - if ((unblacklisted_connections > 0) && (restrict_transports != NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating blacklist with `%s'\n", - restrict_transports); - ret = create_and_copy_blacklist_files (pg, restrict_transports); - if (ret != GNUNET_OK) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed during blacklist file copying!\n"); - return 0; - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklist files created/copied successfully!\n"); - } - } - return num_connections; -} - -#if !OLD -/** - * Iterator for choosing random peers to connect. - * - * @param cls closure, a RandomContext - * @param key the key the second Daemon was stored under - * @param value the GNUNET_TESTING_Daemon that the first is to connect to - * - * @return GNUNET_YES to continue iteration - */ -static int -random_connect_iterator (void *cls, const GNUNET_HashCode * key, void *value) -{ - struct RandomContext *random_ctx = cls; - double random_number; - uint32_t second_pos; - GNUNET_HashCode first_hash; - - random_number = - ((double) - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - UINT64_MAX)) / ((double) UINT64_MAX); - if (random_number < random_ctx->percentage) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (random_ctx-> - first->connect_peers_working_set, - key, value, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - } - - /* Now we have considered this particular connection, remove it from the second peer so it's not double counted */ - uid_from_hash (key, &second_pos); - hash_from_uid (random_ctx->first_uid, &first_hash); - GNUNET_assert (random_ctx->pg->total > second_pos); - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (random_ctx-> - pg->peers - [second_pos].connect_peers, - &first_hash, - random_ctx-> - first->daemon)); - - return GNUNET_YES; -} - -/** - * Iterator for adding at least X peers to a peers connection set. - * - * @param cls closure, MinimumContext - * @param key the key the second Daemon was stored under - * @param value the GNUNET_TESTING_Daemon that the first is to connect to - * - * @return GNUNET_YES to continue iteration - */ -static int -minimum_connect_iterator (void *cls, const GNUNET_HashCode * key, void *value) -{ - struct MinimumContext *min_ctx = cls; - uint32_t second_pos; - GNUNET_HashCode first_hash; - unsigned int i; - - if (GNUNET_CONTAINER_multihashmap_size - (min_ctx->first->connect_peers_working_set) < min_ctx->num_to_add) - { - for (i = 0; i < min_ctx->num_to_add; i++) - { - if (min_ctx->pg_array[i] == min_ctx->current) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (min_ctx-> - first->connect_peers_working_set, - key, value, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - uid_from_hash (key, &second_pos); - hash_from_uid (min_ctx->first_uid, &first_hash); - GNUNET_assert (min_ctx->pg->total > second_pos); - GNUNET_assert (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (min_ctx-> - pg->peers - [second_pos].connect_peers_working_set, - &first_hash, - min_ctx->first-> - daemon, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - /* Now we have added this particular connection, remove it from the second peer's map so it's not double counted */ - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (min_ctx-> - pg->peers - [second_pos].connect_peers, - &first_hash, - min_ctx-> - first->daemon)); - } - } - min_ctx->current++; - return GNUNET_YES; - } - else - return GNUNET_NO; /* We can stop iterating, we have enough peers! */ - -} - -/** - * Iterator for adding peers to a connection set based on a depth first search. - * - * @param cls closure, MinimumContext - * @param key the key the second daemon was stored under - * @param value the GNUNET_TESTING_Daemon that the first is to connect to - * - * @return GNUNET_YES to continue iteration - */ -static int -dfs_connect_iterator (void *cls, const GNUNET_HashCode * key, void *value) -{ - struct DFSContext *dfs_ctx = cls; - GNUNET_HashCode first_hash; - - if (dfs_ctx->current == dfs_ctx->chosen) - { - GNUNET_assert (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (dfs_ctx-> - first->connect_peers_working_set, - key, value, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - uid_from_hash (key, &dfs_ctx->second_uid); - hash_from_uid (dfs_ctx->first_uid, &first_hash); - GNUNET_assert (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (dfs_ctx-> - pg->peers[dfs_ctx-> - second_uid].connect_peers_working_set, - &first_hash, - dfs_ctx->first->daemon, - GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (dfs_ctx-> - pg->peers - [dfs_ctx->second_uid].connect_peers, - &first_hash, - dfs_ctx-> - first->daemon)); - /* Can't remove second from first yet because we are currently iterating, hence the return value in the DFSContext! */ - return GNUNET_NO; /* We have found our peer, don't iterate more */ - } - - dfs_ctx->current++; - return GNUNET_YES; -} -#endif - -/** - * From the set of connections possible, choose percentage percent of connections - * to actually connect. - * - * @param pg the peergroup we are dealing with - * @param percentage what percent of total connections to make - */ -void -choose_random_connections (struct GNUNET_TESTING_PeerGroup *pg, - double percentage) -{ - uint32_t pg_iter; - -#if OLD - struct PeerConnection *conn_iter; - double random_number; -#else - struct RandomContext random_ctx; -#endif - - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { -#if OLD - conn_iter = pg->peers[pg_iter].connect_peers_head; - while (conn_iter != NULL) - { - random_number = - ((double) - GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, - UINT64_MAX)) / ((double) UINT64_MAX); - if (random_number < percentage) - { - add_connections (pg, pg_iter, conn_iter->index, WORKING_SET, - GNUNET_YES); - } - conn_iter = conn_iter->next; - } -#else - random_ctx.first_uid = pg_iter; - random_ctx.first = &pg->peers[pg_iter]; - random_ctx.percentage = percentage; - random_ctx.pg = pg; - pg->peers[pg_iter].connect_peers_working_set = - GNUNET_CONTAINER_multihashmap_create (pg->total); - GNUNET_CONTAINER_multihashmap_iterate (pg->peers[pg_iter].connect_peers, - &random_connect_iterator, - &random_ctx); - /* Now remove the old connections */ - GNUNET_CONTAINER_multihashmap_destroy (pg->peers[pg_iter].connect_peers); - /* And replace with the random set */ - pg->peers[pg_iter].connect_peers = - pg->peers[pg_iter].connect_peers_working_set; -#endif - } - - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - conn_iter = pg->peers[pg_iter].connect_peers_head; - while (pg->peers[pg_iter].connect_peers_head != NULL) - remove_connections (pg, pg_iter, - pg->peers[pg_iter].connect_peers_head->index, CONNECT, - GNUNET_YES); - - pg->peers[pg_iter].connect_peers_head = - pg->peers[pg_iter].connect_peers_working_set_head; - pg->peers[pg_iter].connect_peers_tail = - pg->peers[pg_iter].connect_peers_working_set_tail; - pg->peers[pg_iter].connect_peers_working_set_head = NULL; - pg->peers[pg_iter].connect_peers_working_set_tail = NULL; - } -} - -/** - * Count the number of connections in a linked list of connections. - * - * @param conn_list the connection list to get the count of - * - * @return the number of elements in the list - */ -static unsigned int -count_connections (struct PeerConnection *conn_list) -{ - struct PeerConnection *iter; - unsigned int count; - - count = 0; - iter = conn_list; - while (iter != NULL) - { - iter = iter->next; - count++; - } - return count; -} - -static unsigned int -count_workingset_connections (struct GNUNET_TESTING_PeerGroup *pg) -{ - unsigned int count; - unsigned int pg_iter; - -#if OLD - struct PeerConnection *conn_iter; -#endif - count = 0; - - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { -#if OLD - conn_iter = pg->peers[pg_iter].connect_peers_working_set_head; - while (conn_iter != NULL) - { - count++; - conn_iter = conn_iter->next; - } -#else - count += - GNUNET_CONTAINER_multihashmap_size (pg-> - peers - [pg_iter].connect_peers_working_set); -#endif - } - - return count; -} - -static unsigned int -count_allowed_connections (struct GNUNET_TESTING_PeerGroup *pg) -{ - unsigned int count; - unsigned int pg_iter; - -#if OLD - struct PeerConnection *conn_iter; -#endif - - count = 0; - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { -#if OLD - conn_iter = pg->peers[pg_iter].allowed_peers_head; - while (conn_iter != NULL) - { - count++; - conn_iter = conn_iter->next; - } -#else - count += - GNUNET_CONTAINER_multihashmap_size (pg->peers[pg_iter].allowed_peers); -#endif - } - - return count; -} - -/** - * From the set of connections possible, choose at least num connections per - * peer. - * - * @param pg the peergroup we are dealing with - * @param num how many connections at least should each peer have (if possible)? - */ -static void -choose_minimum (struct GNUNET_TESTING_PeerGroup *pg, unsigned int num) -{ -#if !OLD - struct MinimumContext minimum_ctx; -#else - struct PeerConnection *conn_iter; - unsigned int temp_list_size; - unsigned int i; - unsigned int count; - uint32_t random; /* Random list entry to connect peer to */ -#endif - uint32_t pg_iter; - -#if OLD - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - temp_list_size = count_connections (pg->peers[pg_iter].connect_peers_head); - if (temp_list_size == 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Peer %d has 0 connections!?!?\n", - pg_iter); - break; - } - for (i = 0; i < num; i++) - { - random = - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, temp_list_size); - conn_iter = pg->peers[pg_iter].connect_peers_head; - for (count = 0; count < random; count++) - conn_iter = conn_iter->next; - /* We now have a random connection, connect it! */ - GNUNET_assert (conn_iter != NULL); - add_connections (pg, pg_iter, conn_iter->index, WORKING_SET, GNUNET_YES); - } - } -#else - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - pg->peers[pg_iter].connect_peers_working_set = - GNUNET_CONTAINER_multihashmap_create (num); - } - - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - minimum_ctx.first_uid = pg_iter; - minimum_ctx.pg_array = - GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, - GNUNET_CONTAINER_multihashmap_size - (pg->peers[pg_iter].connect_peers)); - minimum_ctx.first = &pg->peers[pg_iter]; - minimum_ctx.pg = pg; - minimum_ctx.num_to_add = num; - minimum_ctx.current = 0; - GNUNET_CONTAINER_multihashmap_iterate (pg->peers[pg_iter].connect_peers, - &minimum_connect_iterator, - &minimum_ctx); - } - - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - /* Remove the "old" connections */ - GNUNET_CONTAINER_multihashmap_destroy (pg->peers[pg_iter].connect_peers); - /* And replace with the working set */ - pg->peers[pg_iter].connect_peers = - pg->peers[pg_iter].connect_peers_working_set; - } -#endif - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - while (pg->peers[pg_iter].connect_peers_head != NULL) - { - conn_iter = pg->peers[pg_iter].connect_peers_head; - GNUNET_CONTAINER_DLL_remove (pg->peers[pg_iter].connect_peers_head, - pg->peers[pg_iter].connect_peers_tail, - conn_iter); - GNUNET_free (conn_iter); - /*remove_connections(pg, pg_iter, pg->peers[pg_iter].connect_peers_head->index, CONNECT, GNUNET_YES); */ - } - - pg->peers[pg_iter].connect_peers_head = - pg->peers[pg_iter].connect_peers_working_set_head; - pg->peers[pg_iter].connect_peers_tail = - pg->peers[pg_iter].connect_peers_working_set_tail; - pg->peers[pg_iter].connect_peers_working_set_head = NULL; - pg->peers[pg_iter].connect_peers_working_set_tail = NULL; - } -} - -#if !OLD -struct FindClosestContext -{ - /** - * The currently known closest peer. - */ - struct GNUNET_TESTING_Daemon *closest; - - /** - * The info for the peer we are adding connections for. - */ - struct PeerData *curr_peer; - - /** - * The distance (bits) between the current - * peer and the currently known closest. - */ - unsigned int closest_dist; - - /** - * The offset of the closest known peer in - * the peer group. - */ - unsigned int closest_num; -}; - -/** - * Iterator over hash map entries of the allowed - * peer connections. Find the closest, not already - * connected peer and return it. - * - * @param cls closure (struct FindClosestContext) - * @param key current key code (hash of offset in pg) - * @param value value in the hash map - a GNUNET_TESTING_Daemon - * @return GNUNET_YES if we should continue to - * iterate, - * GNUNET_NO if not. - */ -static int -find_closest_peers (void *cls, const GNUNET_HashCode * key, void *value) -{ - struct FindClosestContext *closest_ctx = cls; - struct GNUNET_TESTING_Daemon *daemon = value; - - if (((closest_ctx->closest == NULL) || - (GNUNET_CRYPTO_hash_matching_bits - (&daemon->id.hashPubKey, - &closest_ctx->curr_peer->daemon->id.hashPubKey) > - closest_ctx->closest_dist)) && - (GNUNET_YES != - GNUNET_CONTAINER_multihashmap_contains (closest_ctx-> - curr_peer->connect_peers, key))) - { - closest_ctx->closest_dist = - GNUNET_CRYPTO_hash_matching_bits (&daemon->id.hashPubKey, - &closest_ctx->curr_peer->daemon-> - id.hashPubKey); - closest_ctx->closest = daemon; - uid_from_hash (key, &closest_ctx->closest_num); - } - return GNUNET_YES; -} - -/** - * From the set of connections possible, choose at num connections per - * peer based on depth which are closest out of those allowed. Guaranteed - * to add num peers to connect to, provided there are that many peers - * in the underlay topology to connect to. - * - * @param pg the peergroup we are dealing with - * @param num how many connections at least should each peer have (if possible)? - * @param proc processor to actually add the connections - * @param list the peer list to use - */ -void -add_closest (struct GNUNET_TESTING_PeerGroup *pg, unsigned int num, - GNUNET_TESTING_ConnectionProcessor proc, enum PeerLists list) -{ -#if OLD - -#else - struct FindClosestContext closest_ctx; -#endif - uint32_t pg_iter; - uint32_t i; - - for (i = 0; i < num; i++) /* Each time find a closest peer (from those available) */ - { - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - closest_ctx.curr_peer = &pg->peers[pg_iter]; - closest_ctx.closest = NULL; - closest_ctx.closest_dist = 0; - closest_ctx.closest_num = 0; - GNUNET_CONTAINER_multihashmap_iterate (pg->peers[pg_iter].allowed_peers, - &find_closest_peers, &closest_ctx); - if (closest_ctx.closest != NULL) - { - GNUNET_assert (closest_ctx.closest_num < pg->total); - proc (pg, pg_iter, closest_ctx.closest_num, list); - } - } - } -} -#endif - -/** - * From the set of connections possible, choose at least num connections per - * peer based on depth first traversal of peer connections. If DFS leaves - * peers unconnected, ensure those peers get connections. - * - * @param pg the peergroup we are dealing with - * @param num how many connections at least should each peer have (if possible)? - */ -void -perform_dfs (struct GNUNET_TESTING_PeerGroup *pg, unsigned int num) -{ - uint32_t pg_iter; - uint32_t dfs_count; - uint32_t starting_peer; - uint32_t least_connections; - uint32_t random_connection; - -#if OLD - unsigned int temp_count; - struct PeerConnection *peer_iter; -#else - struct DFSContext dfs_ctx; - GNUNET_HashCode second_hash; -#endif - -#if OLD - starting_peer = 0; - dfs_count = 0; - while ((count_workingset_connections (pg) < num * pg->total) && - (count_allowed_connections (pg) > 0)) - { - if (dfs_count % pg->total == 0) /* Restart the DFS at some weakly connected peer */ - { - least_connections = -1; /* Set to very high number */ - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - temp_count = - count_connections (pg-> - peers[pg_iter].connect_peers_working_set_head); - if (temp_count < least_connections) - { - starting_peer = pg_iter; - least_connections = temp_count; - } - } - } - - temp_count = - count_connections (pg->peers[starting_peer].connect_peers_head); - if (temp_count == 0) - continue; /* FIXME: infinite loop? */ - - random_connection = - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, temp_count); - temp_count = 0; - peer_iter = pg->peers[starting_peer].connect_peers_head; - while (temp_count < random_connection) - { - peer_iter = peer_iter->next; - temp_count++; - } - GNUNET_assert (peer_iter != NULL); - add_connections (pg, starting_peer, peer_iter->index, WORKING_SET, - GNUNET_NO); - remove_connections (pg, starting_peer, peer_iter->index, CONNECT, - GNUNET_YES); - starting_peer = peer_iter->index; - dfs_count++; - } - -#else - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - pg->peers[pg_iter].connect_peers_working_set = - GNUNET_CONTAINER_multihashmap_create (num); - } - - starting_peer = 0; - dfs_count = 0; - while ((count_workingset_connections (pg) < num * pg->total) && - (count_allowed_connections (pg) > 0)) - { - if (dfs_count % pg->total == 0) /* Restart the DFS at some weakly connected peer */ - { - least_connections = -1; /* Set to very high number */ - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - if (GNUNET_CONTAINER_multihashmap_size - (pg->peers[pg_iter].connect_peers_working_set) < least_connections) - { - starting_peer = pg_iter; - least_connections = - GNUNET_CONTAINER_multihashmap_size (pg-> - peers - [pg_iter].connect_peers_working_set); - } - } - } - - if (GNUNET_CONTAINER_multihashmap_size (pg->peers[starting_peer].connect_peers) == 0) /* Ensure there is at least one peer left to connect! */ - { - dfs_count = 0; - continue; - } - - /* Choose a random peer from the chosen peers set of connections to add */ - dfs_ctx.chosen = - GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, - GNUNET_CONTAINER_multihashmap_size (pg->peers - [starting_peer].connect_peers)); - dfs_ctx.first_uid = starting_peer; - dfs_ctx.first = &pg->peers[starting_peer]; - dfs_ctx.pg = pg; - dfs_ctx.current = 0; - - GNUNET_CONTAINER_multihashmap_iterate (pg-> - peers[starting_peer].connect_peers, - &dfs_connect_iterator, &dfs_ctx); - /* Remove the second from the first, since we will be continuing the search and may encounter the first peer again! */ - hash_from_uid (dfs_ctx.second_uid, &second_hash); - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (pg->peers - [starting_peer].connect_peers, - &second_hash, - pg-> - peers - [dfs_ctx.second_uid].daemon)); - starting_peer = dfs_ctx.second_uid; - } - - for (pg_iter = 0; pg_iter < pg->total; pg_iter++) - { - /* Remove the "old" connections */ - GNUNET_CONTAINER_multihashmap_destroy (pg->peers[pg_iter].connect_peers); - /* And replace with the working set */ - pg->peers[pg_iter].connect_peers = - pg->peers[pg_iter].connect_peers_working_set; - } -#endif -} - -/** - * Internal callback for topology information for a particular peer. - */ -static void -internal_topology_callback (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_ATS_Information *atsi, - unsigned int atsi_count) -{ - struct CoreContext *core_ctx = cls; - struct TopologyIterateContext *iter_ctx = core_ctx->iter_context; - - if (peer == NULL) /* Either finished, or something went wrong */ - { - iter_ctx->completed++; - iter_ctx->connected--; - /* One core context allocated per iteration, must free! */ - GNUNET_free (core_ctx); - } - else - { - iter_ctx->topology_cb (iter_ctx->cls, &core_ctx->daemon->id, peer, NULL); - } - - if (iter_ctx->completed == iter_ctx->total) - { - iter_ctx->topology_cb (iter_ctx->cls, NULL, NULL, NULL); - /* Once all are done, free the iteration context */ - GNUNET_free (iter_ctx); - } -} - -/** - * Check running topology iteration tasks, if below max start a new one, otherwise - * schedule for some time in the future. - */ -static void -schedule_get_topology (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct CoreContext *core_context = cls; - struct TopologyIterateContext *topology_context = - (struct TopologyIterateContext *) core_context->iter_context; - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) - return; - - if (topology_context->connected > - topology_context->pg->max_outstanding_connections) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Delaying connect, we have too many outstanding connections!\n"); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 100), - &schedule_get_topology, core_context); - } - else - { - topology_context->connected++; - - if (GNUNET_OK != - GNUNET_CORE_iterate_peers (core_context->daemon->cfg, - &internal_topology_callback, core_context)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Topology iteration failed.\n"); - internal_topology_callback (core_context, NULL, NULL, 0); - } - } -} - -/** - * Iterate over all (running) peers in the peer group, retrieve - * all connections that each currently has. - */ -void -GNUNET_TESTING_get_topology (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_NotifyTopology cb, void *cls) -{ - struct TopologyIterateContext *topology_context; - struct CoreContext *core_ctx; - unsigned int i; - unsigned int total_count; - - /* Allocate a single topology iteration context */ - topology_context = GNUNET_malloc (sizeof (struct TopologyIterateContext)); - topology_context->topology_cb = cb; - topology_context->cls = cls; - topology_context->pg = pg; - total_count = 0; - for (i = 0; i < pg->total; i++) - { - if (pg->peers[i].daemon->running == GNUNET_YES) - { - /* Allocate one core context per core we need to connect to */ - core_ctx = GNUNET_malloc (sizeof (struct CoreContext)); - core_ctx->daemon = pg->peers[i].daemon; - /* Set back pointer to topology iteration context */ - core_ctx->iter_context = topology_context; - GNUNET_SCHEDULER_add_now (&schedule_get_topology, core_ctx); - total_count++; - } - } - if (total_count == 0) - { - cb (cls, NULL, NULL, "Cannot iterate over topology, no running peers!"); - GNUNET_free (topology_context); - } - else - topology_context->total = total_count; - return; -} - -/** - * Callback function to process statistic values. - * This handler is here only really to insert a peer - * identity (or daemon) so the statistics can be uniquely - * tied to a single running peer. - * - * @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 -internal_stats_callback (void *cls, const char *subsystem, const char *name, - uint64_t value, int is_persistent) -{ - struct StatsCoreContext *core_context = cls; - struct StatsIterateContext *stats_context = - (struct StatsIterateContext *) core_context->iter_context; - - return stats_context->proc (stats_context->cls, &core_context->daemon->id, - subsystem, name, value, is_persistent); -} - - -/** - * We don't need the statistics handle anymore, destroy it. - * - * @param cls Closure (the statistics handle to destroy) - * @param tc Task Context - */ -static void -internal_destroy_statistics (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_STATISTICS_Handle *h = cls; - - GNUNET_STATISTICS_destroy (h, GNUNET_NO); -} - - -/** - * Internal continuation call for statistics iteration. - * - * @param cls closure, the CoreContext for this iteration - * @param success whether or not the statistics iterations - * was canceled or not (we don't care) - */ -static void -internal_stats_cont (void *cls, int success) -{ - struct StatsCoreContext *core_context = cls; - struct StatsIterateContext *stats_context = - (struct StatsIterateContext *) core_context->iter_context; - - stats_context->connected--; - stats_context->completed++; - - if (stats_context->completed == stats_context->total) - { - stats_context->cont (stats_context->cls, GNUNET_YES); - GNUNET_free (stats_context); - } - - if (core_context->stats_handle != NULL) - /* Cannot destroy handle inside the continuation */ - GNUNET_SCHEDULER_add_now (&internal_destroy_statistics, - core_context->stats_handle); - - GNUNET_free (core_context); -} - -/** - * Check running topology iteration tasks, if below max start a new one, otherwise - * schedule for some time in the future. - */ -static void -schedule_get_statistics (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct StatsCoreContext *core_context = cls; - struct StatsIterateContext *stats_context = - (struct StatsIterateContext *) core_context->iter_context; - - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) - return; - - if (stats_context->connected > stats_context->pg->max_outstanding_connections) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Delaying connect, we have too many outstanding connections!\n"); - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 100), - &schedule_get_statistics, core_context); - } - else - { - stats_context->connected++; - core_context->stats_handle = - GNUNET_STATISTICS_create ("testing", core_context->daemon->cfg); - if (core_context->stats_handle == NULL) - { - internal_stats_cont (core_context, GNUNET_NO); - return; - } - - core_context->stats_get_handle = - GNUNET_STATISTICS_get (core_context->stats_handle, NULL, NULL, - GNUNET_TIME_UNIT_FOREVER_REL, - &internal_stats_cont, &internal_stats_callback, - core_context); - if (core_context->stats_get_handle == NULL) - internal_stats_cont (core_context, GNUNET_NO); - - } -} - -struct DuplicateStats -{ - /** - * Next item in the list - */ - struct DuplicateStats *next; - - /** - * Nasty string, concatenation of relevant information. - */ - char *unique_string; -}; - -/** - * Check whether the combination of port/host/unix domain socket - * already exists in the list of peers being checked for statistics. - * - * @param pg the peergroup in question - * @param specific_peer the peer we're concerned with - * @param stats_list the list to return to the caller - * - * @return GNUNET_YES if the statistics instance has been seen already, - * GNUNET_NO if not (and we may have added it to the list) - */ -static int -stats_check_existing (struct GNUNET_TESTING_PeerGroup *pg, - struct PeerData *specific_peer, - struct DuplicateStats **stats_list) -{ - struct DuplicateStats *pos; - char *unix_domain_socket; - unsigned long long port; - char *to_match; - - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_yesno (pg->cfg, "testing", - "single_statistics_per_host")) - return GNUNET_NO; /* Each peer has its own statistics instance, do nothing! */ - - pos = *stats_list; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (specific_peer->cfg, "statistics", - "unixpath", &unix_domain_socket)) - return GNUNET_NO; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (specific_peer->cfg, "statistics", - "port", &port)) - { - GNUNET_free (unix_domain_socket); - return GNUNET_NO; - } - - if (specific_peer->daemon->hostname != NULL) - GNUNET_asprintf (&to_match, "%s%s%llu", specific_peer->daemon->hostname, - unix_domain_socket, port); - else - GNUNET_asprintf (&to_match, "%s%llu", unix_domain_socket, port); - - while (pos != NULL) - { - if (0 == strcmp (to_match, pos->unique_string)) - { - GNUNET_free (unix_domain_socket); - GNUNET_free (to_match); - return GNUNET_YES; - } - pos = pos->next; - } - pos = GNUNET_malloc (sizeof (struct DuplicateStats)); - pos->unique_string = to_match; - pos->next = *stats_list; - *stats_list = pos; - GNUNET_free (unix_domain_socket); - return GNUNET_NO; -} - -/** - * Iterate over all (running) peers in the peer group, retrieve - * all statistics from each. - * - * @param pg the peergroup to iterate statistics of - * @param cont continuation to call once all stats have been retrieved - * @param proc processing function for each statistic from each peer - * @param cls closure to pass to proc - * - */ -void -GNUNET_TESTING_get_statistics (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_STATISTICS_Callback cont, - GNUNET_TESTING_STATISTICS_Iterator proc, - void *cls) -{ - struct StatsIterateContext *stats_context; - struct StatsCoreContext *core_ctx; - unsigned int i; - unsigned int total_count; - struct DuplicateStats *stats_list; - struct DuplicateStats *pos; - - stats_list = NULL; - - /* Allocate a single stats iteration context */ - stats_context = GNUNET_malloc (sizeof (struct StatsIterateContext)); - stats_context->cont = cont; - stats_context->proc = proc; - stats_context->cls = cls; - stats_context->pg = pg; - total_count = 0; - - for (i = 0; i < pg->total; i++) - { - if ((pg->peers[i].daemon->running == GNUNET_YES) && - (GNUNET_NO == stats_check_existing (pg, &pg->peers[i], &stats_list))) - { - /* Allocate one core context per core we need to connect to */ - core_ctx = GNUNET_malloc (sizeof (struct StatsCoreContext)); - core_ctx->daemon = pg->peers[i].daemon; - /* Set back pointer to topology iteration context */ - core_ctx->iter_context = stats_context; - GNUNET_SCHEDULER_add_now (&schedule_get_statistics, core_ctx); - total_count++; - } - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Retrieving stats from %u total instances.\n", total_count); - if (0 != total_count) - stats_context->total = total_count; - else - GNUNET_free (stats_context); - if (stats_list != NULL) - { - pos = stats_list; - while (pos != NULL) - { - GNUNET_free (pos->unique_string); - stats_list = pos->next; - GNUNET_free (pos); - pos = stats_list->next; - } - } - return; -} - -/** - * Stop the connection process temporarily. - * - * @param pg the peer group to stop connecting - */ -void -GNUNET_TESTING_stop_connections (struct GNUNET_TESTING_PeerGroup *pg) -{ - pg->stop_connects = GNUNET_YES; -} - -/** - * Resume the connection process temporarily. - * - * @param pg the peer group to resume connecting - */ -void -GNUNET_TESTING_resume_connections (struct GNUNET_TESTING_PeerGroup *pg) -{ - pg->stop_connects = GNUNET_NO; -} - -/** - * There are many ways to connect peers that are supported by this function. - * To connect peers in the same topology that was created via the - * GNUNET_TESTING_create_topology, the topology variable must be set to - * GNUNET_TESTING_TOPOLOGY_NONE. If the topology variable is specified, - * a new instance of that topology will be generated and attempted to be - * connected. This could result in some connections being impossible, - * because some topologies are non-deterministic. - * - * @param pg the peer group struct representing the running peers - * @param topology which topology to connect the peers in - * @param options options for connecting the topology - * @param option_modifier modifier for options that take a parameter - * @param connect_timeout how long to wait before giving up on connecting - * two peers - * @param connect_attempts how many times to attempt to connect two peers - * over the connect_timeout duration - * @param notify_callback notification to be called once all connections completed - * @param notify_cls closure for notification callback - * - * @return the number of connections that will be attempted, GNUNET_SYSERR on error - */ -int -GNUNET_TESTING_connect_topology (struct GNUNET_TESTING_PeerGroup *pg, - enum GNUNET_TESTING_Topology topology, - enum GNUNET_TESTING_TopologyOption options, - double option_modifier, - struct GNUNET_TIME_Relative connect_timeout, - unsigned int connect_attempts, - GNUNET_TESTING_NotifyCompletion - notify_callback, void *notify_cls) -{ - switch (topology) - { - case GNUNET_TESTING_TOPOLOGY_CLIQUE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating clique CONNECT topology\n"); - create_clique (pg, &add_connections, CONNECT, GNUNET_NO); - break; - case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD_RING: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating small world (ring) CONNECT topology\n"); - create_small_world_ring (pg, &add_connections, CONNECT); - break; - case GNUNET_TESTING_TOPOLOGY_SMALL_WORLD: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating small world (2d-torus) CONNECT topology\n"); - create_small_world (pg, &add_connections, CONNECT); - break; - case GNUNET_TESTING_TOPOLOGY_RING: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating ring CONNECT topology\n"); - create_ring (pg, &add_connections, CONNECT); - break; - case GNUNET_TESTING_TOPOLOGY_2D_TORUS: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating 2d torus CONNECT topology\n"); - create_2d_torus (pg, &add_connections, CONNECT); - break; - case GNUNET_TESTING_TOPOLOGY_ERDOS_RENYI: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating Erdos-Renyi CONNECT topology\n"); - create_erdos_renyi (pg, &add_connections, CONNECT); - break; - case GNUNET_TESTING_TOPOLOGY_INTERNAT: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating InterNAT CONNECT topology\n"); - create_nated_internet (pg, &add_connections, CONNECT); - break; - case GNUNET_TESTING_TOPOLOGY_SCALE_FREE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating Scale Free CONNECT topology\n"); - create_scale_free (pg, &add_connections, CONNECT); - break; - case GNUNET_TESTING_TOPOLOGY_LINE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating straight line CONNECT topology\n"); - create_line (pg, &add_connections, CONNECT); - break; - case GNUNET_TESTING_TOPOLOGY_NONE: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating no CONNECT topology\n"); - copy_allowed_topology (pg); - break; - default: - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Unknown topology specification, can't connect peers!\n")); - return GNUNET_SYSERR; - } - - switch (options) - { - case GNUNET_TESTING_TOPOLOGY_OPTION_RANDOM: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connecting random subset (%'.2f percent) of possible peers\n", - 100 * option_modifier); - choose_random_connections (pg, option_modifier); - break; - case GNUNET_TESTING_TOPOLOGY_OPTION_MINIMUM: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connecting a minimum of %u peers each (if possible)\n", - (unsigned int) option_modifier); - choose_minimum (pg, (unsigned int) option_modifier); - break; - case GNUNET_TESTING_TOPOLOGY_OPTION_DFS: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Using DFS to connect a minimum of %u peers each (if possible)\n", - (unsigned int) option_modifier); -#if FIXME - perform_dfs (pg, (int) option_modifier); -#endif - break; - case GNUNET_TESTING_TOPOLOGY_OPTION_ADD_CLOSEST: - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Finding additional %u closest peers each (if possible)\n", - (unsigned int) option_modifier); -#if FIXME - add_closest (pg, (unsigned int) option_modifier, &add_connections, CONNECT); -#endif - break; - case GNUNET_TESTING_TOPOLOGY_OPTION_NONE: - break; - case GNUNET_TESTING_TOPOLOGY_OPTION_ALL: - break; - default: - break; - } - - return connect_topology (pg, connect_timeout, connect_attempts, - notify_callback, notify_cls); -} - -/** - * Lookup and return the number of SSH connections to a host. - * - * @param hostname the hostname to lookup in the list - * @param pg the peergroup that the host belongs to - * - * @return the number of current ssh connections to the host - */ -static unsigned int -count_outstanding_at_host (const char *hostname, - struct GNUNET_TESTING_PeerGroup *pg) -{ - struct OutstandingSSH *pos; - - pos = pg->ssh_head; - while ((pos != NULL) && (strcmp (pos->hostname, hostname) != 0)) - pos = pos->next; - GNUNET_assert (pos != NULL); - return pos->outstanding; -} - -/** - * Increment the number of SSH connections to a host by one. - * - * @param hostname the hostname to lookup in the list - * @param pg the peergroup that the host belongs to - * - */ -static void -increment_outstanding_at_host (const char *hostname, - struct GNUNET_TESTING_PeerGroup *pg) -{ - struct OutstandingSSH *pos; - - pos = pg->ssh_head; - while ((NULL != pos) && (strcmp (pos->hostname, hostname) != 0)) - pos = pos->next; - GNUNET_assert (NULL != pos); - pos->outstanding++; -} - -/** - * Decrement the number of SSH connections to a host by one. - * - * @param hostname the hostname to lookup in the list - * @param pg the peergroup that the host belongs to - * - */ -static void -decrement_outstanding_at_host (const char *hostname, - struct GNUNET_TESTING_PeerGroup *pg) -{ - struct OutstandingSSH *pos; - - pos = pg->ssh_head; - while ((pos != NULL) && (strcmp (pos->hostname, hostname) != 0)) - pos = pos->next; - GNUNET_assert (pos != NULL); - pos->outstanding--; -} - -/** - * Callback that is called whenever a hostkey is generated - * for a peer. Call the real callback and decrement the - * starting counter for the peergroup. - * - * @param cls closure - * @param id identifier for the daemon, NULL on error - * @param d handle for the daemon - * @param emsg error message (NULL on success) - */ -static void -internal_hostkey_callback (void *cls, const struct GNUNET_PeerIdentity *id, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - struct InternalStartContext *internal_context = cls; - - internal_context->peer->pg->starting--; - internal_context->peer->pg->started++; - if (internal_context->hostname != NULL) - decrement_outstanding_at_host (internal_context->hostname, - internal_context->peer->pg); - if (internal_context->hostkey_callback != NULL) - internal_context->hostkey_callback (internal_context->hostkey_cls, id, d, - emsg); - else if (internal_context->peer->pg->started == - internal_context->peer->pg->total) - { - internal_context->peer->pg->started = 0; /* Internal startup may use this counter! */ - GNUNET_TESTING_daemons_continue_startup (internal_context->peer->pg); - } -} - -/** - * Callback that is called whenever a peer has finished starting. - * Call the real callback and decrement the starting counter - * for the peergroup. - * - * @param cls closure - * @param id identifier for the daemon, NULL on error - * @param cfg config - * @param d handle for the daemon - * @param emsg error message (NULL on success) - */ -static void -internal_startup_callback (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - struct InternalStartContext *internal_context = cls; - - internal_context->peer->pg->starting--; - if (internal_context->hostname != NULL) - decrement_outstanding_at_host (internal_context->hostname, - internal_context->peer->pg); - if (internal_context->start_cb != NULL) - internal_context->start_cb (internal_context->start_cb_cls, id, cfg, d, - emsg); -} - - -/** - * Calls GNUNET_TESTING_daemon_continue_startup to set the daemon's state - * from HOSTKEY_CREATED to TOPOLOGY_SETUP. Makes sure not to saturate a host - * with requests delaying them when needed. - * - * @param cls closure: internal context of the daemon. - * @param tc TaskContext - */ -static void -internal_continue_startup (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct InternalStartContext *internal_context = cls; - - internal_context->peer->startup_task = GNUNET_SCHEDULER_NO_TASK; - - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) - { - return; - } - - if ((internal_context->peer->pg->starting < - internal_context->peer->pg->max_concurrent_ssh) || - ((internal_context->hostname != NULL) && - (count_outstanding_at_host - (internal_context->hostname, - internal_context->peer->pg) < - internal_context->peer->pg->max_concurrent_ssh))) - { - if (internal_context->hostname != NULL) - increment_outstanding_at_host (internal_context->hostname, - internal_context->peer->pg); - internal_context->peer->pg->starting++; - GNUNET_TESTING_daemon_continue_startup (internal_context->peer->daemon); - } - else - { - internal_context->peer->startup_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 100), - &internal_continue_startup, - internal_context); - } -} - -/** - * Callback for informing us about a successful - * or unsuccessful churn start call. - * - * @param cls a ChurnContext - * @param id the peer identity of the started peer - * @param cfg the handle to the configuration of the peer - * @param d handle to the daemon for the peer - * @param emsg NULL on success, non-NULL on failure - * - */ -void -churn_start_callback (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - struct ChurnRestartContext *startup_ctx = cls; - struct ChurnContext *churn_ctx = startup_ctx->churn_ctx; - - unsigned int total_left; - char *error_message; - - error_message = NULL; - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Churn stop callback failed with error `%s'\n", emsg); - churn_ctx->num_failed_start++; - } - else - { - churn_ctx->num_to_start--; - } - - total_left = - (churn_ctx->num_to_stop - churn_ctx->num_failed_stop) + - (churn_ctx->num_to_start - churn_ctx->num_failed_start); - - if (total_left == 0) - { - if ((churn_ctx->num_failed_stop > 0) || (churn_ctx->num_failed_start > 0)) - GNUNET_asprintf (&error_message, - "Churn didn't complete successfully, %u peers failed to start %u peers failed to be stopped!", - churn_ctx->num_failed_start, churn_ctx->num_failed_stop); - churn_ctx->cb (churn_ctx->cb_cls, error_message); - GNUNET_free_non_null (error_message); - GNUNET_free (churn_ctx); - GNUNET_free (startup_ctx); - } -} - -static void -schedule_churn_restart (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct PeerRestartContext *peer_restart_ctx = cls; - struct ChurnRestartContext *startup_ctx = peer_restart_ctx->churn_restart_ctx; - - if (startup_ctx->outstanding > startup_ctx->pg->max_concurrent_ssh) - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 100), - &schedule_churn_restart, peer_restart_ctx); - else - { - if (startup_ctx->churn_ctx->service != NULL) - GNUNET_TESTING_daemon_start_stopped_service (peer_restart_ctx->daemon, - startup_ctx-> - churn_ctx->service, - startup_ctx->timeout, - &churn_start_callback, - startup_ctx); - else - GNUNET_TESTING_daemon_start_stopped (peer_restart_ctx->daemon, - startup_ctx->timeout, - &churn_start_callback, startup_ctx); - GNUNET_free (peer_restart_ctx); - } -} - -/** - * Callback for informing us about a successful - * or unsuccessful churn start call. - * - * @param cls a struct ServiceStartContext *startup_ctx - * @param id the peer identity of the started peer - * @param cfg the handle to the configuration of the peer - * @param d handle to the daemon for the peer - * @param emsg NULL on success, non-NULL on failure - * - */ -void -service_start_callback (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - struct ServiceStartContext *startup_ctx = (struct ServiceStartContext *) cls; - - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Service start failed with error `%s'\n", emsg); - } - - startup_ctx->outstanding--; - startup_ctx->remaining--; - - if (startup_ctx->remaining == 0) - { - startup_ctx->cb (startup_ctx->cb_cls, NULL); - GNUNET_free (startup_ctx->service); - GNUNET_free (startup_ctx); - } -} - -static void -schedule_service_start (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct PeerServiceStartContext *peer_ctx = cls; - struct ServiceStartContext *startup_ctx = peer_ctx->start_ctx; - - if (startup_ctx->outstanding > startup_ctx->pg->max_concurrent_ssh) - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 100), - &schedule_service_start, peer_ctx); - else - { - - GNUNET_TESTING_daemon_start_service (peer_ctx->daemon, startup_ctx->service, - startup_ctx->timeout, - &service_start_callback, startup_ctx); - GNUNET_free (peer_ctx); - } -} - - -static void -internal_start (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct InternalStartContext *internal_context = cls; - - if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) - { - return; - } - - if ((internal_context->peer->pg->starting < - internal_context->peer->pg->max_concurrent_ssh) || - ((internal_context->hostname != NULL) && - (count_outstanding_at_host - (internal_context->hostname, - internal_context->peer->pg) < - internal_context->peer->pg->max_concurrent_ssh))) - { - if (internal_context->hostname != NULL) - increment_outstanding_at_host (internal_context->hostname, - internal_context->peer->pg); - internal_context->peer->pg->starting++; - internal_context->peer->daemon = - GNUNET_TESTING_daemon_start (internal_context->peer->cfg, - internal_context->timeout, GNUNET_NO, - internal_context->hostname, - internal_context->username, - internal_context->sshport, - internal_context->hostkey, - &internal_hostkey_callback, - internal_context, - &internal_startup_callback, - internal_context); - } - else - { - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 100), - &internal_start, internal_context); - } -} - -#if USE_START_HELPER - -struct PeerStartHelperContext -{ - struct GNUNET_TESTING_PeerGroup *pg; - - struct HostData *host; - - struct GNUNET_OS_Process *proc; -}; - -static void -check_peers_started (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct PeerStartHelperContext *helper = cls; - enum GNUNET_OS_ProcessStatusType type; - unsigned long code; - unsigned int i; - GNUNET_TESTING_NotifyDaemonRunning cb; - - if (GNUNET_NO == GNUNET_OS_process_status (helper->proc, &type, &code)) /* Still running, wait some more! */ - { - GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_EXEC_WAIT, - &check_peers_started, helper); - return; - } - - helper->pg->starting--; - if (helper->pg->starting == 0) /* All peers have finished starting! */ - { - /* Call the peer started callback for each peer, set proper FSM state (?) */ - for (i = 0; i < helper->pg->total; i++) - { - cb = helper->pg->peers[i].daemon->cb; - helper->pg->peers[i].daemon->cb = NULL; - helper->pg->peers[i].daemon->running = GNUNET_YES; - helper->pg->peers[i].daemon->phase = SP_START_DONE; - if (NULL != cb) - { - if ((type != GNUNET_OS_PROCESS_EXITED) || (code != 0)) - cb (helper->pg->peers[i].daemon->cb_cls, - &helper->pg->peers[i].daemon->id, - helper->pg->peers[i].daemon->cfg, helper->pg->peers[i].daemon, - "Failed to execute peerStartHelper.pl, or return code bad!"); - else - cb (helper->pg->peers[i].daemon->cb_cls, - &helper->pg->peers[i].daemon->id, - helper->pg->peers[i].daemon->cfg, helper->pg->peers[i].daemon, - NULL); - - } - - } - } - GNUNET_OS_process_destroy (helper->proc); -} - -static void -start_peer_helper (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct PeerStartHelperContext *helper = cls; - char *baseservicehome; - char *tempdir; - char *arg; - - /* ssh user@host peerStartHelper /path/to/basedirectory */ - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (helper->pg->cfg, - "PATHS", "SERVICEHOME", - &baseservicehome)); - GNUNET_asprintf (&tempdir, "%s/%s/", baseservicehome, helper->host->hostname); - if (NULL != helper->host->username) - GNUNET_asprintf (&arg, "%s@%s", helper->host->username, - helper->host->hostname); - else - GNUNET_asprintf (&arg, "%s", helper->host->hostname); - - /* FIXME: Doesn't support ssh_port option! */ - helper->proc = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", arg, - "peerStartHelper.pl", tempdir, NULL); - GNUNET_assert (helper->proc != NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting peers with cmd ssh %s %s %s\n", - arg, "peerStartHelper.pl", tempdir); - GNUNET_SCHEDULER_add_now (&check_peers_started, helper); - GNUNET_free (tempdir); - GNUNET_free (baseservicehome); - GNUNET_free (arg); -} -#endif - -/** - * Function which continues a peer group starting up - * after successfully generating hostkeys for each peer. - * - * @param pg the peer group to continue starting - * - */ -void -GNUNET_TESTING_daemons_continue_startup (struct GNUNET_TESTING_PeerGroup *pg) -{ - unsigned int i; - -#if USE_START_HELPER - if ((pg->num_hosts > 0) && (pg->hostkey_data != NULL)) - { - struct PeerStartHelperContext *helper; - - pg->starting = pg->num_hosts; - for (i = 0; i < pg->num_hosts; i++) - { - helper = GNUNET_malloc (sizeof (struct PeerStartHelperContext)); - helper->pg = pg; - helper->host = &pg->hosts[i]; - GNUNET_SCHEDULER_add_now (&start_peer_helper, helper); - } - } - else - { - pg->starting = 0; - for (i = 0; i < pg->total; i++) - { - pg->peers[i].startup_task = - GNUNET_SCHEDULER_add_now (&internal_continue_startup, - &pg->peers[i].internal_context); - } - } -#else - pg->starting = 0; - for (i = 0; i < pg->total; i++) - { - pg->peers[i].startup_task = - GNUNET_SCHEDULER_add_now (&internal_continue_startup, - &pg->peers[i].internal_context); - } -#endif -} - -#if USE_START_HELPER -static void -call_hostkey_callbacks (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_TESTING_PeerGroup *pg = cls; - unsigned int i; - - for (i = 0; i < pg->total; i++) - { - if (pg->peers[i].internal_context.hostkey_callback != NULL) - pg->peers[i].internal_context.hostkey_callback (pg->peers[i]. - internal_context.hostkey_cls, - &pg->peers[i].daemon->id, - pg->peers[i].daemon, - NULL); - } - - if (pg->peers[0].internal_context.hostkey_callback == NULL) - GNUNET_TESTING_daemons_continue_startup (pg); -} -#endif - -/** - * Start count gnunet instances with the same set of transports and - * applications. The port numbers (any option called "PORT") will be - * adjusted to ensure that no two peers running on the same system - * have the same port(s) in their respective configurations. - * - * @param cfg configuration template to use - * @param total number of daemons to start - * @param max_concurrent_connections for testing, how many peers can - * we connect to simultaneously - * @param max_concurrent_ssh when starting with ssh, how many ssh - * connections will we allow at once (based on remote hosts allowed!) - * @param timeout total time allowed for peers to start - * @param hostkey_callback function to call on each peers hostkey generation - * if NULL, peers will be started by this call, if non-null, - * GNUNET_TESTING_daemons_continue_startup must be called after - * successful hostkey generation - * @param hostkey_cls closure for hostkey callback - * @param cb function to call on each daemon that was started - * @param cb_cls closure for cb - * @param connect_callback function to call each time two hosts are connected - * @param connect_callback_cls closure for connect_callback - * @param hostnames linked list of host structs to use to start peers on - * (NULL to run on localhost only) - * - * @return NULL on error, otherwise handle to control peer group - */ -struct GNUNET_TESTING_PeerGroup * -GNUNET_TESTING_daemons_start (const struct GNUNET_CONFIGURATION_Handle *cfg, - unsigned int total, - unsigned int max_concurrent_connections, - unsigned int max_concurrent_ssh, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTING_NotifyHostkeyCreated - hostkey_callback, void *hostkey_cls, - GNUNET_TESTING_NotifyDaemonRunning cb, - void *cb_cls, - GNUNET_TESTING_NotifyConnection connect_callback, - void *connect_callback_cls, - const struct GNUNET_TESTING_Host *hostnames) -{ - struct GNUNET_TESTING_PeerGroup *pg; - const struct GNUNET_TESTING_Host *hostpos; - const char *hostname; - const char *username; - char *baseservicehome; - char *newservicehome; - char *tmpdir; - char *hostkeys_file; - char *arg; - char *ssh_port_str; - struct GNUNET_DISK_FileHandle *fd; - struct GNUNET_CONFIGURATION_Handle *pcfg; - unsigned int off; - struct OutstandingSSH *ssh_entry; - unsigned int hostcnt; - unsigned int i; - uint16_t minport; - uint16_t sshport; - uint32_t upnum; - uint32_t fdnum; - uint64_t fs; - uint64_t total_hostkeys; - struct GNUNET_OS_Process *proc; - - username = NULL; - if (0 == total) - { - GNUNET_break (0); - return NULL; - } - - upnum = 0; - fdnum = 0; - pg = GNUNET_malloc (sizeof (struct GNUNET_TESTING_PeerGroup)); - pg->cfg = cfg; - pg->notify_connection = connect_callback; - pg->notify_connection_cls = connect_callback_cls; - pg->total = total; - pg->max_timeout = GNUNET_TIME_relative_to_absolute (timeout); - pg->peers = GNUNET_malloc (total * sizeof (struct PeerData)); - pg->max_outstanding_connections = max_concurrent_connections; - pg->max_concurrent_ssh = max_concurrent_ssh; - if (NULL != hostnames) - { - off = 0; - hostpos = hostnames; - while (hostpos != NULL) - { - hostpos = hostpos->next; - off++; - } - pg->hosts = GNUNET_malloc (off * sizeof (struct HostData)); - off = 0; - - hostpos = hostnames; - while (hostpos != NULL) - { - pg->hosts[off].minport = LOW_PORT; - pg->hosts[off].hostname = GNUNET_strdup (hostpos->hostname); - if (hostpos->username != NULL) - pg->hosts[off].username = GNUNET_strdup (hostpos->username); - pg->hosts[off].sshport = hostpos->port; - hostpos = hostpos->next; - off++; - } - - if (off == 0) - { - pg->hosts = NULL; - } - hostcnt = off; - minport = 0; - pg->num_hosts = off; - } - else - { - hostcnt = 0; - minport = LOW_PORT; - } - - /* Create the servicehome directory for each remote peer */ - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", - "SERVICEHOME", - &baseservicehome)); - for (i = 0; i < pg->num_hosts; i++) - { - ssh_entry = GNUNET_malloc (sizeof (struct OutstandingSSH)); - ssh_entry->hostname = pg->hosts[i].hostname; /* Don't free! */ - GNUNET_CONTAINER_DLL_insert (pg->ssh_head, pg->ssh_tail, ssh_entry); - GNUNET_asprintf (&tmpdir, "%s/%s", baseservicehome, pg->hosts[i].hostname); - if (NULL != pg->hosts[i].username) - GNUNET_asprintf (&arg, "%s@%s", pg->hosts[i].username, - pg->hosts[i].hostname); - else - GNUNET_asprintf (&arg, "%s", pg->hosts[i].hostname); - if (pg->hosts[i].sshport != 0) - { - GNUNET_asprintf (&ssh_port_str, "%d", pg->hosts[i].sshport); - proc = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", "-P", ssh_port_str, - "-q", - arg, "mkdir -p", tmpdir, NULL); - } - else - proc = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "ssh", "ssh", arg, "mkdir -p", - tmpdir, NULL); - GNUNET_assert (proc != NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating remote dir with command ssh %s %s %s\n", arg, - " mkdir -p ", tmpdir); - GNUNET_free (tmpdir); - GNUNET_free (arg); - GNUNET_OS_process_wait (proc); - GNUNET_OS_process_destroy (proc); - } - GNUNET_free (baseservicehome); - baseservicehome = NULL; - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "TESTING", "HOSTKEYSFILE", - &hostkeys_file)) - { - if (GNUNET_YES != GNUNET_DISK_file_test (hostkeys_file)) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Could not read hostkeys file!\n")); - else - { - /* Check hostkey file size, read entire thing into memory */ - fd = GNUNET_DISK_file_open (hostkeys_file, GNUNET_DISK_OPEN_READ, - GNUNET_DISK_PERM_NONE); - if (NULL == fd) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "open", - hostkeys_file); - GNUNET_free (hostkeys_file); - for (i = 0; i < pg->num_hosts; i++) - { - GNUNET_free (pg->hosts[i].hostname); - GNUNET_free_non_null (pg->hosts[i].username); - } - GNUNET_free (pg->peers); - GNUNET_free (pg->hosts); - GNUNET_free (pg); - return NULL; - } - - if (GNUNET_OK != GNUNET_DISK_file_size (hostkeys_file, &fs, GNUNET_YES, GNUNET_YES)) - fs = 0; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Found file size %llu for hostkeys\n", fs); - if (0 != (fs % HOSTKEYFILESIZE)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "File size %llu seems incorrect for hostkeys...\n", fs); - } - else - { - total_hostkeys = fs / HOSTKEYFILESIZE; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Will read %llu hostkeys from file\n", total_hostkeys); - pg->hostkey_data = GNUNET_malloc_large (fs); - GNUNET_assert (fs == GNUNET_DISK_file_read (fd, pg->hostkey_data, fs)); - } - GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); - } - GNUNET_free (hostkeys_file); - } - - for (off = 0; off < total; off++) - { - if (hostcnt > 0) - { - hostname = pg->hosts[off % hostcnt].hostname; - username = pg->hosts[off % hostcnt].username; - sshport = pg->hosts[off % hostcnt].sshport; - pcfg = - GNUNET_TESTING_create_cfg (cfg, off, &pg->hosts[off % hostcnt].minport, &upnum, - hostname, &fdnum); - } - else - { - hostname = NULL; - username = NULL; - sshport = 0; - pcfg = GNUNET_TESTING_create_cfg (cfg, off, &minport, &upnum, hostname, &fdnum); - } - - if (NULL == pcfg) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Could not create configuration for peer number %u on `%s'!\n"), - off, hostname == NULL ? "localhost" : hostname); - continue; - } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (pcfg, "PATHS", "SERVICEHOME", - &baseservicehome)) - { - if (hostname != NULL) - GNUNET_asprintf (&newservicehome, "%s/%s/%d/", baseservicehome, - hostname, off); - else - GNUNET_asprintf (&newservicehome, "%s/%d/", baseservicehome, off); - GNUNET_free (baseservicehome); - baseservicehome = NULL; - } - else - { - tmpdir = getenv ("TMPDIR"); - tmpdir = tmpdir ? tmpdir : "/tmp"; - if (hostname != NULL) - GNUNET_asprintf (&newservicehome, "%s/%s/%s/%d/", tmpdir, hostname, - "gnunet-testing-test-test", off); - else - GNUNET_asprintf (&newservicehome, "%s/%s/%d/", tmpdir, - "gnunet-testing-test-test", off); - } - GNUNET_CONFIGURATION_set_value_string (pcfg, "PATHS", "SERVICEHOME", - newservicehome); - GNUNET_free (newservicehome); - pg->peers[off].cfg = pcfg; - pg->peers[off].pg = pg; - pg->peers[off].internal_context.peer = &pg->peers[off]; - pg->peers[off].internal_context.timeout = timeout; - pg->peers[off].internal_context.hostname = hostname; - pg->peers[off].internal_context.username = username; - pg->peers[off].internal_context.sshport = sshport; - if (pg->hostkey_data != NULL) - pg->peers[off].internal_context.hostkey = - &pg->hostkey_data[off * HOSTKEYFILESIZE]; - pg->peers[off].internal_context.hostkey_callback = hostkey_callback; - pg->peers[off].internal_context.hostkey_cls = hostkey_cls; - pg->peers[off].internal_context.start_cb = cb; - pg->peers[off].internal_context.start_cb_cls = cb_cls; -#if !USE_START_HELPER - GNUNET_SCHEDULER_add_now (&internal_start, - &pg->peers[off].internal_context); -#else - if ((pg->hostkey_data != NULL) && (hostcnt > 0)) - { - pg->peers[off].daemon = - GNUNET_TESTING_daemon_start (pcfg, timeout, GNUNET_YES, hostname, - username, sshport, - pg->peers[off].internal_context.hostkey, - &internal_hostkey_callback, - &pg->peers[off].internal_context, - &internal_startup_callback, - &pg->peers[off].internal_context); - /** - * At this point, given that we had a hostkeyfile, - * we can call the hostkey callback! - * But first, we should copy (rsync) all of the configs - * and hostkeys to the remote peers. Then let topology - * creation happen, then call the peer start helper processes, - * then set pg->whatever_phase for each peer and let them - * enter the fsm to get the HELLO's for peers and start connecting. - */ - } - else - { - GNUNET_SCHEDULER_add_now (&internal_start, - &pg->peers[off].internal_context); - } - -#endif - } - -#if USE_START_HELPER /* Now the peergroup has been set up, hostkeys and configs written to files. */ - if ((pg->hostkey_data != NULL) && (hostcnt > 0)) - { - for (off = 0; off < hostcnt; off++) - { - - if (hostcnt > 0) - { - hostname = pg->hosts[off % hostcnt].hostname; - username = pg->hosts[off % hostcnt].username; - sshport = pg->hosts[off % hostcnt].sshport; - } - else - { - hostname = NULL; - username = NULL; - sshport = 0; - } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", "SERVICEHOME", - &baseservicehome)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "baseservice home is %s\n", - baseservicehome); - if (hostname != NULL) - GNUNET_asprintf (&newservicehome, "%s/%s/", baseservicehome, - hostname); - else - GNUNET_asprintf (&newservicehome, "%s/", baseservicehome); - GNUNET_free (baseservicehome); - baseservicehome = NULL; - } - else - { - tmpdir = getenv ("TMPDIR"); - tmpdir = tmpdir ? tmpdir : "/tmp"; - if (hostname != NULL) - GNUNET_asprintf (&newservicehome, "%s/%s/%s/", tmpdir, hostname, - "gnunet-testing-test-test"); - else - GNUNET_asprintf (&newservicehome, "%s/%s/", tmpdir, - "gnunet-testing-test-test", off); - } - - if (NULL != username) - GNUNET_asprintf (&arg, "%s@%s:%s", username, pg->hosts[off].hostname, - newservicehome); - else - GNUNET_asprintf (&arg, "%s:%s", pg->hosts[off].hostname, - newservicehome); - - /* FIXME: Doesn't support ssh_port option! */ - proc = - GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, "rsync", "rsync", "-r", - newservicehome, arg, NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "copying directory with command rsync -r %s %s\n", - newservicehome, arg); - GNUNET_free (newservicehome); - GNUNET_free (arg); - if (NULL == proc) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _ - ("Could not start `%s' process to copy configuration directory.\n"), - "scp"); - GNUNET_assert (0); - } - GNUNET_OS_process_wait (proc); - GNUNET_OS_process_destroy (proc); - } - /* Now all the configuration files and hostkeys are copied to the remote host. Call the hostkey callback for each peer! */ - GNUNET_SCHEDULER_add_now (&call_hostkey_callbacks, pg); - } -#endif - return pg; -} - -/* - * Get a daemon by number, so callers don't have to do nasty - * offsetting operation. - */ -struct GNUNET_TESTING_Daemon * -GNUNET_TESTING_daemon_get (struct GNUNET_TESTING_PeerGroup *pg, - unsigned int position) -{ - if (position < pg->total) - return pg->peers[position].daemon; - return NULL; -} - -/* - * Get a daemon by peer identity, so callers can - * retrieve the daemon without knowing it's offset. - * - * @param pg the peer group to retrieve the daemon from - * @param peer_id the peer identity of the daemon to retrieve - * - * @return the daemon on success, or NULL if no such peer identity is found - */ -struct GNUNET_TESTING_Daemon * -GNUNET_TESTING_daemon_get_by_id (struct GNUNET_TESTING_PeerGroup *pg, - const struct GNUNET_PeerIdentity *peer_id) -{ - unsigned int i; - - for (i = 0; i < pg->total; i++) - { - if (0 == - memcmp (&pg->peers[i].daemon->id, peer_id, - sizeof (struct GNUNET_PeerIdentity))) - return pg->peers[i].daemon; - } - return NULL; -} - -/** - * Prototype of a function that will be called when a - * particular operation was completed the testing library. - * - * @param cls closure (a struct RestartContext) - * @param id id of the peer that was restarted - * @param cfg handle to the configuration of the peer - * @param d handle to the daemon that was restarted - * @param emsg NULL on success - */ -static void -restart_callback (void *cls, const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - struct RestartContext *restart_context = cls; - - if (emsg == NULL) - { - restart_context->peers_restarted++; - } - else - { - restart_context->peers_restart_failed++; - } - - if (restart_context->peers_restarted == restart_context->peer_group->total) - { - restart_context->callback (restart_context->callback_cls, NULL); - GNUNET_free (restart_context); - } - else if (restart_context->peers_restart_failed + - restart_context->peers_restarted == - restart_context->peer_group->total) - { - restart_context->callback (restart_context->callback_cls, - "Failed to restart peers!"); - GNUNET_free (restart_context); - } - -} - -/** - * Callback for informing us about a successful - * or unsuccessful churn stop call. - * - * @param cls a ChurnContext - * @param emsg NULL on success, non-NULL on failure - * - */ -static void -churn_stop_callback (void *cls, const char *emsg) -{ - struct ShutdownContext *shutdown_ctx = cls; - struct ChurnContext *churn_ctx = shutdown_ctx->cb_cls; - unsigned int total_left; - char *error_message; - - error_message = NULL; - shutdown_ctx->outstanding--; - - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Churn stop callback failed with error `%s'\n", emsg); - churn_ctx->num_failed_stop++; - } - else - { - churn_ctx->num_to_stop--; - } - - total_left = - (churn_ctx->num_to_stop - churn_ctx->num_failed_stop) + - (churn_ctx->num_to_start - churn_ctx->num_failed_start); - - if (total_left == 0) - { - if ((churn_ctx->num_failed_stop > 0) || (churn_ctx->num_failed_start > 0)) - { - GNUNET_asprintf (&error_message, - "Churn didn't complete successfully, %u peers failed to start %u peers failed to be stopped!", - churn_ctx->num_failed_start, churn_ctx->num_failed_stop); - } - churn_ctx->cb (churn_ctx->cb_cls, error_message); - GNUNET_free_non_null (error_message); - GNUNET_free (churn_ctx); - GNUNET_free (shutdown_ctx); - } -} - -/** - * Count the number of running peers. - * - * @param pg handle for the peer group - * - * @return the number of currently running peers in the peer group - */ -unsigned int -GNUNET_TESTING_daemons_running (struct GNUNET_TESTING_PeerGroup *pg) -{ - unsigned int i; - unsigned int running = 0; - - for (i = 0; i < pg->total; i++) - { - if (pg->peers[i].daemon->running == GNUNET_YES) - { - GNUNET_assert (running != -1); - running++; - } - } - return running; -} - -/** - * Task to rate limit the number of outstanding peer shutdown - * requests. This is necessary for making sure we don't do - * too many ssh connections at once, but is generally nicer - * to any system as well (graduated task starts, as opposed - * to calling gnunet-arm N times all at once). - */ -static void -schedule_churn_shutdown_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct PeerShutdownContext *peer_shutdown_ctx = cls; - struct ShutdownContext *shutdown_ctx; - struct ChurnContext *churn_ctx; - - GNUNET_assert (peer_shutdown_ctx != NULL); - shutdown_ctx = peer_shutdown_ctx->shutdown_ctx; - GNUNET_assert (shutdown_ctx != NULL); - churn_ctx = (struct ChurnContext *) shutdown_ctx->cb_cls; - if (shutdown_ctx->outstanding > churn_ctx->pg->max_concurrent_ssh) - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 100), - &schedule_churn_shutdown_task, - peer_shutdown_ctx); - else - { - shutdown_ctx->outstanding++; - if (churn_ctx->service != NULL) - GNUNET_TESTING_daemon_stop_service (peer_shutdown_ctx->daemon, - churn_ctx->service, - shutdown_ctx->timeout, - shutdown_ctx->cb, shutdown_ctx); - else - GNUNET_TESTING_daemon_stop (peer_shutdown_ctx->daemon, - shutdown_ctx->timeout, shutdown_ctx->cb, - shutdown_ctx, GNUNET_NO, GNUNET_YES); - GNUNET_free (peer_shutdown_ctx); - } -} - - -/** - * Simulate churn by stopping some peers (and possibly - * re-starting others if churn is called multiple times). This - * function can only be used to create leave-join churn (peers "never" - * leave for good). First "voff" random peers that are currently - * online will be taken offline; then "von" random peers that are then - * offline will be put back online. No notifications will be - * generated for any of these operations except for the callback upon - * completion. - * - * @param pg handle for the peer group - * @param service the service to churn off/on, NULL to churn peer - * @param voff number of peers that should go offline - * @param von number of peers that should come back online; - * must be zero on first call (since "testbed_start" - * always starts all of the peers) - * @param timeout how long to wait for operations to finish before - * giving up - * @param cb function to call at the end - * @param cb_cls closure for cb - */ -void -GNUNET_TESTING_daemons_churn (struct GNUNET_TESTING_PeerGroup *pg, - char *service, unsigned int voff, - unsigned int von, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTING_NotifyCompletion cb, void *cb_cls) -{ - struct ChurnContext *churn_ctx; - struct ShutdownContext *shutdown_ctx; - struct PeerShutdownContext *peer_shutdown_ctx; - struct PeerRestartContext *peer_restart_ctx; - struct ChurnRestartContext *churn_startup_ctx; - - unsigned int running; - unsigned int stopped; - unsigned int total_running; - unsigned int total_stopped; - unsigned int i; - unsigned int *running_arr; - unsigned int *stopped_arr; - unsigned int *running_permute; - unsigned int *stopped_permute; - char *pos; - - shutdown_ctx = NULL; - peer_shutdown_ctx = NULL; - peer_restart_ctx = NULL; - churn_startup_ctx = NULL; - - running = 0; - stopped = 0; - - if ((von == 0) && (voff == 0)) /* No peers at all? */ - { - cb (cb_cls, NULL); - return; - } - - for (i = 0; i < pg->total; i++) - { - if (service == NULL) - { - if (pg->peers[i].daemon->running == GNUNET_YES) - { - GNUNET_assert (running != -1); - running++; - } - else - { - GNUNET_assert (stopped != -1); - stopped++; - } - } - else - { - /* FIXME: make churned services a list! */ - pos = pg->peers[i].daemon->churned_services; - /* FIXME: while (pos != NULL) */ - if (pos != NULL) - { -#if FIXME - if (0 == strcasecmp (pos, service)) - { - - break; - } -#endif - GNUNET_assert (stopped != -1); - stopped++; - /* FIXME: pos = pos->next; */ - } - if (pos == NULL) - { - GNUNET_assert (running != -1); - running++; - } - } - } - - if (voff > running) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Trying to stop more peers (%d) than are currently running (%d)!\n", - voff, running); - cb (cb_cls, "Trying to stop more peers than are currently running!"); - return; - } - - if (von > stopped) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Trying to start more peers (%d) than are currently stopped (%d)!\n", - von, stopped); - cb (cb_cls, "Trying to start more peers than are currently stopped!"); - return; - } - - churn_ctx = GNUNET_malloc (sizeof (struct ChurnContext)); - - if (service != NULL) - churn_ctx->service = GNUNET_strdup (service); - running_arr = NULL; - if (running > 0) - running_arr = GNUNET_malloc (running * sizeof (unsigned int)); - - stopped_arr = NULL; - if (stopped > 0) - stopped_arr = GNUNET_malloc (stopped * sizeof (unsigned int)); - - running_permute = NULL; - stopped_permute = NULL; - - if (running > 0) - running_permute = - GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, running); - if (stopped > 0) - stopped_permute = - GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK, stopped); - - total_running = running; - total_stopped = stopped; - running = 0; - stopped = 0; - - churn_ctx->num_to_start = von; - churn_ctx->num_to_stop = voff; - churn_ctx->cb = cb; - churn_ctx->cb_cls = cb_cls; - churn_ctx->pg = pg; - - for (i = 0; i < pg->total; i++) - { - if (service == NULL) - { - if (pg->peers[i].daemon->running == GNUNET_YES) - { - GNUNET_assert ((running_arr != NULL) && (total_running > running)); - running_arr[running] = i; - running++; - } - else - { - GNUNET_assert ((stopped_arr != NULL) && (total_stopped > stopped)); - stopped_arr[stopped] = i; - stopped++; - } - } - else - { - /* FIXME: make churned services a list! */ - pos = pg->peers[i].daemon->churned_services; - /* FIXME: while (pos != NULL) */ - if (pos != NULL) - { - GNUNET_assert ((stopped_arr != NULL) && (total_stopped > stopped)); - stopped_arr[stopped] = i; - stopped++; - /* FIXME: pos = pos->next; */ - } - if (pos == NULL) - { - GNUNET_assert ((running_arr != NULL) && (total_running > running)); - running_arr[running] = i; - running++; - } - } - } - - GNUNET_assert (running >= voff); - if (voff > 0) - { - shutdown_ctx = GNUNET_malloc (sizeof (struct ShutdownContext)); - shutdown_ctx->cb = &churn_stop_callback; - shutdown_ctx->cb_cls = churn_ctx; - shutdown_ctx->total_peers = voff; - shutdown_ctx->timeout = timeout; - } - - for (i = 0; i < voff; i++) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping peer %d!\n", - running_arr[running_permute[i]]); - GNUNET_assert (running_arr != NULL); - peer_shutdown_ctx = GNUNET_malloc (sizeof (struct PeerShutdownContext)); - peer_shutdown_ctx->daemon = - pg->peers[running_arr[running_permute[i]]].daemon; - peer_shutdown_ctx->shutdown_ctx = shutdown_ctx; - GNUNET_SCHEDULER_add_now (&schedule_churn_shutdown_task, peer_shutdown_ctx); - } - - GNUNET_assert (stopped >= von); - if (von > 0) - { - churn_startup_ctx = GNUNET_malloc (sizeof (struct ChurnRestartContext)); - churn_startup_ctx->churn_ctx = churn_ctx; - churn_startup_ctx->timeout = timeout; - churn_startup_ctx->pg = pg; - } - for (i = 0; i < von; i++) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting up peer %d!\n", - stopped_arr[stopped_permute[i]]); - GNUNET_assert (stopped_arr != NULL); - peer_restart_ctx = GNUNET_malloc (sizeof (struct PeerRestartContext)); - peer_restart_ctx->churn_restart_ctx = churn_startup_ctx; - peer_restart_ctx->daemon = - pg->peers[stopped_arr[stopped_permute[i]]].daemon; - GNUNET_SCHEDULER_add_now (&schedule_churn_restart, peer_restart_ctx); - } - - GNUNET_free_non_null (running_arr); - GNUNET_free_non_null (stopped_arr); - GNUNET_free_non_null (running_permute); - GNUNET_free_non_null (stopped_permute); -} - -/* - * Start a given service for each of the peers in the peer group. - * - * @param pg handle for the peer group - * @param service the service to start - * @param timeout how long to wait for operations to finish before - * giving up - * @param cb function to call once finished - * @param cb_cls closure for cb - * - */ -void -GNUNET_TESTING_daemons_start_service (struct GNUNET_TESTING_PeerGroup *pg, - char *service, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTING_NotifyCompletion cb, - void *cb_cls) -{ - struct ServiceStartContext *start_ctx; - struct PeerServiceStartContext *peer_start_ctx; - unsigned int i; - - GNUNET_assert (service != NULL); - - start_ctx = GNUNET_malloc (sizeof (struct ServiceStartContext)); - start_ctx->pg = pg; - start_ctx->remaining = pg->total; - start_ctx->cb = cb; - start_ctx->cb_cls = cb_cls; - start_ctx->service = GNUNET_strdup (service); - start_ctx->timeout = timeout; - - for (i = 0; i < pg->total; i++) - { - peer_start_ctx = GNUNET_malloc (sizeof (struct PeerServiceStartContext)); - peer_start_ctx->start_ctx = start_ctx; - peer_start_ctx->daemon = pg->peers[i].daemon; - GNUNET_SCHEDULER_add_now (&schedule_service_start, peer_start_ctx); - } -} - -/** - * Restart all peers in the given group. - * - * @param pg the handle to the peer group - * @param callback function to call on completion (or failure) - * @param callback_cls closure for the callback function - */ -void -GNUNET_TESTING_daemons_restart (struct GNUNET_TESTING_PeerGroup *pg, - GNUNET_TESTING_NotifyCompletion callback, - void *callback_cls) -{ - struct RestartContext *restart_context; - unsigned int off; - - if (pg->total > 0) - { - restart_context = GNUNET_malloc (sizeof (struct RestartContext)); - restart_context->peer_group = pg; - restart_context->peers_restarted = 0; - restart_context->callback = callback; - restart_context->callback_cls = callback_cls; - - for (off = 0; off < pg->total; off++) - { - GNUNET_TESTING_daemon_restart (pg->peers[off].daemon, &restart_callback, - restart_context); - } - } -} - - -/** - * Start or stop an individual peer from the given group. - * - * @param pg handle to the peer group - * @param offset which peer to start or stop - * @param desired_status GNUNET_YES to have it running, GNUNET_NO to stop it - * @param timeout how long to wait for shutdown - * @param cb function to call at the end - * @param cb_cls closure for cb - */ -void -GNUNET_TESTING_daemons_vary (struct GNUNET_TESTING_PeerGroup *pg, - unsigned int offset, int desired_status, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTING_NotifyCompletion cb, void *cb_cls) -{ - struct ShutdownContext *shutdown_ctx; - struct ChurnRestartContext *startup_ctx; - struct ChurnContext *churn_ctx; - - if (GNUNET_NO == desired_status) - { - if (NULL != pg->peers[offset].daemon) - { - shutdown_ctx = GNUNET_malloc (sizeof (struct ShutdownContext)); - churn_ctx = GNUNET_malloc (sizeof (struct ChurnContext)); - churn_ctx->num_to_start = 0; - churn_ctx->num_to_stop = 1; - churn_ctx->cb = cb; - churn_ctx->cb_cls = cb_cls; - shutdown_ctx->cb_cls = churn_ctx; - GNUNET_TESTING_daemon_stop (pg->peers[offset].daemon, timeout, - &churn_stop_callback, shutdown_ctx, GNUNET_NO, - GNUNET_YES); - } - } - else if (GNUNET_YES == desired_status) - { - if (NULL == pg->peers[offset].daemon) - { - startup_ctx = GNUNET_malloc (sizeof (struct ChurnRestartContext)); - churn_ctx = GNUNET_malloc (sizeof (struct ChurnContext)); - churn_ctx->num_to_start = 1; - churn_ctx->num_to_stop = 0; - churn_ctx->cb = cb; - churn_ctx->cb_cls = cb_cls; - startup_ctx->churn_ctx = churn_ctx; - GNUNET_TESTING_daemon_start_stopped (pg->peers[offset].daemon, timeout, - &churn_start_callback, startup_ctx); - } - } - else - GNUNET_break (0); -} - - -/** - * Callback for shutting down peers in a peer group. - * - * @param cls closure (struct ShutdownContext) - * @param emsg NULL on success - */ -static void -internal_shutdown_callback (void *cls, const char *emsg) -{ - struct PeerShutdownContext *peer_shutdown_ctx = cls; - struct ShutdownContext *shutdown_ctx = peer_shutdown_ctx->shutdown_ctx; - unsigned int off; - int i; - struct OutstandingSSH *ssh_pos; - - shutdown_ctx->outstanding--; - if (peer_shutdown_ctx->daemon->hostname != NULL) - decrement_outstanding_at_host (peer_shutdown_ctx->daemon->hostname, - shutdown_ctx->pg); - - if (emsg == NULL) - { - shutdown_ctx->peers_down++; - } - else - { - GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "internal_shutdown_callback", - "Failed to stop a peer: %s\n", emsg); - shutdown_ctx->peers_failed++; - } - - if ((shutdown_ctx->cb != NULL) && - (shutdown_ctx->peers_down + shutdown_ctx->peers_failed == - shutdown_ctx->total_peers)) - { - if (shutdown_ctx->peers_failed > 0) - shutdown_ctx->cb (shutdown_ctx->cb_cls, - "Not all peers successfully shut down!"); - else - shutdown_ctx->cb (shutdown_ctx->cb_cls, NULL); - - for (i = 0; i < shutdown_ctx->pg->total; i++) - { - if (shutdown_ctx->pg->peers[i].startup_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (shutdown_ctx->pg->peers[i].startup_task); - } - GNUNET_free (shutdown_ctx->pg->peers); - GNUNET_free_non_null (shutdown_ctx->pg->hostkey_data); - for (off = 0; off < shutdown_ctx->pg->num_hosts; off++) - { - GNUNET_free (shutdown_ctx->pg->hosts[off].hostname); - GNUNET_free_non_null (shutdown_ctx->pg->hosts[off].username); - } - GNUNET_free_non_null (shutdown_ctx->pg->hosts); - while (NULL != (ssh_pos = shutdown_ctx->pg->ssh_head)) - { - GNUNET_CONTAINER_DLL_remove (shutdown_ctx->pg->ssh_head, - shutdown_ctx->pg->ssh_tail, ssh_pos); - GNUNET_free (ssh_pos); - } - GNUNET_free (shutdown_ctx->pg); - GNUNET_free (shutdown_ctx); - } - GNUNET_free (peer_shutdown_ctx); -} - - -/** - * Task to rate limit the number of outstanding peer shutdown - * requests. This is necessary for making sure we don't do - * too many ssh connections at once, but is generally nicer - * to any system as well (graduated task starts, as opposed - * to calling gnunet-arm N times all at once). - */ -static void -schedule_shutdown_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct PeerShutdownContext *peer_shutdown_ctx = cls; - struct ShutdownContext *shutdown_ctx; - struct GNUNET_TESTING_Daemon *d; - - GNUNET_assert (peer_shutdown_ctx != NULL); - d = peer_shutdown_ctx->daemon; - shutdown_ctx = peer_shutdown_ctx->shutdown_ctx; - GNUNET_assert (shutdown_ctx != NULL); - - if ((shutdown_ctx->outstanding < shutdown_ctx->pg->max_concurrent_ssh) || - ((d->hostname != NULL) && - (count_outstanding_at_host - (d->hostname, - shutdown_ctx->pg) < shutdown_ctx->pg->max_concurrent_ssh))) - { - if (d->hostname != NULL) - increment_outstanding_at_host (d->hostname, - shutdown_ctx->pg); - shutdown_ctx->outstanding++; - GNUNET_TESTING_daemon_stop (d, - shutdown_ctx->timeout, - &internal_shutdown_callback, peer_shutdown_ctx, - shutdown_ctx->delete_files, GNUNET_NO); - } - else - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, 100), - &schedule_shutdown_task, peer_shutdown_ctx); - -} - -/** - * Read a testing hosts file based on a configuration. - * Returns a DLL of hosts (caller must free!) on success - * or NULL on failure. - * - * @param cfg a configuration with a testing section - * - * @return DLL of hosts on success, NULL on failure - */ -struct GNUNET_TESTING_Host * -GNUNET_TESTING_hosts_load (const struct GNUNET_CONFIGURATION_Handle *cfg) -{ - struct GNUNET_TESTING_Host *hosts; - struct GNUNET_TESTING_Host *temphost; - char *data; - char *buf; - char *hostfile; - struct stat frstat; - int count; - int ret; - - /* Check for a hostfile containing user@host:port triples */ - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "hostfile", - &hostfile)) - return NULL; - - hosts = NULL; - temphost = NULL; - data = NULL; - if (hostfile != NULL) - { - if (GNUNET_OK != GNUNET_DISK_file_test (hostfile)) - GNUNET_DISK_fn_write (hostfile, NULL, 0, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - if ((0 != STAT (hostfile, &frstat)) || (frstat.st_size == 0)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not open file specified for host list, ending test!"); - GNUNET_free (hostfile); - return NULL; - } - - data = GNUNET_malloc_large (frstat.st_size); - GNUNET_assert (data != NULL); - if (frstat.st_size != GNUNET_DISK_fn_read (hostfile, data, frstat.st_size)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not read file %s specified for host list, ending test!", - hostfile); - GNUNET_free (hostfile); - GNUNET_free (data); - return NULL; - } - - GNUNET_free_non_null (hostfile); - - buf = data; - count = 0; - while (count < frstat.st_size - 1) - { - count++; - if (((data[count] == '\n')) && (buf != &data[count])) - { - data[count] = '\0'; - temphost = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Host)); - ret = - SSCANF (buf, "%a[a-zA-Z0-9_]@%a[a-zA-Z0-9.]:%hd", - &temphost->username, &temphost->hostname, &temphost->port); - if (3 == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Successfully read host %s, port %d and user %s from file\n", - temphost->hostname, temphost->port, temphost->username); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Error reading line `%s' in hostfile\n", buf); - GNUNET_free (temphost); - buf = &data[count + 1]; - continue; - } - temphost->next = hosts; - hosts = temphost; - buf = &data[count + 1]; - } - else if ((data[count] == '\n') || (data[count] == '\0')) - buf = &data[count + 1]; - } - } - GNUNET_free_non_null (data); - - return hosts; -} - -/** - * Shutdown all peers started in the given group. - * - * @param pg handle to the peer group - * @param timeout how long to wait for shutdown - * @param cb callback to notify upon success or failure - * @param cb_cls closure for cb - */ -void -GNUNET_TESTING_daemons_stop (struct GNUNET_TESTING_PeerGroup *pg, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTING_NotifyCompletion cb, void *cb_cls) -{ - unsigned int off; - struct ShutdownContext *shutdown_ctx; - struct PeerShutdownContext *peer_shutdown_ctx; - -#if OLD - struct PeerConnection *conn_iter; - struct PeerConnection *temp_conn; -#endif - struct ConnectContext *cc; - - GNUNET_assert (pg->total > 0); - while (NULL != (cc = pg->cc_head)) - { - GNUNET_CONTAINER_DLL_remove (pg->cc_head, pg->cc_tail, cc); - if (GNUNET_SCHEDULER_NO_TASK != cc->task) - GNUNET_SCHEDULER_cancel (cc->task); - if (NULL != cc->cc) - GNUNET_TESTING_daemons_connect_cancel (cc->cc); - GNUNET_free (cc); - } - - shutdown_ctx = GNUNET_malloc (sizeof (struct ShutdownContext)); - shutdown_ctx->delete_files = - GNUNET_CONFIGURATION_get_value_yesno (pg->cfg, "TESTING", "DELETE_FILES"); - shutdown_ctx->cb = cb; - shutdown_ctx->cb_cls = cb_cls; - shutdown_ctx->total_peers = pg->total; - shutdown_ctx->timeout = timeout; - shutdown_ctx->pg = pg; - - for (off = 0; off < pg->total; off++) - { - GNUNET_assert (NULL != pg->peers[off].daemon); - peer_shutdown_ctx = GNUNET_malloc (sizeof (struct PeerShutdownContext)); - peer_shutdown_ctx->daemon = pg->peers[off].daemon; - peer_shutdown_ctx->shutdown_ctx = shutdown_ctx; - GNUNET_SCHEDULER_add_now (&schedule_shutdown_task, peer_shutdown_ctx); - - if (NULL != pg->peers[off].cfg) - { - GNUNET_CONFIGURATION_destroy (pg->peers[off].cfg); - pg->peers[off].cfg = NULL; - } -#if OLD -// FIXME Do DLL remove for all pg->peers[off].LIST - conn_iter = pg->peers[off].allowed_peers_head; - while (conn_iter != NULL) - { - temp_conn = conn_iter->next; - GNUNET_free (conn_iter); - conn_iter = temp_conn; - } - pg->peers[off].allowed_peers_head = NULL; - - conn_iter = pg->peers[off].connect_peers_head; - while (conn_iter != NULL) - { - temp_conn = conn_iter->next; - GNUNET_free (conn_iter); - conn_iter = temp_conn; - } - pg->peers[off].connect_peers_head = NULL; - - conn_iter = pg->peers[off].blacklisted_peers_head; - while (conn_iter != NULL) - { - temp_conn = conn_iter->next; - GNUNET_free (conn_iter); - conn_iter = temp_conn; - } - pg->peers[off].blacklisted_peers_head = NULL; - - conn_iter = pg->peers[off].connect_peers_working_set_head; - while (conn_iter != NULL) - { - temp_conn = conn_iter->next; - GNUNET_free (conn_iter); - conn_iter = temp_conn; - } - pg->peers[off].connect_peers_working_set_head = NULL; -#else - if (pg->peers[off].allowed_peers != NULL) - GNUNET_CONTAINER_multihashmap_destroy (pg->peers[off].allowed_peers); - if (pg->peers[off].connect_peers != NULL) - GNUNET_CONTAINER_multihashmap_destroy (pg->peers[off].connect_peers); - if (pg->peers[off].blacklisted_peers != NULL) - GNUNET_CONTAINER_multihashmap_destroy (pg->peers[off].blacklisted_peers); -#endif - } -} - -/* end of testing_group.c */ diff --git a/src/testing/testing_new.c b/src/testing/testing_new.c deleted file mode 100644 index c45b89e..0000000 --- a/src/testing/testing_new.c +++ /dev/null @@ -1,1000 +0,0 @@ -/* - This file is part of GNUnet - (C) 2008, 2009, 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 testing/testing_new.c - * @brief convenience API for writing testcases for GNUnet - * Many testcases need to start and stop a peer/service - * and this library is supposed to make that easier - * for TESTCASES. Normal programs should always - * use functions from gnunet_{util,arm}_lib.h. This API is - * ONLY for writing testcases (or internal use of the testbed). - * @author Christian Grothoff - * - */ -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_testing_lib-new.h" - -#define LOG(kind,...) \ - GNUNET_log_from (kind, "gnunettestingnew", __VA_ARGS__) - - -/** - * Size of a hostkey when written to a file - */ -#define HOSTKEYFILESIZE 914 - - -/** - * Handle for a system on which GNUnet peers are executed; - * a system is used for reserving unique paths and ports. - */ -struct GNUNET_TESTING_System -{ - /** - * Prefix (i.e. "/tmp/gnunet-testing/") we prepend to each - * SERVICEHOME. - */ - char *tmppath; - - /** - * The hostname of the controller - */ - char *controller; - - /** - * Hostkeys data, contains "HOSTKEYFILESIZE * total_hostkeys" bytes. - */ - char *hostkeys_data; - - /** - * Bitmap where each TCP port that has already been reserved for - * some GNUnet peer is recorded. Note that we additionally need to - * test if a port is already in use by non-GNUnet components before - * assigning it to a peer/service. If we detect that a port is - * already in use, we also mark it in this bitmap. So all the bits - * that are zero merely indicate ports that MIGHT be available for - * peers. - */ - uint32_t reserved_tcp_ports[65536 / 32]; - - /** - * Bitmap where each UDP port that has already been reserved for - * some GNUnet peer is recorded. Note that we additionally need to - * test if a port is already in use by non-GNUnet components before - * assigning it to a peer/service. If we detect that a port is - * already in use, we also mark it in this bitmap. So all the bits - * that are zero merely indicate ports that MIGHT be available for - * peers. - */ - uint32_t reserved_udp_ports[65536 / 32]; - - /** - * Counter we use to make service home paths unique on this system; - * the full path consists of the tmppath and this number. Each - * UNIXPATH for a peer is also modified to include the respective - * path counter to ensure uniqueness. This field is incremented - * by one for each configured peer. Even if peers are destroyed, - * we never re-use path counters. - */ - uint32_t path_counter; - - /** - * The number of hostkeys - */ - uint32_t total_hostkeys; -}; - - -/** - * Handle for a GNUnet peer controlled by testing. - */ -struct GNUNET_TESTING_Peer -{ - - /** - * Path to the configuration file for this peer. - */ - char *cfgfile; - - /** - * Binary to be executed during 'GNUNET_TESTING_peer_start'. - * Typically 'gnunet-service-arm' (but can be set to a - * specific service by 'GNUNET_TESTING_service_run' if - * necessary). - */ - char *main_binary; - - /** - * Handle to the running binary of the service, NULL if the - * peer/service is currently not running. - */ - struct GNUNET_OS_Process *main_process; -}; - - -/** - * Lowest port used for GNUnet testing. Should be high enough to not - * conflict with other applications running on the hosts but be low - * enough to not conflict with client-ports (typically starting around - * 32k). - */ -#define LOW_PORT 12000 - - -/** - * Highest port used for GNUnet testing. Should be low enough to not - * conflict with the port range for "local" ports (client apps; see - * /proc/sys/net/ipv4/ip_local_port_range on Linux for example). - */ -#define HIGH_PORT 56000 - - -/** - * Create a system handle. There must only be one system - * handle per operating system. - * - * @param tmppath prefix path to use for all service homes - * @param controller hostname of the controlling host, - * service configurations are modified to allow - * control connections from this host; can be NULL - * @return handle to this system, NULL on error - */ -struct GNUNET_TESTING_System * -GNUNET_TESTING_system_create (const char *tmppath, - const char *controller) -{ - struct GNUNET_TESTING_System *system; - - if (NULL == tmppath) - { - LOG (GNUNET_ERROR_TYPE_ERROR, _("tmppath cannot be NULL\n")); - return NULL; - } - system = GNUNET_malloc (sizeof (struct GNUNET_TESTING_System)); - system->tmppath = GNUNET_strdup (tmppath); - if (NULL != controller) - system->controller = GNUNET_strdup (controller); - return system; -} - - -/** - * Free system resources. - * - * @param system system to be freed - * @param remove_paths should the 'tmppath' and all subdirectories - * be removed (clean up on shutdown)? - */ -void -GNUNET_TESTING_system_destroy (struct GNUNET_TESTING_System *system, - int remove_paths) -{ - if (NULL != system->hostkeys_data) - { - GNUNET_break (0); /* Use GNUNET_TESTING_hostkeys_unload() */ - GNUNET_TESTING_hostkeys_unload (system); - } - if (GNUNET_YES == remove_paths) - GNUNET_DISK_directory_remove (system->tmppath); - GNUNET_free (system->tmppath); - GNUNET_free_non_null (system->controller); - GNUNET_free (system); -} - - -/** - * Reserve a TCP or UDP port for a peer. - * - * @param system system to use for reservation tracking - * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP - * @return 0 if no free port was available - */ -uint16_t -GNUNET_TESTING_reserve_port (struct GNUNET_TESTING_System *system, - int is_tcp) -{ - struct GNUNET_NETWORK_Handle *socket; - struct addrinfo hint; - struct addrinfo *ret; - uint32_t *port_buckets; - char *open_port_str; - int bind_status; - uint32_t xor_image; - uint16_t index; - uint16_t open_port; - uint16_t pos; - - /* - FIXME: Instead of using getaddrinfo we should try to determine the port - status by the following heurestics. - - On systems which support both IPv4 and IPv6, only ports open on both - address families are considered open. - On system with either IPv4 or IPv6. A port is considered open if it's - open in the respective address family - */ - hint.ai_family = AF_UNSPEC; /* IPv4 and IPv6 */ - hint.ai_socktype = (GNUNET_YES == is_tcp)? SOCK_STREAM : SOCK_DGRAM; - hint.ai_protocol = 0; - hint.ai_addrlen = 0; - hint.ai_addr = NULL; - hint.ai_canonname = NULL; - hint.ai_next = NULL; - hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV; /* Wild card address */ - port_buckets = (GNUNET_YES == is_tcp) ? - system->reserved_tcp_ports : system->reserved_udp_ports; - for (index = (LOW_PORT / 32) + 1; index < (HIGH_PORT / 32); index++) - { - xor_image = (UINT32_MAX ^ port_buckets[index]); - if (0 == xor_image) /* Ports in the bucket are full */ - continue; - pos = 0; - while (pos < 32) - { - if (0 == ((xor_image >> pos) & 1U)) - { - pos++; - continue; - } - open_port = (index * 32) + pos; - GNUNET_asprintf (&open_port_str, "%u", (unsigned int) open_port); - ret = NULL; - GNUNET_assert (0 == getaddrinfo (NULL, open_port_str, &hint, &ret)); - GNUNET_free (open_port_str); - socket = GNUNET_NETWORK_socket_create (ret->ai_family, - (GNUNET_YES == is_tcp) ? - SOCK_STREAM : SOCK_DGRAM, - 0); - GNUNET_assert (NULL != socket); - bind_status = GNUNET_NETWORK_socket_bind (socket, - ret->ai_addr, - ret->ai_addrlen); - freeaddrinfo (ret); - GNUNET_NETWORK_socket_close (socket); - socket = NULL; - port_buckets[index] |= (1U << pos); /* Set the port bit */ - if (GNUNET_OK == bind_status) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Found a free port %u\n", (unsigned int) open_port); - return open_port; - } - pos++; - } - } - return 0; -} - - -/** - * Release reservation of a TCP or UDP port for a peer - * (used during GNUNET_TESTING_peer_destroy). - * - * @param system system to use for reservation tracking - * @param is_tcp GNUNET_YES for TCP ports, GNUNET_NO for UDP - * @param port reserved port to release - */ -void -GNUNET_TESTING_release_port (struct GNUNET_TESTING_System *system, - int is_tcp, - uint16_t port) -{ - uint32_t *port_buckets; - uint16_t bucket; - uint16_t pos; - - port_buckets = (GNUNET_YES == is_tcp) ? - system->reserved_tcp_ports : system->reserved_udp_ports; - bucket = port / 32; - pos = port % 32; - LOG (GNUNET_ERROR_TYPE_DEBUG, "Releasing port %u\n", port); - if (0 == (port_buckets[bucket] & (1U << pos))) - { - GNUNET_break(0); /* Port was not reserved by us using reserve_port() */ - return; - } - port_buckets[bucket] &= ~(1U << pos); -} - - -/** - * Reserve a SERVICEHOME path for a peer. - * - * @param system system to use for reservation tracking - * @return NULL on error, otherwise fresh unique path to use - * as the servicehome for the peer; must be freed by the caller - */ -// static -char * -reserve_path (struct GNUNET_TESTING_System *system) -{ - char *reserved_path; - - GNUNET_asprintf (&reserved_path, - "%s/%u", system->tmppath, system->path_counter++); - return reserved_path; -} - - -/** - * Testing includes a number of pre-created hostkeys for faster peer - * startup. This function loads such keys into memory from a file. - * - * @param system the testing system handle - * @param filename the path of the hostkeys file - * @return GNUNET_OK on success; GNUNET_SYSERR on error - */ -int -GNUNET_TESTING_hostkeys_load (struct GNUNET_TESTING_System *system, - const char *filename) -{ - struct GNUNET_DISK_FileHandle *fd; - uint64_t fs; - - if (GNUNET_YES != GNUNET_DISK_file_test (filename)) - { - LOG (GNUNET_ERROR_TYPE_ERROR, - _("Hostkeys file not found: %s\n"), filename); - return GNUNET_SYSERR; - } - /* Check hostkey file size, read entire thing into memory */ - fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, - GNUNET_DISK_PERM_NONE); - if (NULL == fd) - { - LOG (GNUNET_ERROR_TYPE_ERROR, - _("Could not open hostkeys file: %s\n"), filename); - return GNUNET_SYSERR; - } - if (GNUNET_OK != - GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) - fs = 0; - if (0 == fs) - { - GNUNET_DISK_file_close (fd); - return GNUNET_SYSERR; /* File is empty */ - } - if (0 != (fs % HOSTKEYFILESIZE)) - { - GNUNET_DISK_file_close (fd); - LOG (GNUNET_ERROR_TYPE_ERROR, - _("Incorrect hostkey file format: %s\n"), filename); - return GNUNET_SYSERR; - } - GNUNET_break (NULL == system->hostkeys_data); - system->total_hostkeys = fs / HOSTKEYFILESIZE; - system->hostkeys_data = GNUNET_malloc_large (fs); /* free in hostkeys_unload */ - GNUNET_assert (fs == GNUNET_DISK_file_read (fd, system->hostkeys_data, fs)); - GNUNET_DISK_file_close (fd); - return GNUNET_OK; -} - - -/** - * Function to remove the loaded hostkeys - * - * @param system the testing system handle - */ -void -GNUNET_TESTING_hostkeys_unload (struct GNUNET_TESTING_System *system) -{ - GNUNET_break (NULL != system->hostkeys_data); - GNUNET_free_non_null (system->hostkeys_data); - system->hostkeys_data = NULL; - system->total_hostkeys = 0; -} - - -/** - * Testing includes a number of pre-created hostkeys for - * faster peer startup. This function can be used to - * access the n-th key of those pre-created hostkeys; note - * that these keys are ONLY useful for testing and not - * secure as the private keys are part of the public - * GNUnet source code. - * - * This is primarily a helper function used internally - * by 'GNUNET_TESTING_peer_configure'. - * - * @param system the testing system handle - * @param key_number desired pre-created hostkey to obtain - * @param id set to the peer's identity (hash of the public - * key; if NULL, GNUNET_SYSERR is returned immediately - * @return GNUNET_SYSERR on error (not enough keys) - */ -int -GNUNET_TESTING_hostkey_get (const struct GNUNET_TESTING_System *system, - uint32_t key_number, - struct GNUNET_PeerIdentity *id) -{ - struct GNUNET_CRYPTO_RsaPrivateKey *private_key; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded public_key; - - if ((NULL == id) || (NULL == system->hostkeys_data)) - return GNUNET_SYSERR; - if (key_number >= system->total_hostkeys) - { - LOG (GNUNET_ERROR_TYPE_ERROR, - _("Key number %u does not exist\n"), key_number); - return GNUNET_SYSERR; - } - private_key = GNUNET_CRYPTO_rsa_decode_key (system->hostkeys_data + - (key_number * HOSTKEYFILESIZE), - HOSTKEYFILESIZE); - if (NULL == private_key) - { - LOG (GNUNET_ERROR_TYPE_ERROR, - _("Error while decoding key %u\n"), key_number); - return GNUNET_SYSERR; - } - GNUNET_CRYPTO_rsa_key_get_public (private_key, &public_key); - GNUNET_CRYPTO_hash (&public_key, - sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &(id->hashPubKey)); - GNUNET_CRYPTO_rsa_key_free (private_key); - return GNUNET_OK; -} - - -/** - * Structure for holding data to build new configurations from a configuration - * template - */ -struct UpdateContext -{ - /** - * The system for which we are building configurations - */ - struct GNUNET_TESTING_System *system; - - /** - * The configuration we are building - */ - struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * The customized service home path for this peer - */ - char *service_home; - - /** - * build status - to signal error while building a configuration - */ - int status; -}; - - -/** - * Function to iterate over options. Copies - * the options to the target configuration, - * updating PORT values as needed. - * - * @param cls the UpdateContext - * @param section name of the section - * @param option name of the option - * @param value value of the option - */ -static void -update_config (void *cls, const char *section, const char *option, - const char *value) -{ - struct UpdateContext *uc = cls; - unsigned int ival; - char cval[12]; - char uval[128]; - char *single_variable; - char *per_host_variable; - unsigned long long num_per_host; - uint16_t new_port; - - if (GNUNET_OK != uc->status) - return; - if (! ((0 == strcmp (option, "PORT")) - || (0 == strcmp (option, "UNIXPATH")) - || (0 == strcmp (option, "HOSTNAME")))) - return; - GNUNET_asprintf (&single_variable, "single_%s_per_host", section); - GNUNET_asprintf (&per_host_variable, "num_%s_per_host", section); - if ((0 == strcmp (option, "PORT")) && (1 == SSCANF (value, "%u", &ival))) - { - if ((ival != 0) && - (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, "testing", - single_variable))) - { - /* FIXME: What about UDP? */ - new_port = GNUNET_TESTING_reserve_port (uc->system, GNUNET_YES); - if (0 == new_port) - { - uc->status = GNUNET_SYSERR; - return; - } - GNUNET_snprintf (cval, sizeof (cval), "%u", new_port); - value = cval; - } - else if ((ival != 0) && - (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, "testing", - single_variable)) && - GNUNET_CONFIGURATION_get_value_number (uc->cfg, "testing", - per_host_variable, - &num_per_host)) - { - /* GNUNET_snprintf (cval, sizeof (cval), "%u", */ - /* ival + ctx->fdnum % num_per_host); */ - /* value = cval; */ - GNUNET_break (0); /* FIXME */ - } - } - if (0 == strcmp (option, "UNIXPATH")) - { - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_yesno (uc->cfg, "testing", - single_variable)) - { - GNUNET_snprintf (uval, sizeof (uval), "%s/%s.sock", - uc->service_home, section); - value = uval; - } - else if ((GNUNET_YES == - GNUNET_CONFIGURATION_get_value_number (uc->cfg, "testing", - per_host_variable, - &num_per_host)) && - (num_per_host > 0)) - { - GNUNET_break(0); /* FIXME */ - } - } - if ((0 == strcmp (option, "HOSTNAME")) && (NULL != uc->system->controller)) - { - value = uc->system->controller; - } - GNUNET_free (single_variable); - GNUNET_free (per_host_variable); - GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, option, value); -} - - -/** - * Section iterator to set ACCEPT_FROM in all sections - * - * @param cls the UpdateContext - * @param section name of the section - */ -static void -update_config_sections (void *cls, - const char *section) -{ - struct UpdateContext *uc = cls; - char *orig_allowed_hosts; - char *allowed_hosts; - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (uc->cfg, section, "ACCEPT_FROM", - &orig_allowed_hosts)) - { - orig_allowed_hosts = GNUNET_strdup ("127.0.0.1;"); - } - if (NULL == uc->system->controller) - allowed_hosts = GNUNET_strdup (orig_allowed_hosts); - else - GNUNET_asprintf (&allowed_hosts, "%s %s;", orig_allowed_hosts, - uc->system->controller); - GNUNET_free (orig_allowed_hosts); - GNUNET_CONFIGURATION_set_value_string (uc->cfg, section, "ACCEPT_FROM", - allowed_hosts); - GNUNET_free (allowed_hosts); -} - - -/** - * Create a new configuration using the given configuration - * as a template; ports and paths will be modified to select - * available ports on the local system. If we run - * out of "*port" numbers, return SYSERR. - * - * This is primarily a helper function used internally - * by 'GNUNET_TESTING_peer_configure'. - * - * @param system system to use to coordinate resource usage - * @param cfg template configuration to update - * @return GNUNET_OK on success, GNUNET_SYSERR on error - the configuration will - * be incomplete and should not be used there upon - */ -int -GNUNET_TESTING_configuration_create (struct GNUNET_TESTING_System *system, - struct GNUNET_CONFIGURATION_Handle *cfg) -{ - struct UpdateContext uc; - - uc.system = system; - uc.cfg = cfg; - uc.status = GNUNET_OK; - GNUNET_asprintf (&uc.service_home, "%s/%u", system->tmppath, - system->path_counter++); - GNUNET_CONFIGURATION_set_value_string (cfg, "PATHS", "SERVICEHOME", - uc.service_home); - /* make PORTs and UNIXPATHs unique */ - GNUNET_CONFIGURATION_iterate (cfg, &update_config, &uc); - /* allow connections to services from system controller host */ - GNUNET_CONFIGURATION_iterate_sections (cfg, &update_config_sections, &uc); - /* enable loopback-based connections between peers */ - GNUNET_CONFIGURATION_set_value_string (cfg, - "nat", - "USE_LOCALADDR", "YES"); - GNUNET_free (uc.service_home); - return uc.status; -} - - -/** - * Configure a GNUnet peer. GNUnet must be installed on the local - * system and available in the PATH. - * - * @param system system to use to coordinate resource usage - * @param cfg configuration to use; will be UPDATED (to reflect needed - * changes in port numbers and paths) - * @param key_number number of the hostkey to use for the peer - * @param id identifier for the daemon, will be set, can be NULL - * @param emsg set to error message (set to NULL on success), can be NULL - * @return handle to the peer, NULL on error - */ -struct GNUNET_TESTING_Peer * -GNUNET_TESTING_peer_configure (struct GNUNET_TESTING_System *system, - struct GNUNET_CONFIGURATION_Handle *cfg, - uint32_t key_number, - struct GNUNET_PeerIdentity *id, - char **emsg) -{ - struct GNUNET_TESTING_Peer *peer; - struct GNUNET_DISK_FileHandle *fd; - char *service_home; - char hostkey_filename[128]; - char *config_filename; - char *emsg_; - - if (NULL != emsg) - *emsg = NULL; - if (GNUNET_OK != GNUNET_TESTING_configuration_create (system, cfg)) - { - GNUNET_asprintf (&emsg_, - _("Failed to create configuration for peer (not enough free ports?)\n")); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", *emsg_); - if (NULL != emsg) - *emsg = emsg_; - else - GNUNET_free (emsg_); - return NULL; - } - if (key_number >= system->total_hostkeys) - { - GNUNET_asprintf (&emsg_, - _("You attempted to create a testbed with more than %u hosts. Please precompute more hostkeys first.\n"), - (unsigned int) system->total_hostkeys); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", *emsg_); - if (NULL != emsg) - *emsg = emsg_; - else - GNUNET_free (emsg_); - return NULL; - } - if ((NULL != id) && - (GNUNET_SYSERR == GNUNET_TESTING_hostkey_get (system, key_number, id))) - { - GNUNET_asprintf (&emsg_, - _("Failed to initialize hostkey for peer %u\n"), - (unsigned int) key_number); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", *emsg_); - if (NULL != emsg) - *emsg = emsg_; - else - GNUNET_free (emsg_); - return NULL; - } - GNUNET_assert (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (cfg, "PATHS", - "SERVICEHOME", - &service_home)); - GNUNET_snprintf (hostkey_filename, sizeof (hostkey_filename), "%s/.hostkey", - service_home); - fd = GNUNET_DISK_file_open (hostkey_filename, - GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, - GNUNET_DISK_PERM_USER_READ - | GNUNET_DISK_PERM_USER_WRITE); - if (NULL == fd) - { - GNUNET_break (0); - return NULL; - } - if (HOSTKEYFILESIZE != - GNUNET_DISK_file_write (fd, system->hostkeys_data - + (key_number * HOSTKEYFILESIZE), - HOSTKEYFILESIZE)) - { - GNUNET_asprintf (&emsg_, - _("Failed to write hostkey file for peer %u: %s\n"), - (unsigned int) key_number, - STRERROR (errno)); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", *emsg_); - if (NULL != emsg) - *emsg = emsg_; - else - GNUNET_free (emsg_); - GNUNET_DISK_file_close (fd); - return NULL; - } - GNUNET_DISK_file_close (fd); - GNUNET_asprintf (&config_filename, "%s/config", service_home); - GNUNET_free (service_home); - if (GNUNET_OK != GNUNET_CONFIGURATION_write (cfg, config_filename)) - { - GNUNET_asprintf (&emsg_, - _("Failed to write configuration file `%s' for peer %u: %s\n"), - config_filename, - (unsigned int) key_number, - STRERROR (errno)); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s", *emsg_); - if (NULL != emsg) - *emsg = emsg_; - else - GNUNET_free (emsg_); - return NULL; - } - peer = GNUNET_malloc (sizeof (struct GNUNET_TESTING_Peer)); - peer->cfgfile = config_filename; /* Free in peer_destroy */ - peer->main_binary = GNUNET_strdup ("gnunet-service-arm"); - return peer; -} - - -/** - * Start the peer. - * - * @param peer peer to start - * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer already running) - */ -int -GNUNET_TESTING_peer_start (struct GNUNET_TESTING_Peer *peer) -{ - if (NULL != peer->main_process) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - GNUNET_assert (NULL != peer->cfgfile); - peer->main_process = GNUNET_OS_start_process (GNUNET_NO, NULL, NULL, - peer->main_binary, "-c", - peer->cfgfile, - NULL); - if (NULL == peer->main_process) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to start `%s': %s\n"), - peer->main_binary, - STRERROR (errno)); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Stop the peer. - * - * @param peer peer to stop - * @return GNUNET_OK on success, GNUNET_SYSERR on error (i.e. peer not running) - */ -int -GNUNET_TESTING_peer_stop (struct GNUNET_TESTING_Peer *peer) -{ - if (NULL == peer->main_process) - { - GNUNET_break (0); - return GNUNET_SYSERR; - } - (void) GNUNET_OS_process_kill (peer->main_process, SIGTERM); - GNUNET_assert (GNUNET_OK == GNUNET_OS_process_wait (peer->main_process)); - GNUNET_OS_process_destroy (peer->main_process); - peer->main_process = NULL; - return GNUNET_OK; -} - - -/** - * Destroy the peer. Releases resources locked during peer configuration. - * If the peer is still running, it will be stopped AND a warning will be - * printed (users of the API should stop the peer explicitly first). - * - * @param peer peer to destroy - */ -void -GNUNET_TESTING_peer_destroy (struct GNUNET_TESTING_Peer *peer) -{ - if (NULL != peer->main_process) - { - GNUNET_break (0); - GNUNET_TESTING_peer_stop (peer); - } - GNUNET_free (peer->cfgfile); - GNUNET_free (peer->main_binary); - GNUNET_free (peer); -} - - -/** - * Start a single peer and run a test using the testing library. - * Starts a peer using the given configuration and then invokes the - * given callback. This function ALSO initializes the scheduler loop - * and should thus be called directly from "main". The testcase - * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'. - * - * @param tmppath path for storing temporary data for the test - * @param cfgfilename name of the configuration file to use; - * use NULL to only run with defaults - * @param tm main function of the testcase - * @param tm_cls closure for 'tm' - * @return 0 on success, 1 on error - */ -int -GNUNET_TESTING_peer_run (const char *tmppath, - const char *cfgfilename, - GNUNET_TESTING_TestMain tm, - void *tm_cls) -{ - return GNUNET_TESTING_service_run (tmppath, "arm", - cfgfilename, tm, tm_cls); -} - - -/** - * Structure for holding service data - */ -struct ServiceContext -{ - /** - * The configuration of the peer in which the service is run - */ - const struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * Callback to signal service startup - */ - GNUNET_TESTING_TestMain tm; - - /** - * Closure for the above callback - */ - void *tm_cls; -}; - - -/** - * Callback to be called when SCHEDULER has been started - * - * @param cls the ServiceContext - * @param tc the TaskContext - */ -static void -service_run_main (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct ServiceContext *sc = cls; - - sc->tm (sc->tm_cls, sc->cfg); -} - - -/** - * Start a single service (no ARM, except of course if the given - * service name is 'arm') and run a test using the testing library. - * Starts a service using the given configuration and then invokes the - * given callback. This function ALSO initializes the scheduler loop - * and should thus be called directly from "main". The testcase - * should self-terminate by invoking 'GNUNET_SCHEDULER_shutdown'. - * - * This function is useful if the testcase is for a single service - * and if that service doesn't itself depend on other services. - * - * @param tmppath path for storing temporary data for the test - * @param service_name name of the service to run - * @param cfgfilename name of the configuration file to use; - * use NULL to only run with defaults - * @param tm main function of the testcase - * @param tm_cls closure for 'tm' - * @return 0 on success, 1 on error - */ -int -GNUNET_TESTING_service_run (const char *tmppath, - const char *service_name, - const char *cfgfilename, - GNUNET_TESTING_TestMain tm, - void *tm_cls) -{ - struct ServiceContext sc; - struct GNUNET_TESTING_System *system; - struct GNUNET_TESTING_Peer *peer; - struct GNUNET_CONFIGURATION_Handle *cfg; - char *data_dir; - char *hostkeys_file; - - data_dir = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR); - GNUNET_asprintf (&hostkeys_file, "%s/testing_hostkeys.dat", data_dir); - GNUNET_free (data_dir); - system = GNUNET_TESTING_system_create (tmppath, "localhost"); - if (NULL == system) - { - GNUNET_free (hostkeys_file); - return 1; - } - if (GNUNET_OK != GNUNET_TESTING_hostkeys_load (system, hostkeys_file)) - { - GNUNET_free (hostkeys_file); - GNUNET_TESTING_system_destroy (system, GNUNET_YES); - return 1; - } - GNUNET_free (hostkeys_file); - cfg = GNUNET_CONFIGURATION_create (); - if (GNUNET_OK != GNUNET_CONFIGURATION_load (cfg, cfgfilename)) - { - LOG (GNUNET_ERROR_TYPE_ERROR, - _("Failed to load configuration from %s\n"), cfgfilename); - GNUNET_CONFIGURATION_destroy (cfg); - GNUNET_TESTING_system_destroy (system, GNUNET_YES); - return 1; - } - peer = GNUNET_TESTING_peer_configure (system, cfg, 0, NULL, NULL); - if (NULL == peer) - { - GNUNET_CONFIGURATION_destroy (cfg); - GNUNET_TESTING_hostkeys_unload (system); - GNUNET_TESTING_system_destroy (system, GNUNET_YES); - return 1; - } - GNUNET_TESTING_hostkeys_unload (system); - GNUNET_free (peer->main_binary); - GNUNET_asprintf (&peer->main_binary, "gnunet-service-%s", service_name); - if (GNUNET_OK != GNUNET_TESTING_peer_start (peer)) - { - GNUNET_TESTING_peer_destroy (peer); - GNUNET_CONFIGURATION_destroy (cfg); - GNUNET_TESTING_system_destroy (system, GNUNET_YES); - return 1; - } - sc.cfg = cfg; - sc.tm = tm; - sc.tm_cls = tm_cls; - GNUNET_SCHEDULER_run (&service_run_main, &sc); /* Scheduler loop */ - if (GNUNET_OK != GNUNET_TESTING_peer_stop (peer)) - { - GNUNET_TESTING_peer_destroy (peer); - GNUNET_CONFIGURATION_destroy (cfg); - GNUNET_TESTING_system_destroy (system, GNUNET_YES); - return 1; - } - GNUNET_TESTING_peer_destroy (peer); - GNUNET_CONFIGURATION_destroy (cfg); - GNUNET_TESTING_system_destroy (system, GNUNET_YES); - return 0; -} - - -/* end of testing_new.c */ diff --git a/src/testing/testing_peergroup.c b/src/testing/testing_peergroup.c deleted file mode 100644 index 87504ed..0000000 --- a/src/testing/testing_peergroup.c +++ /dev/null @@ -1,1017 +0,0 @@ -/* - This file is part of GNUnet - (C) 2008-2011 Christian Grothoff (and other contributing authors) - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - */ - -/** - * @file testing/testing_peergroup.c - * @brief API implementation for easy peer group creation - * @author Nathan Evans - * @author Christian Grothoff - * - */ -#include "platform.h" -#include "gnunet_constants.h" -#include "gnunet_arm_service.h" -#include "gnunet_testing_lib.h" -#include "gnunet_core_service.h" -#include "gnunet_disk_lib.h" - -/** Globals **/ -#define DEFAULT_CONNECT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) - -#define DEFAULT_CONNECT_ATTEMPTS 2 - -/** Struct definitions **/ - -struct PeerGroupStartupContext -{ - struct GNUNET_TESTING_PeerGroup *pg; - const struct GNUNET_CONFIGURATION_Handle *cfg; - unsigned int total; - unsigned int peers_left; - unsigned long long max_concurrent_connections; - - /** - * Maximum attemps to connect two daemons. - */ - unsigned long long connect_attempts; - - /** - * How long to spend trying to establish all the connections? - */ - struct GNUNET_TIME_Relative connect_timeout; - - unsigned long long max_concurrent_ssh; - struct GNUNET_TIME_Absolute timeout; - GNUNET_TESTING_NotifyConnection connect_cb; - GNUNET_TESTING_NotifyCompletion peergroup_cb; - - /** - * Closure for all peergroup callbacks. - */ - void *cls; - - const struct GNUNET_TESTING_Host *hostnames; - - /** - * FIXME document - */ - enum GNUNET_TESTING_Topology topology; - - float topology_percentage; - - float topology_probability; - - /** - * FIXME document - */ - enum GNUNET_TESTING_Topology restrict_topology; - - /** - * FIXME document - */ - char *restrict_transports; - - /** - * Initial connections - */ - enum GNUNET_TESTING_Topology connect_topology; - enum GNUNET_TESTING_TopologyOption connect_topology_option; - double connect_topology_option_modifier; - int verbose; - - struct ProgressMeter *hostkey_meter; - struct ProgressMeter *peer_start_meter; - struct ProgressMeter *connect_meter; - - /** - * Task used to kill the peergroup. - */ - GNUNET_SCHEDULER_TaskIdentifier die_task; - - char *fail_reason; - - /** - * Variable used to store the number of connections we should wait for. - */ - unsigned int expected_connections; - - /** - * Time when the connecting peers was started. - */ - struct GNUNET_TIME_Absolute connect_start_time; - - /** - * The total number of connections that have been created so far. - */ - unsigned int total_connections; - - /** - * The total number of connections that have failed so far. - */ - unsigned int failed_connections; - - /** - * File handle to write out topology in dot format. - */ - struct GNUNET_DISK_FileHandle *topology_output_file; -}; - -struct TopologyOutputContext -{ - struct GNUNET_DISK_FileHandle *file; - GNUNET_TESTING_NotifyCompletion notify_cb; - void *notify_cb_cls; -}; - -/** - * Simple struct to keep track of progress, and print a - * percentage meter for long running tasks. - */ -struct ProgressMeter -{ - /** - * Total number of tasks to complete. - */ - unsigned int total; - - /** - * Print percentage done after modnum tasks. - */ - unsigned int modnum; - - /** - * Print a . each dotnum tasks. - */ - unsigned int dotnum; - - /** - * Total number completed thus far. - */ - unsigned int completed; - - /** - * Whether or not to print. - */ - int print; - - /** - * Startup string for progress meter. - */ - char *startup_string; -}; - - -/** Utility functions **/ - -/** - * Create a meter to keep track of the progress of some task. - * - * @param total the total number of items to complete - * @param start_string a string to prefix the meter with (if printing) - * @param print GNUNET_YES to print the meter, GNUNET_NO to count - * internally only - * - * @return the progress meter - */ -static struct ProgressMeter * -create_meter (unsigned int total, char *start_string, int print) -{ - struct ProgressMeter *ret; - - ret = GNUNET_malloc (sizeof (struct ProgressMeter)); - ret->print = print; - ret->total = total; - ret->modnum = (total / 4 == 0) ? 1 : (total / 4); - ret->dotnum = (total / 50) + 1; - if (start_string != NULL) - ret->startup_string = GNUNET_strdup (start_string); - else - ret->startup_string = GNUNET_strdup (""); - - return ret; -} - -/** - * Update progress meter (increment by one). - * - * @param meter the meter to update and print info for - * - * @return GNUNET_YES if called the total requested, - * GNUNET_NO if more items expected - */ -static int -update_meter (struct ProgressMeter *meter) -{ - if (meter->print == GNUNET_YES) - { - if (meter->completed % meter->modnum == 0) - { - if (meter->completed == 0) - { - FPRINTF (stdout, "%sProgress: [0%%", meter->startup_string); - } - else - FPRINTF (stdout, "%d%%", - (int) (((float) meter->completed / meter->total) * 100)); - } - else if (meter->completed % meter->dotnum == 0) - FPRINTF (stdout, "%s", "."); - - if (meter->completed + 1 == meter->total) - FPRINTF (stdout, "%d%%]\n", 100); - fflush (stdout); - } - meter->completed++; - - if (meter->completed == meter->total) - return GNUNET_YES; - return GNUNET_NO; -} - -/** - * Reset progress meter. - * - * @param meter the meter to reset - * - * @return GNUNET_YES if meter reset, - * GNUNET_SYSERR on error - */ -static int -reset_meter (struct ProgressMeter *meter) -{ - if (meter == NULL) - return GNUNET_SYSERR; - - meter->completed = 0; - return GNUNET_YES; -} - -/** - * Release resources for meter - * - * @param meter the meter to free - */ -static void -free_meter (struct ProgressMeter *meter) -{ - GNUNET_free_non_null (meter->startup_string); - GNUNET_free (meter); -} - - -/** Functions for creating, starting and connecting the peergroup **/ - -/** - * Check whether peers successfully shut down. - */ -static void -internal_shutdown_callback (void *cls, const char *emsg) -{ - struct PeerGroupStartupContext *pg_start_ctx = cls; - - if (emsg != NULL) - pg_start_ctx->peergroup_cb (pg_start_ctx->cls, emsg); - else - pg_start_ctx->peergroup_cb (pg_start_ctx->cls, pg_start_ctx->fail_reason); -} - -/** - * 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) -{ - struct PeerGroupStartupContext *pg_start_ctx = cls; - - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failing peer group startup with error: `%s'!\n", - pg_start_ctx->fail_reason); - - GNUNET_TESTING_daemons_stop (pg_start_ctx->pg, - GNUNET_TIME_absolute_get_remaining - (pg_start_ctx->timeout), - &internal_shutdown_callback, pg_start_ctx); - - if (pg_start_ctx->hostkey_meter != NULL) - { - free_meter (pg_start_ctx->hostkey_meter); - pg_start_ctx->hostkey_meter = NULL; - } - if (pg_start_ctx->peer_start_meter != NULL) - { - free_meter (pg_start_ctx->peer_start_meter); - pg_start_ctx->peer_start_meter = NULL; - } - if (pg_start_ctx->connect_meter != NULL) - { - free_meter (pg_start_ctx->connect_meter); - pg_start_ctx->connect_meter = 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 -internal_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) -{ - struct PeerGroupStartupContext *pg_start_ctx = cls; - char *temp_str; - char *second_str; - int temp; - -#if TIMING - unsigned long long duration; - unsigned long long total_duration; - unsigned int new_connections; - unsigned int new_failed_connections; - double conns_per_sec_recent; - double conns_per_sec_total; - double failed_conns_per_sec_recent; - double failed_conns_per_sec_total; -#endif - -#if TIMING - if (GNUNET_TIME_absolute_get_difference - (connect_last_time, - GNUNET_TIME_absolute_get ()).rel_value > - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, - CONN_UPDATE_DURATION).rel_value) - { - /* Get number of new connections */ - new_connections = total_connections - previous_connections; - - /* Get number of new FAILED connections */ - new_failed_connections = failed_connections - previous_failed_connections; - - /* Get duration in seconds */ - duration = - GNUNET_TIME_absolute_get_difference (connect_last_time, - GNUNET_TIME_absolute_get - ()).rel_value / 1000; - total_duration = - GNUNET_TIME_absolute_get_difference (connect_start_time, - GNUNET_TIME_absolute_get - ()).rel_value / 1000; - - failed_conns_per_sec_recent = (double) new_failed_connections / duration; - failed_conns_per_sec_total = (double) failed_connections / total_duration; - conns_per_sec_recent = (double) new_connections / duration; - conns_per_sec_total = (double) total_connections / total_duration; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Recent: %.2f/s, Total: %.2f/s, Recent failed: %.2f/s, total failed %.2f/s\n", - conns_per_sec_recent, CONN_UPDATE_DURATION, conns_per_sec_total, - failed_conns_per_sec_recent, failed_conns_per_sec_total); - connect_last_time = GNUNET_TIME_absolute_get (); - previous_connections = total_connections; - previous_failed_connections = failed_connections; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "have %u total_connections, %u failed\n", total_connections, - failed_connections); - } -#endif - - - if (emsg == NULL) - { - pg_start_ctx->total_connections++; -#if VERBOSE > 1 - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "connected peer %s to peer %s, distance %u\n", - first_daemon->shortname, second_daemon->shortname, distance); -#endif - if (pg_start_ctx->topology_output_file != NULL) - { - second_str = GNUNET_strdup (GNUNET_i2s (second)); - temp = - GNUNET_asprintf (&temp_str, "\t\"%s\" -- \"%s\"\n", - GNUNET_i2s (first), second_str); - GNUNET_free (second_str); - if (temp > 0) - GNUNET_DISK_file_write (pg_start_ctx->topology_output_file, temp_str, - temp); - GNUNET_free (temp_str); - } - } - else - { - pg_start_ctx->failed_connections++; -#if VERBOSE - 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); - - 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 - } - - GNUNET_assert (pg_start_ctx->connect_meter != NULL); - if (pg_start_ctx->connect_cb != NULL) - pg_start_ctx->connect_cb (pg_start_ctx->cls, first, second, distance, - first_cfg, second_cfg, first_daemon, - second_daemon, emsg); - if (GNUNET_YES != update_meter (pg_start_ctx->connect_meter)) - { - /* No finished yet */ - return; - } -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Created %d total connections, which is our target number! Starting next phase of testing.\n", - pg_start_ctx->total_connections); -#endif - -#if TIMING - total_duration = - GNUNET_TIME_absolute_get_difference (connect_start_time, - GNUNET_TIME_absolute_get - ()).rel_value / 1000; - failed_conns_per_sec_total = (double) failed_connections / total_duration; - conns_per_sec_total = (double) total_connections / total_duration; - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Overall connection info --- Total: %u, Total Failed %u/s\n", - total_connections, failed_connections); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Overall connection info --- Total: %.2f/s, Total Failed %.2f/s\n", - conns_per_sec_total, failed_conns_per_sec_total); -#endif - - GNUNET_assert (pg_start_ctx->die_task != GNUNET_SCHEDULER_NO_TASK); - GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task); - - /* Call final callback, signifying that the peer group has been started and connected */ - if (pg_start_ctx->peergroup_cb != NULL) - pg_start_ctx->peergroup_cb (pg_start_ctx->cls, NULL); - - if (pg_start_ctx->topology_output_file != NULL) - { - temp = GNUNET_asprintf (&temp_str, "}\n"); - if (temp > 0) - GNUNET_DISK_file_write (pg_start_ctx->topology_output_file, temp_str, - temp); - GNUNET_free (temp_str); - GNUNET_DISK_file_close (pg_start_ctx->topology_output_file); - } - GNUNET_free_non_null (pg_start_ctx->fail_reason); - if (NULL != pg_start_ctx->hostkey_meter) - free_meter(pg_start_ctx->hostkey_meter); - if (NULL != pg_start_ctx->peer_start_meter) - free_meter(pg_start_ctx->peer_start_meter); - if (NULL != pg_start_ctx->connect_meter) - free_meter(pg_start_ctx->connect_meter); - GNUNET_free (pg_start_ctx); -} - - -/** - * Callback called for each started daemon. - * - * @param cls Clause (PG Context). - * @param id PeerIdentidy of started daemon. - * @param cfg Configuration used by the daemon. - * @param d Handle for the daemon. - * @param emsg Error message, NULL on success. - */ -static void -internal_peers_started_callback (void *cls, - const struct GNUNET_PeerIdentity *id, - const struct GNUNET_CONFIGURATION_Handle *cfg, - struct GNUNET_TESTING_Daemon *d, - const char *emsg) -{ - struct PeerGroupStartupContext *pg_start_ctx = cls; - - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to start daemon with error: `%s'\n", emsg); - return; - } - GNUNET_assert (id != NULL); - -#if VERBOSE > 1 - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n", - (pg_start_ctx->total - pg_start_ctx->peers_left) + 1, - pg_start_ctx->total); -#endif - - pg_start_ctx->peers_left--; - - if (NULL == pg_start_ctx->peer_start_meter) - { - /* Cancelled Ctrl-C or error */ - return; - } - if (GNUNET_YES == update_meter (pg_start_ctx->peer_start_meter)) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All %d daemons started, now connecting peers!\n", - pg_start_ctx->total); -#endif - GNUNET_assert (pg_start_ctx->die_task != GNUNET_SCHEDULER_NO_TASK); - GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task); - - pg_start_ctx->expected_connections = UINT_MAX; - // FIXME: why whould peers_left be != 0?? Or pg NULL? - if ((pg_start_ctx->pg != NULL) && (pg_start_ctx->peers_left == 0)) - { - pg_start_ctx->connect_start_time = GNUNET_TIME_absolute_get (); - pg_start_ctx->expected_connections = - GNUNET_TESTING_connect_topology (pg_start_ctx->pg, - pg_start_ctx->connect_topology, - pg_start_ctx->connect_topology_option, - pg_start_ctx->connect_topology_option_modifier, - pg_start_ctx->connect_timeout, - pg_start_ctx->connect_attempts, NULL, - NULL); - - pg_start_ctx->connect_meter = - create_meter (pg_start_ctx->expected_connections, "Peer connection ", - pg_start_ctx->verbose); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have %d expected connections\n", - pg_start_ctx->expected_connections); - } - - if (pg_start_ctx->expected_connections == 0) - { - GNUNET_free_non_null (pg_start_ctx->fail_reason); - pg_start_ctx->fail_reason = - GNUNET_strdup ("from connect topology (bad return)"); - pg_start_ctx->die_task = - GNUNET_SCHEDULER_add_now (&end_badly, pg_start_ctx); - return; - } - - GNUNET_free_non_null (pg_start_ctx->fail_reason); - pg_start_ctx->fail_reason = - GNUNET_strdup ("from connect topology (timeout)"); - pg_start_ctx->die_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining - (pg_start_ctx->timeout), &end_badly, - pg_start_ctx); - } -} - -/** - * Callback indicating that the hostkey was created for a peer. - * - * @param cls NULL - * @param id the peer identity - * @param d the daemon handle (pretty useless at this point, remove?) - * @param emsg non-null on failure - */ -static void -internal_hostkey_callback (void *cls, const struct GNUNET_PeerIdentity *id, - struct GNUNET_TESTING_Daemon *d, const char *emsg) -{ - struct PeerGroupStartupContext *pg_start_ctx = cls; - unsigned int create_expected_connections; - - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Hostkey callback received error: %s\n", emsg); - } - -#if VERBOSE > 1 - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Hostkey (%d/%d) created for peer `%s'\n", - pg_start_ctx->total - pg_start_ctx->peers_left + 1, - pg_start_ctx->total, GNUNET_i2s (id)); -#endif - - pg_start_ctx->peers_left--; - if (GNUNET_YES == update_meter (pg_start_ctx->hostkey_meter)) - { - GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task); - GNUNET_free_non_null (pg_start_ctx->fail_reason); - /* Set up task in case topology creation doesn't finish - * within a reasonable amount of time */ - pg_start_ctx->fail_reason = GNUNET_strdup ("from create_topology"); - pg_start_ctx->die_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining - (pg_start_ctx->timeout), &end_badly, - pg_start_ctx); - pg_start_ctx->peers_left = pg_start_ctx->total; /* Reset counter */ - create_expected_connections = - GNUNET_TESTING_create_topology (pg_start_ctx->pg, - pg_start_ctx->topology, - pg_start_ctx->restrict_topology, - pg_start_ctx->restrict_transports); - if (create_expected_connections > 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Topology set up, have %u expected connections, now starting peers!\n", - create_expected_connections); - GNUNET_TESTING_daemons_continue_startup (pg_start_ctx->pg); - } - else - { - GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task); - GNUNET_free_non_null (pg_start_ctx->fail_reason); - pg_start_ctx->fail_reason = - GNUNET_strdup ("from create topology (bad return)"); - pg_start_ctx->die_task = - GNUNET_SCHEDULER_add_now (&end_badly, pg_start_ctx); - return; - } - - GNUNET_SCHEDULER_cancel (pg_start_ctx->die_task); - GNUNET_free_non_null (pg_start_ctx->fail_reason); - pg_start_ctx->fail_reason = - GNUNET_strdup ("from continue startup (timeout)"); - pg_start_ctx->die_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining - (pg_start_ctx->timeout), &end_badly, - pg_start_ctx); - } -} - - -/** - * Prototype of a callback function indicating that two peers - * are currently connected. - * - * @param cls closure - * @param first peer id for first daemon - * @param second peer id for the second daemon - * @param emsg error message (NULL on success) - */ -void -write_topology_cb (void *cls, const struct GNUNET_PeerIdentity *first, - const struct GNUNET_PeerIdentity *second, const char *emsg) -{ - struct TopologyOutputContext *topo_ctx; - int temp; - char *temp_str; - char *temp_pid2; - - topo_ctx = (struct TopologyOutputContext *) cls; - GNUNET_assert (topo_ctx->file != NULL); - if ((emsg == NULL) && (first != NULL) && (second != NULL)) - { - GNUNET_assert (first != NULL); - GNUNET_assert (second != NULL); - temp_pid2 = GNUNET_strdup (GNUNET_i2s (second)); - temp = - GNUNET_asprintf (&temp_str, "\t\"%s\" -- \"%s\"\n", GNUNET_i2s (first), - temp_pid2); - GNUNET_free (temp_pid2); - GNUNET_DISK_file_write (topo_ctx->file, temp_str, temp); - } - else if ((emsg == NULL) && (first == NULL) && (second == NULL)) - { - temp = GNUNET_asprintf (&temp_str, "}\n"); - GNUNET_DISK_file_write (topo_ctx->file, temp_str, temp); - GNUNET_DISK_file_close (topo_ctx->file); - topo_ctx->notify_cb (topo_ctx->notify_cb_cls, NULL); - GNUNET_free (topo_ctx); - } - else - { - temp = GNUNET_asprintf (&temp_str, "}\n"); - GNUNET_DISK_file_write (topo_ctx->file, temp_str, temp); - GNUNET_DISK_file_close (topo_ctx->file); - topo_ctx->notify_cb (topo_ctx->notify_cb_cls, emsg); - GNUNET_free (topo_ctx); - } -} - -/** - * Print current topology to a graphviz readable file. - * - * @param pg a currently running peergroup to print to file - * @param output_filename the file to write the topology to - * @param notify_cb callback to call upon completion or failure - * @param notify_cb_cls closure for notify_cb - * - */ -void -GNUNET_TESTING_peergroup_topology_to_file (struct GNUNET_TESTING_PeerGroup *pg, - const char *output_filename, - GNUNET_TESTING_NotifyCompletion - notify_cb, void *notify_cb_cls) -{ - struct TopologyOutputContext *topo_ctx; - int temp; - char *temp_str; - - topo_ctx = GNUNET_malloc (sizeof (struct TopologyOutputContext)); - - topo_ctx->notify_cb = notify_cb; - topo_ctx->notify_cb_cls = notify_cb_cls; - topo_ctx->file = - GNUNET_DISK_file_open (output_filename, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - if (topo_ctx->file == NULL) - { - notify_cb (notify_cb_cls, "Failed to open output file!"); - GNUNET_free (topo_ctx); - return; - } - - temp = GNUNET_asprintf (&temp_str, "strict graph G {\n"); - if (temp > 0) - GNUNET_DISK_file_write (topo_ctx->file, temp_str, temp); - GNUNET_free_non_null (temp_str); - GNUNET_TESTING_get_topology (pg, &write_topology_cb, topo_ctx); -} - -/** - * Start a peer group with a given number of peers. Notify - * on completion of peer startup and connection based on given - * topological constraints. Optionally notify on each - * established connection. - * - * @param cfg configuration template to use - * @param total number of daemons to start - * @param timeout total time allowed for peers to start - * @param connect_cb function to call each time two daemons are connected - * @param peergroup_cb function to call once all peers are up and connected - * @param peergroup_cls closure for peergroup callbacks - * @param hostnames linked list of host structs to use to start peers on - * (NULL to run on localhost only) - * - * @return NULL on error, otherwise handle to control peer group - */ -struct GNUNET_TESTING_PeerGroup * -GNUNET_TESTING_peergroup_start (const struct GNUNET_CONFIGURATION_Handle *cfg, - unsigned int total, - struct GNUNET_TIME_Relative timeout, - GNUNET_TESTING_NotifyConnection connect_cb, - GNUNET_TESTING_NotifyCompletion peergroup_cb, - void *peergroup_cls, - const struct GNUNET_TESTING_Host *hostnames) -{ - struct PeerGroupStartupContext *pg_start_ctx; - char *temp_str; - int temp; - struct GNUNET_TIME_Relative rtimeout; - - GNUNET_assert (total > 0); - GNUNET_assert (cfg != NULL); - - pg_start_ctx = GNUNET_malloc (sizeof (struct PeerGroupStartupContext)); - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "connect_attempts", - &pg_start_ctx->connect_attempts)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "connect_attempts"); - GNUNET_free (pg_start_ctx); - return NULL; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "CONNECT_TIMEOUT", - &pg_start_ctx->connect_timeout)) - { - pg_start_ctx->connect_timeout = DEFAULT_CONNECT_TIMEOUT; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", - "max_outstanding_connections", - &pg_start_ctx->max_concurrent_connections)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "max_outstanding_connections"); - GNUNET_free (pg_start_ctx); - return NULL; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (cfg, "testing", - "max_concurrent_ssh", - &pg_start_ctx->max_concurrent_ssh)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "max_concurrent_ssh"); - GNUNET_free (pg_start_ctx); - return NULL; - } - - if (GNUNET_SYSERR == - (pg_start_ctx->verbose = - GNUNET_CONFIGURATION_get_value_yesno (cfg, "testing", - "use_progressbars"))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "use_progressbars"); - GNUNET_free (pg_start_ctx); - return NULL; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_time (cfg, "testing", "PEERGROUP_TIMEOUT", - &rtimeout)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Must provide option %s:%s!\n", - "testing", "PEERGROUP_TIMEOUT"); - GNUNET_free (pg_start_ctx); - return NULL; - } - pg_start_ctx->timeout = GNUNET_TIME_relative_to_absolute (rtimeout); - - - /* Read topology related options from the configuration file */ - temp_str = NULL; - if ((GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "topology", - &temp_str)) && - (GNUNET_NO == - GNUNET_TESTING_topology_get (&pg_start_ctx->topology, temp_str))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid topology `%s' given for section %s option %s\n", - temp_str, "TESTING", "TOPOLOGY"); - pg_start_ctx->topology = GNUNET_TESTING_TOPOLOGY_CLIQUE; /* Defaults to NONE, so set better default here */ - } - GNUNET_free_non_null (temp_str); - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "topology_output_file", &temp_str)) - { - pg_start_ctx->topology_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 (pg_start_ctx->topology_output_file != NULL) - { - GNUNET_free (temp_str); - temp = GNUNET_asprintf (&temp_str, "strict graph G {\n"); - if (temp > 0) - GNUNET_DISK_file_write (pg_start_ctx->topology_output_file, temp_str, - temp); - } - GNUNET_free (temp_str); - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "percentage", - &temp_str)) - pg_start_ctx->topology_percentage = 0.5; - else - { - pg_start_ctx->topology_percentage = atof (temp_str); - GNUNET_free (temp_str); - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", "probability", - &temp_str)) - pg_start_ctx->topology_probability = 0.5; - else - { - pg_start_ctx->topology_probability = atof (temp_str); - GNUNET_free (temp_str); - } - - if ((GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "connect_topology", &temp_str)) && - (GNUNET_NO == - GNUNET_TESTING_topology_get (&pg_start_ctx->connect_topology, temp_str))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid connect topology `%s' given for section %s option %s\n", - temp_str, "TESTING", "CONNECT_TOPOLOGY"); - } - GNUNET_free_non_null (temp_str); - - if ((GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "connect_topology_option", - &temp_str)) && - (GNUNET_NO == - GNUNET_TESTING_topology_option_get - (&pg_start_ctx->connect_topology_option, temp_str))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid connect topology option `%s' given for section %s option %s\n", - temp_str, "TESTING", "CONNECT_TOPOLOGY_OPTION"); - pg_start_ctx->connect_topology_option = GNUNET_TESTING_TOPOLOGY_OPTION_ALL; /* Defaults to NONE, set to ALL */ - } - GNUNET_free_non_null (temp_str); - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "connect_topology_option_modifier", - &temp_str)) - { - if (SSCANF - (temp_str, "%lf", &pg_start_ctx->connect_topology_option_modifier) != 1) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _ - ("Invalid value `%s' for option `%s' in section `%s': expected float\n"), - temp_str, "connect_topology_option_modifier", "TESTING"); - GNUNET_free (temp_str); - GNUNET_free (pg_start_ctx); - return NULL; - } - GNUNET_free (temp_str); - } - - if (GNUNET_YES != - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "blacklist_transports", - &pg_start_ctx->restrict_transports)) - pg_start_ctx->restrict_transports = NULL; - - pg_start_ctx->restrict_topology = GNUNET_TESTING_TOPOLOGY_NONE; - if ((GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "testing", - "blacklist_topology", &temp_str)) - && (GNUNET_NO == - GNUNET_TESTING_topology_get (&pg_start_ctx->restrict_topology, - temp_str))) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Invalid topology `%s' given for section %s option %s\n", - temp_str, "TESTING", "BLACKLIST_TOPOLOGY"); - } - - GNUNET_free_non_null (temp_str); - - pg_start_ctx->cfg = cfg; - pg_start_ctx->total = total; - pg_start_ctx->peers_left = total; - pg_start_ctx->connect_cb = connect_cb; - pg_start_ctx->peergroup_cb = peergroup_cb; - pg_start_ctx->cls = peergroup_cls; - pg_start_ctx->hostnames = hostnames; - pg_start_ctx->hostkey_meter = - create_meter (pg_start_ctx->peers_left, "Hostkeys created ", - pg_start_ctx->verbose); - pg_start_ctx->peer_start_meter = - create_meter (pg_start_ctx->peers_left, "Peers started ", - pg_start_ctx->verbose); - /* Make compilers happy */ - reset_meter (pg_start_ctx->peer_start_meter); - pg_start_ctx->fail_reason = - GNUNET_strdup - ("didn't generate all hostkeys within allowed startup time!"); - pg_start_ctx->die_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining - (pg_start_ctx->timeout), &end_badly, - pg_start_ctx); - - pg_start_ctx->pg = - GNUNET_TESTING_daemons_start (pg_start_ctx->cfg, pg_start_ctx->peers_left, - pg_start_ctx->max_concurrent_connections, - pg_start_ctx->max_concurrent_ssh, - GNUNET_TIME_absolute_get_remaining - (pg_start_ctx->timeout), - &internal_hostkey_callback, pg_start_ctx, - &internal_peers_started_callback, - pg_start_ctx, &internal_topology_callback, - pg_start_ctx, pg_start_ctx->hostnames); - - return pg_start_ctx->pg; -} - -/* end of testing_peergroup.c */ |