diff options
author | Bertrand Marc <beberking@gmail.com> | 2012-05-02 21:43:37 +0200 |
---|---|---|
committer | Bertrand Marc <beberking@gmail.com> | 2012-05-02 21:43:37 +0200 |
commit | 2b81464a43485fcc8ce079fafdee7b7a171835f4 (patch) | |
tree | 394774c0f735199b57d51a2d3840356317853fe1 /src/hostlist |
Imported Upstream version 0.9.2upstream/0.9.2
Diffstat (limited to 'src/hostlist')
20 files changed, 5249 insertions, 0 deletions
diff --git a/src/hostlist/Makefile.am b/src/hostlist/Makefile.am new file mode 100644 index 0000000..f764f2f --- /dev/null +++ b/src/hostlist/Makefile.am @@ -0,0 +1,81 @@ +INCLUDES = -I$(top_srcdir)/src/include + +pkgcfgdir= $(pkgdatadir)/config.d/ + +dist_pkgcfg_DATA = \ + hostlist.conf + +if USE_COVERAGE + AM_CFLAGS = --coverage -O0 +endif + +if HAVE_MHD + HOSTLIST_SERVER_SOURCES = hostlist-server.c hostlist-server.h + GN_LIBMHD = -lmicrohttpd +endif + +bin_PROGRAMS = \ + gnunet-daemon-hostlist + +gnunet_daemon_hostlist_SOURCES = \ + gnunet-daemon-hostlist.c gnunet-daemon-hostlist.h \ + hostlist-client.c hostlist-client.h \ + $(HOSTLIST_SERVER_SOURCES) + +gnunet_daemon_hostlist_LDADD = \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBMHD) \ + @LIBCURL@ \ + $(GN_LIBINTL) + +gnunet_daemon_hostlist_CPPFLAGS = \ + @LIBCURL_CPPFLAGS@ + +check_PROGRAMS = \ + test_gnunet_daemon_hostlist \ + test_gnunet_daemon_hostlist_reconnect \ + test_gnunet_daemon_hostlist_learning + +if HAVE_MHD +if ENABLE_TEST_RUN +TESTS = \ + test_gnunet_daemon_hostlist \ + test_gnunet_daemon_hostlist_reconnect \ + test_gnunet_daemon_hostlist_learning +endif +endif + +test_gnunet_daemon_hostlist_SOURCES = \ + test_gnunet_daemon_hostlist.c +test_gnunet_daemon_hostlist_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_gnunet_daemon_hostlist_reconnect_SOURCES = \ + test_gnunet_daemon_hostlist_reconnect.c +test_gnunet_daemon_hostlist_reconnect_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_gnunet_daemon_hostlist_learning_SOURCES = \ + test_gnunet_daemon_hostlist_learning.c +test_gnunet_daemon_hostlist_learning_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la + +EXTRA_DIST = \ + test_hostlist_defaults.conf \ + test_gnunet_daemon_hostlist_data.conf \ + test_gnunet_daemon_hostlist_peer1.conf \ + test_gnunet_daemon_hostlist_peer2.conf \ + test_learning_adv_peer.conf \ + test_learning_learn_peer.conf \ + test_learning_learn_peer2.conf \ + learning_data.conf diff --git a/src/hostlist/Makefile.in b/src/hostlist/Makefile.in new file mode 100644 index 0000000..737e87c --- /dev/null +++ b/src/hostlist/Makefile.in @@ -0,0 +1,949 @@ +# Makefile.in generated by automake 1.11.1 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. +# 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. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = gnunet-daemon-hostlist$(EXEEXT) +check_PROGRAMS = test_gnunet_daemon_hostlist$(EXEEXT) \ + test_gnunet_daemon_hostlist_reconnect$(EXEEXT) \ + test_gnunet_daemon_hostlist_learning$(EXEEXT) +@ENABLE_TEST_RUN_TRUE@@HAVE_MHD_TRUE@TESTS = test_gnunet_daemon_hostlist$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@@HAVE_MHD_TRUE@ test_gnunet_daemon_hostlist_reconnect$(EXEEXT) \ +@ENABLE_TEST_RUN_TRUE@@HAVE_MHD_TRUE@ test_gnunet_daemon_hostlist_learning$(EXEEXT) +subdir = src/hostlist +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/progtest.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/gnunet_config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)" +PROGRAMS = $(bin_PROGRAMS) +am__gnunet_daemon_hostlist_SOURCES_DIST = gnunet-daemon-hostlist.c \ + gnunet-daemon-hostlist.h hostlist-client.c hostlist-client.h \ + hostlist-server.c hostlist-server.h +@HAVE_MHD_TRUE@am__objects_1 = gnunet_daemon_hostlist-hostlist-server.$(OBJEXT) +am_gnunet_daemon_hostlist_OBJECTS = \ + gnunet_daemon_hostlist-gnunet-daemon-hostlist.$(OBJEXT) \ + gnunet_daemon_hostlist-hostlist-client.$(OBJEXT) \ + $(am__objects_1) +gnunet_daemon_hostlist_OBJECTS = $(am_gnunet_daemon_hostlist_OBJECTS) +am__DEPENDENCIES_1 = +gnunet_daemon_hostlist_DEPENDENCIES = \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +am_test_gnunet_daemon_hostlist_OBJECTS = \ + test_gnunet_daemon_hostlist.$(OBJEXT) +test_gnunet_daemon_hostlist_OBJECTS = \ + $(am_test_gnunet_daemon_hostlist_OBJECTS) +test_gnunet_daemon_hostlist_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la +am_test_gnunet_daemon_hostlist_learning_OBJECTS = \ + test_gnunet_daemon_hostlist_learning.$(OBJEXT) +test_gnunet_daemon_hostlist_learning_OBJECTS = \ + $(am_test_gnunet_daemon_hostlist_learning_OBJECTS) +test_gnunet_daemon_hostlist_learning_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la +am_test_gnunet_daemon_hostlist_reconnect_OBJECTS = \ + test_gnunet_daemon_hostlist_reconnect.$(OBJEXT) +test_gnunet_daemon_hostlist_reconnect_OBJECTS = \ + $(am_test_gnunet_daemon_hostlist_reconnect_OBJECTS) +test_gnunet_daemon_hostlist_reconnect_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +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_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(gnunet_daemon_hostlist_SOURCES) \ + $(test_gnunet_daemon_hostlist_SOURCES) \ + $(test_gnunet_daemon_hostlist_learning_SOURCES) \ + $(test_gnunet_daemon_hostlist_reconnect_SOURCES) +DIST_SOURCES = $(am__gnunet_daemon_hostlist_SOURCES_DIST) \ + $(test_gnunet_daemon_hostlist_SOURCES) \ + $(test_gnunet_daemon_hostlist_learning_SOURCES) \ + $(test_gnunet_daemon_hostlist_reconnect_SOURCES) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +DATA = $(dist_pkgcfg_DATA) +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ARGZ_H = @ARGZ_H@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_INTERFACE = @DEFAULT_INTERFACE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLDIR = @DLLDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXT_LIBS = @EXT_LIBS@ +EXT_LIB_PATH = @EXT_LIB_PATH@ +FGREP = @FGREP@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUNETDNS_GROUP = @GNUNETDNS_GROUP@ +GN_DAEMON_CONFIG_DIR = @GN_DAEMON_CONFIG_DIR@ +GN_DAEMON_HOME_DIR = @GN_DAEMON_HOME_DIR@ +GN_INTLINCL = @GN_INTLINCL@ +GN_LIBINTL = @GN_LIBINTL@ +GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@ +GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@ +GN_USER_HOME_DIR = @GN_USER_HOME_DIR@ +GREP = @GREP@ +HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBCURL = @LIBCURL@ +LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBPREFIX = @LIBPREFIX@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUNISTRING = @LIBUNISTRING@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LTLIBUNISTRING = @LTLIBUNISTRING@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@ +POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@ +POSUB = @POSUB@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SQLITE_CPPFLAGS = @SQLITE_CPPFLAGS@ +SQLITE_LDFLAGS = @SQLITE_LDFLAGS@ +STRIP = @STRIP@ +SUDO_BINARY = @SUDO_BINARY@ +UNIXONLY = @UNIXONLY@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +_libcurl_config = @_libcurl_config@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +ac_ct_OBJC = @ac_ct_OBJC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_target = @build_target@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir)/src/include +pkgcfgdir = $(pkgdatadir)/config.d/ +dist_pkgcfg_DATA = \ + hostlist.conf + +@USE_COVERAGE_TRUE@AM_CFLAGS = --coverage -O0 +@HAVE_MHD_TRUE@HOSTLIST_SERVER_SOURCES = hostlist-server.c hostlist-server.h +@HAVE_MHD_TRUE@GN_LIBMHD = -lmicrohttpd +gnunet_daemon_hostlist_SOURCES = \ + gnunet-daemon-hostlist.c gnunet-daemon-hostlist.h \ + hostlist-client.c hostlist-client.h \ + $(HOSTLIST_SERVER_SOURCES) + +gnunet_daemon_hostlist_LDADD = \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBMHD) \ + @LIBCURL@ \ + $(GN_LIBINTL) + +gnunet_daemon_hostlist_CPPFLAGS = \ + @LIBCURL_CPPFLAGS@ + +test_gnunet_daemon_hostlist_SOURCES = \ + test_gnunet_daemon_hostlist.c + +test_gnunet_daemon_hostlist_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_gnunet_daemon_hostlist_reconnect_SOURCES = \ + test_gnunet_daemon_hostlist_reconnect.c + +test_gnunet_daemon_hostlist_reconnect_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la + +test_gnunet_daemon_hostlist_learning_SOURCES = \ + test_gnunet_daemon_hostlist_learning.c + +test_gnunet_daemon_hostlist_learning_LDADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/core/libgnunetcore.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la \ + $(top_builddir)/src/util/libgnunetutil.la + +EXTRA_DIST = \ + test_hostlist_defaults.conf \ + test_gnunet_daemon_hostlist_data.conf \ + test_gnunet_daemon_hostlist_peer1.conf \ + test_gnunet_daemon_hostlist_peer2.conf \ + test_learning_adv_peer.conf \ + test_learning_learn_peer.conf \ + test_learning_learn_peer2.conf \ + learning_data.conf + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/hostlist/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/hostlist/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +gnunet-daemon-hostlist$(EXEEXT): $(gnunet_daemon_hostlist_OBJECTS) $(gnunet_daemon_hostlist_DEPENDENCIES) + @rm -f gnunet-daemon-hostlist$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(gnunet_daemon_hostlist_OBJECTS) $(gnunet_daemon_hostlist_LDADD) $(LIBS) +test_gnunet_daemon_hostlist$(EXEEXT): $(test_gnunet_daemon_hostlist_OBJECTS) $(test_gnunet_daemon_hostlist_DEPENDENCIES) + @rm -f test_gnunet_daemon_hostlist$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gnunet_daemon_hostlist_OBJECTS) $(test_gnunet_daemon_hostlist_LDADD) $(LIBS) +test_gnunet_daemon_hostlist_learning$(EXEEXT): $(test_gnunet_daemon_hostlist_learning_OBJECTS) $(test_gnunet_daemon_hostlist_learning_DEPENDENCIES) + @rm -f test_gnunet_daemon_hostlist_learning$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gnunet_daemon_hostlist_learning_OBJECTS) $(test_gnunet_daemon_hostlist_learning_LDADD) $(LIBS) +test_gnunet_daemon_hostlist_reconnect$(EXEEXT): $(test_gnunet_daemon_hostlist_reconnect_OBJECTS) $(test_gnunet_daemon_hostlist_reconnect_DEPENDENCIES) + @rm -f test_gnunet_daemon_hostlist_reconnect$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_gnunet_daemon_hostlist_reconnect_OBJECTS) $(test_gnunet_daemon_hostlist_reconnect_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_daemon_hostlist-gnunet-daemon-hostlist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_daemon_hostlist-hostlist-client.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet_daemon_hostlist-hostlist-server.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gnunet_daemon_hostlist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gnunet_daemon_hostlist_learning.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_gnunet_daemon_hostlist_reconnect.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(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@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +gnunet_daemon_hostlist-gnunet-daemon-hostlist.o: gnunet-daemon-hostlist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gnunet_daemon_hostlist-gnunet-daemon-hostlist.o -MD -MP -MF $(DEPDIR)/gnunet_daemon_hostlist-gnunet-daemon-hostlist.Tpo -c -o gnunet_daemon_hostlist-gnunet-daemon-hostlist.o `test -f 'gnunet-daemon-hostlist.c' || echo '$(srcdir)/'`gnunet-daemon-hostlist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_daemon_hostlist-gnunet-daemon-hostlist.Tpo $(DEPDIR)/gnunet_daemon_hostlist-gnunet-daemon-hostlist.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gnunet-daemon-hostlist.c' object='gnunet_daemon_hostlist-gnunet-daemon-hostlist.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gnunet_daemon_hostlist-gnunet-daemon-hostlist.o `test -f 'gnunet-daemon-hostlist.c' || echo '$(srcdir)/'`gnunet-daemon-hostlist.c + +gnunet_daemon_hostlist-gnunet-daemon-hostlist.obj: gnunet-daemon-hostlist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gnunet_daemon_hostlist-gnunet-daemon-hostlist.obj -MD -MP -MF $(DEPDIR)/gnunet_daemon_hostlist-gnunet-daemon-hostlist.Tpo -c -o gnunet_daemon_hostlist-gnunet-daemon-hostlist.obj `if test -f 'gnunet-daemon-hostlist.c'; then $(CYGPATH_W) 'gnunet-daemon-hostlist.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-daemon-hostlist.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_daemon_hostlist-gnunet-daemon-hostlist.Tpo $(DEPDIR)/gnunet_daemon_hostlist-gnunet-daemon-hostlist.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gnunet-daemon-hostlist.c' object='gnunet_daemon_hostlist-gnunet-daemon-hostlist.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gnunet_daemon_hostlist-gnunet-daemon-hostlist.obj `if test -f 'gnunet-daemon-hostlist.c'; then $(CYGPATH_W) 'gnunet-daemon-hostlist.c'; else $(CYGPATH_W) '$(srcdir)/gnunet-daemon-hostlist.c'; fi` + +gnunet_daemon_hostlist-hostlist-client.o: hostlist-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gnunet_daemon_hostlist-hostlist-client.o -MD -MP -MF $(DEPDIR)/gnunet_daemon_hostlist-hostlist-client.Tpo -c -o gnunet_daemon_hostlist-hostlist-client.o `test -f 'hostlist-client.c' || echo '$(srcdir)/'`hostlist-client.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_daemon_hostlist-hostlist-client.Tpo $(DEPDIR)/gnunet_daemon_hostlist-hostlist-client.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hostlist-client.c' object='gnunet_daemon_hostlist-hostlist-client.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gnunet_daemon_hostlist-hostlist-client.o `test -f 'hostlist-client.c' || echo '$(srcdir)/'`hostlist-client.c + +gnunet_daemon_hostlist-hostlist-client.obj: hostlist-client.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gnunet_daemon_hostlist-hostlist-client.obj -MD -MP -MF $(DEPDIR)/gnunet_daemon_hostlist-hostlist-client.Tpo -c -o gnunet_daemon_hostlist-hostlist-client.obj `if test -f 'hostlist-client.c'; then $(CYGPATH_W) 'hostlist-client.c'; else $(CYGPATH_W) '$(srcdir)/hostlist-client.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_daemon_hostlist-hostlist-client.Tpo $(DEPDIR)/gnunet_daemon_hostlist-hostlist-client.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hostlist-client.c' object='gnunet_daemon_hostlist-hostlist-client.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gnunet_daemon_hostlist-hostlist-client.obj `if test -f 'hostlist-client.c'; then $(CYGPATH_W) 'hostlist-client.c'; else $(CYGPATH_W) '$(srcdir)/hostlist-client.c'; fi` + +gnunet_daemon_hostlist-hostlist-server.o: hostlist-server.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gnunet_daemon_hostlist-hostlist-server.o -MD -MP -MF $(DEPDIR)/gnunet_daemon_hostlist-hostlist-server.Tpo -c -o gnunet_daemon_hostlist-hostlist-server.o `test -f 'hostlist-server.c' || echo '$(srcdir)/'`hostlist-server.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_daemon_hostlist-hostlist-server.Tpo $(DEPDIR)/gnunet_daemon_hostlist-hostlist-server.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hostlist-server.c' object='gnunet_daemon_hostlist-hostlist-server.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gnunet_daemon_hostlist-hostlist-server.o `test -f 'hostlist-server.c' || echo '$(srcdir)/'`hostlist-server.c + +gnunet_daemon_hostlist-hostlist-server.obj: hostlist-server.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gnunet_daemon_hostlist-hostlist-server.obj -MD -MP -MF $(DEPDIR)/gnunet_daemon_hostlist-hostlist-server.Tpo -c -o gnunet_daemon_hostlist-hostlist-server.obj `if test -f 'hostlist-server.c'; then $(CYGPATH_W) 'hostlist-server.c'; else $(CYGPATH_W) '$(srcdir)/hostlist-server.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gnunet_daemon_hostlist-hostlist-server.Tpo $(DEPDIR)/gnunet_daemon_hostlist-hostlist-server.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hostlist-server.c' object='gnunet_daemon_hostlist-hostlist-server.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gnunet_daemon_hostlist_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gnunet_daemon_hostlist-hostlist-server.obj `if test -f 'hostlist-server.c'; then $(CYGPATH_W) 'hostlist-server.c'; else $(CYGPATH_W) '$(srcdir)/hostlist-server.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +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=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgcfgdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgcfgdir)" || exit $$?; \ + done + +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 + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + echo "$$grn$$dashes"; \ + else \ + echo "$$red$$dashes"; \ + fi; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes$$std"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-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 +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_pkgcfgDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-dist_pkgcfgDATA + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ + clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am \ + install-dist_pkgcfgDATA install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-dist_pkgcfgDATA + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c new file mode 100644 index 0000000..0eedb56 --- /dev/null +++ b/src/hostlist/gnunet-daemon-hostlist.c @@ -0,0 +1,347 @@ +/* + This file is part of GNUnet. + (C) 2007, 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 hostlist/gnunet-daemon-hostlist.c + * @brief code for bootstrapping via hostlist servers + * @author Christian Grothoff + */ + +#include <stdlib.h> +#include "platform.h" +#include "hostlist-client.h" +#include "gnunet_core_service.h" +#include "gnunet_getopt_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_program_lib.h" +#include "gnunet_statistics_service.h" +#include "gnunet_strings_lib.h" +#include "gnunet_time_lib.h" +#include "gnunet_util_lib.h" + +#if HAVE_MHD + +#include "hostlist-server.h" + +/** + * Set if we are allowed to advertise our hostlist to others. + */ +static int advertising; + +/** + * Set if the user wants us to run a hostlist server. + */ +static int provide_hostlist; + +/** + * Handle to hostlist server's connect handler + */ +static GNUNET_CORE_ConnectEventHandler server_ch; + +/** + * Handle to hostlist server's disconnect handler + */ +static GNUNET_CORE_DisconnectEventHandler server_dh; + +#endif + +/** + * Set if we are allowed to learn about peers by accessing + * hostlist servers. + */ +static int bootstrapping; + +/** + * Set if the user allows us to learn about new hostlists + * from the network. + */ +static int learning; + +/** + * Statistics handle. + */ +static struct GNUNET_STATISTICS_Handle *stats; + +/** + * Handle to the core service (NULL until we've connected to it). + */ +static struct GNUNET_CORE_Handle *core; + +/** + * Handle to the hostlist client's advertisement handler + */ +static GNUNET_CORE_MessageCallback client_adv_handler; + +/** + * Handle to hostlist client's connect handler + */ +static GNUNET_CORE_ConnectEventHandler client_ch; + +/** + * Handle to hostlist client's disconnect handler + */ +static GNUNET_CORE_DisconnectEventHandler client_dh; + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * A HOSTLIST_ADV message is used to exchange information about + * hostlist advertisements. This struct is always + * followed by the actual url under which the hostlist can be obtained: + * + * 1) transport-name (0-terminated) + * 2) address-length (uint32_t, network byte order; possibly + * unaligned!) + * 3) address expiration (GNUNET_TIME_AbsoluteNBO); possibly + * unaligned!) + * 4) address (address-length bytes; possibly unaligned!) + */ +struct GNUNET_HOSTLIST_ADV_Message +{ + /** + * Type will be GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT. + */ + struct GNUNET_MessageHeader header; + + /** + * Always zero (for alignment). + */ + uint32_t reserved GNUNET_PACKED; +}; +GNUNET_NETWORK_STRUCT_END + +static struct GNUNET_PeerIdentity me; + +static void +core_init (void *cls, struct GNUNET_CORE_Handle *server, + const struct GNUNET_PeerIdentity *my_identity) +{ + me = *my_identity; +} + +/** + * Core handler for p2p hostlist advertisements + * + * @param cls closure + * @param peer identity of the sender + * @param message advertisement message we got + * @param atsi performance information + * @param atsi_count number of records in 'atsi' + * @return GNUNET_OK on success + */ +static int +advertisement_handler (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information *atsi, + unsigned int atsi_count) +{ + GNUNET_assert (NULL != client_adv_handler); + return (*client_adv_handler) (cls, peer, message, atsi, atsi_count); +} + + +/** + * Method called whenever a given peer connects. Wrapper to call both client's and server's functions + * + * @param cls closure + * @param peer peer identity this notification is about + * @param atsi performance data + * @param atsi_count number of records in 'atsi' + */ +static void +connect_handler (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *atsi, + unsigned int atsi_count) +{ + if (0 == memcmp (&me, peer, sizeof (struct GNUNET_PeerIdentity))) + return; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "A new peer connected, notifying client and server\n"); + if (NULL != client_ch) + (*client_ch) (cls, peer, atsi, atsi_count); +#if HAVE_MHD + if (NULL != server_ch) + (*server_ch) (cls, peer, atsi, atsi_count); +#endif +} + +/** + * Method called whenever a given peer disconnects. Wrapper to call both client's and server's functions + * + * @param cls closure + * @param peer peer identity this notification is about + */ +static void +disconnect_handler (void *cls, const struct GNUNET_PeerIdentity *peer) +{ + if (0 == memcmp (&me, peer, sizeof (struct GNUNET_PeerIdentity))) + return; + /* call hostlist client disconnect handler */ + if (NULL != client_dh) + (*client_dh) (cls, peer); +#if HAVE_MHD + /* call hostlist server disconnect handler */ + if (NULL != server_dh) + (*server_dh) (cls, peer); +#endif +} + +/** + * Last task run during shutdown. Disconnects us from + * the other services. + */ +static void +cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist daemon is shutting down\n"); + if (core != NULL) + { + GNUNET_CORE_disconnect (core); + core = NULL; + } + if (bootstrapping) + { + GNUNET_HOSTLIST_client_stop (); + } +#if HAVE_MHD + if (provide_hostlist) + { + GNUNET_HOSTLIST_server_stop (); + } +#endif + if (stats != NULL) + { + GNUNET_STATISTICS_destroy (stats, GNUNET_NO); + stats = NULL; + } +} + + +/** + * Main function that will be run. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + static const struct GNUNET_CORE_MessageHandler learn_handlers[] = { + {&advertisement_handler, GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT, 0}, + {NULL, 0, 0} + }; + static const struct GNUNET_CORE_MessageHandler no_learn_handlers[] = { + {NULL, 0, 0} + }; + if ((!bootstrapping) && (!learning) +#if HAVE_MHD + && (!provide_hostlist) +#endif + ) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("None of the functions for the hostlist daemon were enabled. I have no reason to run!\n")); + return; + } + + + + stats = GNUNET_STATISTICS_create ("hostlist", cfg); + + core = + GNUNET_CORE_connect (cfg, 1, NULL, &core_init, &connect_handler, + &disconnect_handler, NULL, GNUNET_NO, NULL, + GNUNET_NO, + learning ? learn_handlers : no_learn_handlers); + + if (bootstrapping) + { + GNUNET_HOSTLIST_client_start (cfg, stats, &client_ch, &client_dh, + &client_adv_handler, learning); + } + +#if HAVE_MHD + if (provide_hostlist) + { + GNUNET_HOSTLIST_server_start (cfg, stats, core, &server_ch, &server_dh, + advertising); + } +#endif + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task, + NULL); + + if (NULL == core) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to connect to `%s' service.\n"), "core"); + GNUNET_SCHEDULER_shutdown (); + return; + } +} + + +/** + * The main function for the hostlist daemon. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { +#if HAVE_MHD + {'a', "advertise", NULL, + gettext_noop ("advertise our hostlist to other peers"), + GNUNET_NO, &GNUNET_GETOPT_set_one, &advertising}, +#endif + {'b', "bootstrap", NULL, + gettext_noop + ("bootstrap using hostlists (it is highly recommended that you always use this option)"), + GNUNET_NO, &GNUNET_GETOPT_set_one, &bootstrapping}, + {'e', "enable-learning", NULL, + gettext_noop ("enable learning about hostlist servers from other peers"), + GNUNET_NO, &GNUNET_GETOPT_set_one, &learning}, +#if HAVE_MHD + {'p', "provide-hostlist", NULL, + gettext_noop ("provide a hostlist server"), + GNUNET_NO, &GNUNET_GETOPT_set_one, &provide_hostlist}, +#endif + GNUNET_GETOPT_OPTION_END + }; + + int ret; + + GNUNET_log_setup ("hostlist", "WARNING", NULL); + ret = + (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "hostlist", + _("GNUnet hostlist server and client"), options, + &run, NULL)) ? 0 : 1; + + return ret; +} + +/* end of gnunet-daemon-hostlist.c */ diff --git a/src/hostlist/gnunet-daemon-hostlist.h b/src/hostlist/gnunet-daemon-hostlist.h new file mode 100644 index 0000000..8c9824e --- /dev/null +++ b/src/hostlist/gnunet-daemon-hostlist.h @@ -0,0 +1,47 @@ +/* + 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 hostlist/gnunet-daemon-hostlist.h + * @brief common internal definitions for hostlist daemon + * @author Matthias Wachs + */ +#include <stdlib.h> +#include "platform.h" +#include "hostlist-client.h" +#include "hostlist-server.h" +#include "gnunet_core_service.h" +#include "gnunet_getopt_lib.h" +#include "gnunet_protocols.h" +#include "gnunet_program_lib.h" +#include "gnunet_statistics_service.h" +#include "gnunet_strings_lib.h" +#include "gnunet_time_lib.h" +#include "gnunet_util_lib.h" + +/** + * General hostlist daemon debugging. + */ +#define DEBUG_HOSTLIST GNUNET_EXTRA_LOGGING + +#define MAX_URL_LEN 1000 +#define MAX_BYTES_PER_HOSTLISTS 500000 + +/* end of gnunet-daemon-hostlist.h */ diff --git a/src/hostlist/hostlist-client.c b/src/hostlist/hostlist-client.c new file mode 100644 index 0000000..350a0ba --- /dev/null +++ b/src/hostlist/hostlist-client.c @@ -0,0 +1,1568 @@ +/* + This file is part of GNUnet. + (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 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 hostlist/hostlist-client.c + * @brief hostlist support. Downloads HELLOs via HTTP. + * @author Christian Grothoff + * @author Matthias Wachs + */ + +#include "platform.h" +#include "hostlist-client.h" +#include "gnunet_core_service.h" +#include "gnunet_hello_lib.h" +#include "gnunet_statistics_service.h" +#include "gnunet_transport_service.h" +#include "gnunet-daemon-hostlist.h" +#include <curl/curl.h> +#include "gnunet_common.h" +#include "gnunet_bio_lib.h" + +#define DEBUG_HOSTLIST_CLIENT GNUNET_EXTRA_LOGGING + + +/** + * Number of connections that we must have to NOT download + * hostlists anymore. + */ +#define MIN_CONNECTIONS 4 + +/** + * Interval between two advertised hostlist tests + */ +#define TESTING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) + +/** + * A single hostlist obtained by hostlist advertisements + */ +struct Hostlist +{ + /** + * previous entry, used to manage entries in a double linked list + */ + struct Hostlist *prev; + + /** + * next entry, used to manage entries in a double linked list + */ + struct Hostlist *next; + + /** + * URI where hostlist can be obtained + */ + const char *hostlist_uri; + + /** + * Value describing the quality of the hostlist, the bigger the better but (should) never < 0 + * used for deciding which hostlist is replaced if MAX_NUMBER_HOSTLISTS in data structure is reached + * intial value = HOSTLIST_INITIAL + * increased every successful download by HOSTLIST_SUCCESSFULL_DOWNLOAD + * increased every successful download by number of obtained HELLO messages + * decreased every failed download by HOSTLIST_SUCCESSFULL_DOWNLOAD + */ + uint64_t quality; + + /** + * Time the hostlist advertisement was recieved and the entry was created + */ + struct GNUNET_TIME_Absolute time_creation; + + /** + * Last time the hostlist was obtained + */ + struct GNUNET_TIME_Absolute time_last_usage; + + /** + * Number of HELLO messages obtained during last download + */ + uint32_t hello_count; + + /** + * Number of times the hostlist was successfully obtained + */ + uint32_t times_used; + +}; + + +/** + * Our configuration. + */ +static const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * Statistics handle. + */ +static struct GNUNET_STATISTICS_Handle *stats; + +/** + * Transport handle. + */ +static struct GNUNET_TRANSPORT_Handle *transport; + +/** + * Proxy that we are using (can be NULL). + */ +static char *proxy; + +/** + * Number of bytes valid in 'download_buffer'. + */ +static size_t download_pos; + +/** + * Current URL that we are using. + */ +static char *current_url; + +/** + * Current CURL handle. + */ +static CURL *curl; + +/** + * Current multi-CURL handle. + */ +static CURLM *multi; + +/** + * How many bytes did we download from the current hostlist URL? + */ +static uint32_t stat_bytes_downloaded; + +/** + * Amount of time we wait between hostlist downloads. + */ +static struct GNUNET_TIME_Relative hostlist_delay; + +/** + * ID of the task, checking if hostlist download should take plate + */ +static GNUNET_SCHEDULER_TaskIdentifier ti_check_download; + +/** + * ID of the task downloading the hostlist + */ +static GNUNET_SCHEDULER_TaskIdentifier ti_download; + +/** + * ID of the task saving the hostlsit in a regular intervall + */ +static GNUNET_SCHEDULER_TaskIdentifier ti_saving_task; + +/** + * ID of the task called to initiate a download + */ +static GNUNET_SCHEDULER_TaskIdentifier ti_download_dispatcher_task; + +/** + * ID of the task controlling the locking between two hostlist tests + */ +static GNUNET_SCHEDULER_TaskIdentifier ti_testing_intervall_task; + +/** + * At what time MUST the current hostlist request be done? + */ +static struct GNUNET_TIME_Absolute end_time; + +/** + * Head of the linked list used to store hostlists + */ +static struct Hostlist *linked_list_head; + +/** + * Tail of the linked list used to store hostlists + */ +static struct Hostlist *linked_list_tail; + +/** + * Current hostlist used for downloading + */ +static struct Hostlist *current_hostlist; + +/** + * Size of the linke list used to store hostlists + */ +static unsigned int linked_list_size; + +/** + * Head of the linked list used to store hostlists + */ +static struct Hostlist *hostlist_to_test; + +/** + * Set to GNUNET_YES if the current URL had some problems. + */ +static int stat_bogus_url; + +/** + * Value controlling if a hostlist is tested at the moment + */ +static int stat_testing_hostlist; + +/** + * Value controlling if a hostlist testing is allowed at the moment + */ +static int stat_testing_allowed; + +/** + * Value controlling if a hostlist download is running at the moment + */ +static int stat_download_in_progress; + +/** + * Value saying if a preconfigured bootstrap server is used + */ +static unsigned int stat_use_bootstrap; + +/** + * Set if we are allowed to learn new hostlists and use them + */ +static int stat_learning; + +/** + * Value saying if hostlist download was successful + */ +static unsigned int stat_download_successful; + +/** + * Value saying how many valid HELLO messages were obtained during download + */ +static unsigned int stat_hellos_obtained; + +/** + * Number of active connections (according to core service). + */ +static unsigned int stat_connection_count; + + +/** + * Process downloaded bits by calling callback on each HELLO. + * + * @param ptr buffer with downloaded data + * @param size size of a record + * @param nmemb number of records downloaded + * @param ctx unused + * @return number of bytes that were processed (always size*nmemb) + */ +static size_t +callback_download (void *ptr, size_t size, size_t nmemb, void *ctx) +{ + static char download_buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; + const char *cbuf = ptr; + const struct GNUNET_MessageHeader *msg; + size_t total; + size_t cpy; + size_t left; + uint16_t msize; + + total = size * nmemb; + stat_bytes_downloaded += total; + if ((total == 0) || (stat_bogus_url)) + { + return total; /* ok, no data or bogus data */ + } + + GNUNET_STATISTICS_update (stats, + gettext_noop + ("# bytes downloaded from hostlist servers"), + (int64_t) total, GNUNET_NO); + left = total; + while ((left > 0) || (download_pos > 0)) + { + cpy = GNUNET_MIN (left, GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - download_pos); + memcpy (&download_buffer[download_pos], cbuf, cpy); + cbuf += cpy; + download_pos += cpy; + left -= cpy; + if (download_pos < sizeof (struct GNUNET_MessageHeader)) + { + GNUNET_assert (left == 0); + break; + } + msg = (const struct GNUNET_MessageHeader *) download_buffer; + msize = ntohs (msg->size); + if (msize < sizeof (struct GNUNET_MessageHeader)) + { + GNUNET_STATISTICS_update (stats, + gettext_noop + ("# invalid HELLOs downloaded from hostlist servers"), + 1, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Invalid `%s' message received from hostlist at `%s'\n"), + "HELLO", current_url); + stat_hellos_obtained++; + stat_bogus_url = 1; + return total; + } + if (download_pos < msize) + { + GNUNET_assert (left == 0); + break; + } + if (GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *) msg) == msize) + { +#if DEBUG_HOSTLIST_CLIENT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received valid `%s' message from hostlist server.\n", + "HELLO"); +#endif + GNUNET_STATISTICS_update (stats, + gettext_noop + ("# valid HELLOs downloaded from hostlist servers"), + 1, GNUNET_NO); + stat_hellos_obtained++; + GNUNET_TRANSPORT_offer_hello (transport, msg, NULL, NULL); + } + else + { + GNUNET_STATISTICS_update (stats, + gettext_noop + ("# invalid HELLOs downloaded from hostlist servers"), + 1, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Invalid `%s' message received from hostlist at `%s'\n"), + "HELLO", current_url); + stat_bogus_url = GNUNET_YES; + stat_hellos_obtained++; + return total; + } + memmove (download_buffer, &download_buffer[msize], download_pos - msize); + download_pos -= msize; + } + return total; +} + + +/** + * Obtain a hostlist URL that we should use. + * + * @return NULL if there is no URL available + */ +static char * +get_bootstrap_server () +{ + char *servers; + char *ret; + size_t urls; + size_t pos; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "SERVERS", + &servers)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("No `%s' specified in `%s' configuration, will not bootstrap.\n"), + "SERVERS", "HOSTLIST"); + return NULL; + } + + urls = 0; + if (strlen (servers) > 0) + { + urls++; + pos = strlen (servers) - 1; + while (pos > 0) + { + if (servers[pos] == ' ') + urls++; + pos--; + } + } + if (urls == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("No `%s' specified in `%s' configuration, will not bootstrap.\n"), + "SERVERS", "HOSTLIST"); + GNUNET_free (servers); + return NULL; + } + + urls = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, urls) + 1; + pos = strlen (servers) - 1; + while (pos > 0) + { + if (servers[pos] == ' ') + { + urls--; + servers[pos] = '\0'; + } + if (urls == 0) + { + pos++; + break; + } + pos--; + } + ret = GNUNET_strdup (&servers[pos]); + GNUNET_free (servers); + return ret; +} + +/** + * Method deciding if a preconfigured or advertisied hostlist is used on a 50:50 ratio + * @return uri to use, NULL if there is no URL available + */ +static char * +download_get_url () +{ + uint32_t index; + unsigned int counter; + struct Hostlist *pos; + + if (GNUNET_NO == stat_learning) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Using preconfigured bootstrap server\n"); + current_hostlist = NULL; + return get_bootstrap_server (); + } + + if ((GNUNET_YES == stat_testing_hostlist) && (NULL != hostlist_to_test)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Testing new advertised hostlist if it is obtainable\n"); + current_hostlist = hostlist_to_test; + return GNUNET_strdup (hostlist_to_test->hostlist_uri); + } + + if ((GNUNET_YES == stat_use_bootstrap) || (linked_list_size == 0)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Using preconfigured bootstrap server\n"); + current_hostlist = NULL; + return get_bootstrap_server (); + } + index = + GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, linked_list_size); + counter = 0; + pos = linked_list_head; + while (counter < index) + { + pos = pos->next; + counter++; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using learned hostlist `%s'\n", + pos->hostlist_uri); + current_hostlist = pos; + return GNUNET_strdup (pos->hostlist_uri); +} + + +#define CURL_EASY_SETOPT(c, a, b) do { ret = curl_easy_setopt(c, a, b); if (ret != CURLE_OK) GNUNET_log(GNUNET_ERROR_TYPE_WARNING, _("%s failed at %s:%d: `%s'\n"), "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret)); } while (0) + + +/** + * Method to save hostlist to a file during hostlist client shutdown + * @param shutdown set if called because of shutdown, entries in linked list will be destroyed + */ +static void +save_hostlist_file (int shutdown); + + +/** + * add val2 to val1 with overflow check + * @param val1 value 1 + * @param val2 value 2 + * @return result + */ +static uint64_t +checked_add (uint64_t val1, uint64_t val2) +{ + static uint64_t temp; + static uint64_t maxv; + + maxv = 0; + maxv--; + + temp = val1 + val2; + if (temp < val1) + return maxv; + else + return temp; +} + +/** + * Subtract val2 from val1 with underflow check + * @param val1 value 1 + * @param val2 value 2 + * @return result + */ +static uint64_t +checked_sub (uint64_t val1, uint64_t val2) +{ + if (val1 <= val2) + return 0; + else + return (val1 - val2); +} + +/** + * Method to check if a URI is in hostlist linked list + * @param uri uri to check + * @return GNUNET_YES if existing in linked list, GNUNET_NO if not + */ +static int +linked_list_contains (const char *uri) +{ + struct Hostlist *pos; + + pos = linked_list_head; + while (pos != NULL) + { + if (0 == strcmp (pos->hostlist_uri, uri)) + return GNUNET_YES; + pos = pos->next; + } + return GNUNET_NO; +} + + +/** + * Method returning the hostlist element with the lowest quality in the datastore + * @return hostlist with lowest quality + */ +static struct Hostlist * +linked_list_get_lowest_quality () +{ + struct Hostlist *pos; + struct Hostlist *lowest; + + if (linked_list_size == 0) + return NULL; + lowest = linked_list_head; + pos = linked_list_head->next; + while (pos != NULL) + { + if (pos->quality < lowest->quality) + lowest = pos; + pos = pos->next; + } + return lowest; +} + + +/** + * Method to insert a hostlist into the datastore. If datastore + * contains maximum number of elements, the elements with lowest + * quality is dismissed + */ +static void +insert_hostlist () +{ + struct Hostlist *lowest_quality; + + if (MAX_NUMBER_HOSTLISTS <= linked_list_size) + { + /* No free entries available, replace existing entry */ + lowest_quality = linked_list_get_lowest_quality (); + GNUNET_assert (lowest_quality != NULL); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Removing hostlist with URI `%s' which has the worst quality of all (%llu)\n", + lowest_quality->hostlist_uri, + (unsigned long long) lowest_quality->quality); + GNUNET_CONTAINER_DLL_remove (linked_list_head, linked_list_tail, + lowest_quality); + linked_list_size--; + GNUNET_free (lowest_quality); + } + GNUNET_CONTAINER_DLL_insert (linked_list_head, linked_list_tail, + hostlist_to_test); + linked_list_size++; + GNUNET_STATISTICS_set (stats, gettext_noop ("# advertised hostlist URIs"), + linked_list_size, GNUNET_NO); + stat_testing_hostlist = GNUNET_NO; +} + + +/** + * Method updating hostlist statistics + */ +static void +update_hostlist () +{ + char *stat; + + if (((stat_use_bootstrap == GNUNET_NO) && (NULL != current_hostlist)) || + ((stat_testing_hostlist == GNUNET_YES) && (NULL != current_hostlist))) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Updating hostlist statics for URI `%s'\n", + current_hostlist->hostlist_uri); + current_hostlist->hello_count = stat_hellos_obtained; + current_hostlist->time_last_usage = GNUNET_TIME_absolute_get (); + current_hostlist->quality = + checked_add (current_hostlist->quality, + (stat_hellos_obtained * HOSTLIST_SUCCESSFUL_HELLO)); + if (GNUNET_YES == stat_download_successful) + { + current_hostlist->times_used++; + current_hostlist->quality = + checked_add (current_hostlist->quality, HOSTLIST_SUCCESSFUL_DOWNLOAD); + GNUNET_asprintf (&stat, gettext_noop ("# advertised URI `%s' downloaded"), + current_hostlist->hostlist_uri); + + GNUNET_STATISTICS_update (stats, stat, 1, GNUNET_YES); + GNUNET_free (stat); + } + else + current_hostlist->quality = + checked_sub (current_hostlist->quality, HOSTLIST_FAILED_DOWNLOAD); + } + current_hostlist = NULL; + /* Alternating the usage of preconfigured and learned hostlists */ + + if (stat_testing_hostlist == GNUNET_YES) + return; + + if (GNUNET_YES == stat_learning) + { + if (stat_use_bootstrap == GNUNET_YES) + stat_use_bootstrap = GNUNET_NO; + else + stat_use_bootstrap = GNUNET_YES; + } + else + stat_use_bootstrap = GNUNET_YES; +} + +/** + * Clean up the state from the task that downloaded the + * hostlist and schedule the next task. + */ +static void +clean_up () +{ + CURLMcode mret; + + if ((stat_testing_hostlist == GNUNET_YES) && + (GNUNET_NO == stat_download_successful) && (NULL != hostlist_to_test)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _ + ("Advertised hostlist with URI `%s' could not be downloaded. Advertised URI gets dismissed.\n"), + hostlist_to_test->hostlist_uri); + } + + if (stat_testing_hostlist == GNUNET_YES) + { + stat_testing_hostlist = GNUNET_NO; + } + if (NULL != hostlist_to_test) + { + GNUNET_free (hostlist_to_test); + hostlist_to_test = NULL; + } + + if (multi != NULL) + { + mret = curl_multi_remove_handle (multi, curl); + if (mret != CURLM_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), + "curl_multi_remove_handle", __FILE__, __LINE__, + curl_multi_strerror (mret)); + } + mret = curl_multi_cleanup (multi); + if (mret != CURLM_OK) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), + "curl_multi_cleanup", __FILE__, __LINE__, + curl_multi_strerror (mret)); + multi = NULL; + } + if (curl != NULL) + { + curl_easy_cleanup (curl); + curl = NULL; + } + GNUNET_free_non_null (current_url); + current_url = NULL; + stat_bytes_downloaded = 0; + stat_download_in_progress = GNUNET_NO; +} + + +/** + * Task that is run when we are ready to receive more data from the hostlist + * server. + * + * @param cls closure, unused + * @param tc task context, unused + */ +static void +task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); + + +/** + * Ask CURL for the select set and then schedule the + * receiving task with the scheduler. + */ +static void +download_prepare () +{ + CURLMcode mret; + fd_set rs; + fd_set ws; + fd_set es; + int max; + struct GNUNET_NETWORK_FDSet *grs; + struct GNUNET_NETWORK_FDSet *gws; + long timeout; + struct GNUNET_TIME_Relative rtime; + + max = -1; + FD_ZERO (&rs); + FD_ZERO (&ws); + FD_ZERO (&es); + mret = curl_multi_fdset (multi, &rs, &ws, &es, &max); + if (mret != CURLM_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), + "curl_multi_fdset", __FILE__, __LINE__, + curl_multi_strerror (mret)); + clean_up (); + return; + } + mret = curl_multi_timeout (multi, &timeout); + if (mret != CURLM_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), + "curl_multi_timeout", __FILE__, __LINE__, + curl_multi_strerror (mret)); + clean_up (); + return; + } + rtime = + GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining (end_time), + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_MILLISECONDS, timeout)); + grs = GNUNET_NETWORK_fdset_create (); + gws = GNUNET_NETWORK_fdset_create (); + GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); + GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); +#if DEBUG_HOSTLIST_CLIENT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Scheduling task for hostlist download using cURL\n"); +#endif + ti_download = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, + GNUNET_SCHEDULER_NO_TASK, rtime, grs, gws, + &task_download, multi); + GNUNET_NETWORK_fdset_destroy (gws); + GNUNET_NETWORK_fdset_destroy (grs); +} + + +/** + * Task that is run when we are ready to receive more data from the hostlist + * server. + * + * @param cls closure, unused + * @param tc task context, unused + */ +static void +task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + int running; + struct CURLMsg *msg; + CURLMcode mret; + + ti_download = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + { +#if DEBUG_HOSTLIST_CLIENT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Shutdown requested while trying to download hostlist from `%s'\n", + current_url); +#endif + update_hostlist (); + clean_up (); + return; + } + if (GNUNET_TIME_absolute_get_remaining (end_time).rel_value == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Timeout trying to download hostlist from `%s'\n"), + current_url); + update_hostlist (); + clean_up (); + return; + } +#if DEBUG_HOSTLIST_CLIENT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Ready for processing hostlist client request\n"); +#endif + + do + { + running = 0; + if (stat_bytes_downloaded > MAX_BYTES_PER_HOSTLISTS) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Download limit of %u bytes exceeded, stopping download\n"), + MAX_BYTES_PER_HOSTLISTS); + clean_up (); + return; + } + mret = curl_multi_perform (multi, &running); + if (running == 0) + { + do + { + msg = curl_multi_info_read (multi, &running); + GNUNET_break (msg != NULL); + if (msg == NULL) + break; + switch (msg->msg) + { + case CURLMSG_DONE: + if ((msg->data.result != CURLE_OK) && + (msg->data.result != CURLE_GOT_NOTHING)) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("%s failed for `%s' at %s:%d: `%s'\n"), + "curl_multi_perform", current_url, __FILE__, __LINE__, + curl_easy_strerror (msg->data.result)); + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Download of hostlist `%s' completed.\n"), + current_url); + stat_download_successful = GNUNET_YES; + update_hostlist (); + if (GNUNET_YES == stat_testing_hostlist) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _ + ("Adding successfully tested hostlist `%s' datastore.\n"), + current_url); + insert_hostlist (); + hostlist_to_test = NULL; + stat_testing_hostlist = GNUNET_NO; + } + } + clean_up (); + return; + default: + break; + } + + } + while ((running > 0)); + } + } + while (mret == CURLM_CALL_MULTI_PERFORM); + + if (mret != CURLM_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("%s failed at %s:%d: `%s'\n"), + "curl_multi_perform", __FILE__, __LINE__, + curl_multi_strerror (mret)); + clean_up (); + } + download_prepare (); +} + + +/** + * Main function that will download a hostlist and process its + * data. + */ +static void +download_hostlist () +{ + CURLcode ret; + CURLMcode mret; + + + current_url = download_get_url (); + if (current_url == NULL) + return; + curl = curl_easy_init (); + multi = NULL; + if (curl == NULL) + { + GNUNET_break (0); + clean_up (); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, + _("Bootstrapping using hostlist at `%s'.\n"), current_url); + + stat_download_in_progress = GNUNET_YES; + stat_download_successful = GNUNET_NO; + stat_hellos_obtained = 0; + stat_bytes_downloaded = 0; + + GNUNET_STATISTICS_update (stats, + gettext_noop ("# hostlist downloads initiated"), 1, + GNUNET_NO); + if (proxy != NULL) + CURL_EASY_SETOPT (curl, CURLOPT_PROXY, proxy); + download_pos = 0; + stat_bogus_url = 0; + CURL_EASY_SETOPT (curl, CURLOPT_WRITEFUNCTION, &callback_download); + if (ret != CURLE_OK) + { + clean_up (); + return; + } + CURL_EASY_SETOPT (curl, CURLOPT_WRITEDATA, NULL); + if (ret != CURLE_OK) + { + clean_up (); + return; + } + CURL_EASY_SETOPT (curl, CURLOPT_FOLLOWLOCATION, 1); + CURL_EASY_SETOPT (curl, CURLOPT_MAXREDIRS, 4); + /* no need to abort if the above failed */ + CURL_EASY_SETOPT (curl, CURLOPT_URL, current_url); + if (ret != CURLE_OK) + { + clean_up (); + return; + } + CURL_EASY_SETOPT (curl, CURLOPT_FAILONERROR, 1); +#if 0 + CURL_EASY_SETOPT (curl, CURLOPT_VERBOSE, 1); +#endif + CURL_EASY_SETOPT (curl, CURLOPT_BUFFERSIZE, GNUNET_SERVER_MAX_MESSAGE_SIZE); + if (0 == strncmp (current_url, "http", 4)) + CURL_EASY_SETOPT (curl, CURLOPT_USERAGENT, "GNUnet"); + CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 60L); + CURL_EASY_SETOPT (curl, CURLOPT_TIMEOUT, 60L); +#if 0 + /* this should no longer be needed; we're now single-threaded! */ + CURL_EASY_SETOPT (curl, CURLOPT_NOSIGNAL, 1); +#endif + multi = curl_multi_init (); + if (multi == NULL) + { + GNUNET_break (0); + /* clean_up (); */ + return; + } + mret = curl_multi_add_handle (multi, curl); + if (mret != CURLM_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), + "curl_multi_add_handle", __FILE__, __LINE__, + curl_multi_strerror (mret)); + mret = curl_multi_cleanup (multi); + if (mret != CURLM_OK) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), + "curl_multi_cleanup", __FILE__, __LINE__, + curl_multi_strerror (mret)); + multi = NULL; + clean_up (); + return; + } + end_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES); + download_prepare (); +} + + +static void +task_download_dispatcher (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + ti_download_dispatcher_task = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download is initiated...\n"); + if (GNUNET_NO == stat_download_in_progress) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download can start immediately...\n"); + download_hostlist (); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Download in progess, have to wait...\n"); + ti_download_dispatcher_task = + GNUNET_SCHEDULER_add_delayed (WAITING_INTERVALL, + &task_download_dispatcher, NULL); + } +} + +/** + * Task that checks if we should try to download a hostlist. + * If so, we initiate the download, otherwise we schedule + * this task again for a later time. + */ +static void +task_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + static int once; + struct GNUNET_TIME_Relative delay; + + ti_check_download = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + + if (stat_connection_count < MIN_CONNECTIONS) + { + ti_download_dispatcher_task = + GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL); + } + + if (stats == NULL) + { + curl_global_cleanup (); + return; /* in shutdown */ + } + delay = hostlist_delay; + if (hostlist_delay.rel_value == 0) + hostlist_delay = GNUNET_TIME_UNIT_SECONDS; + else + hostlist_delay = GNUNET_TIME_relative_multiply (hostlist_delay, 2); + if (hostlist_delay.rel_value > + GNUNET_TIME_UNIT_HOURS.rel_value * (1 + stat_connection_count)) + hostlist_delay = + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, + (1 + stat_connection_count)); + GNUNET_STATISTICS_set (stats, + gettext_noop + ("# milliseconds between hostlist downloads"), + hostlist_delay.rel_value, GNUNET_YES); + if (0 == once) + { + delay = GNUNET_TIME_UNIT_ZERO; + once = 1; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _ + ("Have %u/%u connections. Will consider downloading hostlist in %llums\n"), + stat_connection_count, MIN_CONNECTIONS, + (unsigned long long) delay.rel_value); + ti_check_download = GNUNET_SCHEDULER_add_delayed (delay, &task_check, NULL); +} + + +/** + * This tasks sets hostlist testing to allowed after intervall between to testings is reached + * + * @param cls closure + * @param tc TaskContext + */ +static void +task_testing_intervall_reset (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + ti_testing_intervall_task = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + stat_testing_allowed = GNUNET_OK; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Testing new hostlist advertisements is allowed again\n"); +} + + +/** + * Task that writes hostlist entries to a file on a regular base + * + * @param cls closure + * @param tc TaskContext + */ +static void +task_hostlist_saving (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + ti_saving_task = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Scheduled saving of hostlists\n")); + save_hostlist_file (GNUNET_NO); + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Hostlists will be saved to file again in %llums\n"), + (unsigned long long) SAVING_INTERVALL.rel_value); + ti_saving_task = + GNUNET_SCHEDULER_add_delayed (SAVING_INTERVALL, &task_hostlist_saving, + NULL); +} + + +/** + * Method called whenever a given peer connects. + * + * @param cls closure + * @param peer peer identity this notification is about + * @param atsi performance data + * @param atsi_count number of records in 'atsi' + */ +static void +handler_connect (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *atsi, + unsigned int atsi_count) +{ + GNUNET_assert (stat_connection_count < UINT_MAX); + stat_connection_count++; + GNUNET_STATISTICS_update (stats, gettext_noop ("# active connections"), 1, + GNUNET_NO); +} + + +/** + * Method called whenever a given peer disconnects. + * + * @param cls closure + * @param peer peer identity this notification is about + */ +static void +handler_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer) +{ + GNUNET_assert (stat_connection_count > 0); + stat_connection_count--; + GNUNET_STATISTICS_update (stats, gettext_noop ("# active connections"), -1, + GNUNET_NO); +} + + +/** + * Method called whenever an advertisement message arrives. + * + * @param cls closure (always NULL) + * @param peer the peer sending the message + * @param message the actual message + * @param atsi performance data + * @param atsi_count number of records in 'atsi' + * @return GNUNET_OK to keep the connection open, + * GNUNET_SYSERR to close it (signal serious error) + */ +static int +handler_advertisement (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information *atsi, + unsigned int atsi_count) +{ + size_t size; + size_t uri_size; + const struct GNUNET_MessageHeader *incoming; + const char *uri; + struct Hostlist *hostlist; + + GNUNET_assert (ntohs (message->type) == + GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); + size = ntohs (message->size); + if (size <= sizeof (struct GNUNET_MessageHeader)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + incoming = (const struct GNUNET_MessageHeader *) message; + uri = (const char *) &incoming[1]; + uri_size = size - sizeof (struct GNUNET_MessageHeader); + if (uri[uri_size - 1] != '\0') + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Hostlist client recieved advertisement from `%s' containing URI `%s'\n", + GNUNET_i2s (peer), uri); + if (GNUNET_NO != linked_list_contains (uri)) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "URI `%s' is already known\n", uri); + return GNUNET_OK; + } + + if (GNUNET_NO == stat_testing_allowed) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Currently not accepting new advertisements: interval between to advertisements is not reached\n"); + return GNUNET_SYSERR; + } + if (GNUNET_YES == stat_testing_hostlist) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Currently not accepting new advertisements: we are already testing a hostlist\n"); + return GNUNET_SYSERR; + } + + hostlist = GNUNET_malloc (sizeof (struct Hostlist) + uri_size); + hostlist->hostlist_uri = (const char *) &hostlist[1]; + memcpy (&hostlist[1], uri, uri_size); + hostlist->time_creation = GNUNET_TIME_absolute_get (); + hostlist->time_last_usage = GNUNET_TIME_absolute_get_zero (); + hostlist->quality = HOSTLIST_INITIAL; + hostlist_to_test = hostlist; + + stat_testing_hostlist = GNUNET_YES; + stat_testing_allowed = GNUNET_NO; + ti_testing_intervall_task = + GNUNET_SCHEDULER_add_delayed (TESTING_INTERVAL, + &task_testing_intervall_reset, NULL); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Testing new hostlist advertisements is locked for the next %u ms\n", + TESTING_INTERVAL.rel_value); + + ti_download_dispatcher_task = + GNUNET_SCHEDULER_add_now (&task_download_dispatcher, NULL); + + return GNUNET_OK; +} + + + +/** + * Continuation called by the statistics code once + * we go the stat. Initiates hostlist download scheduling. + * + * @param cls closure + * @param success GNUNET_OK if statistics were + * successfully obtained, GNUNET_SYSERR if not. + */ +static void +primary_task (void *cls, int success) +{ + if (stats == NULL) + return; /* in shutdown */ +#if DEBUG_HOSTLIST_CLIENT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Statistics request done, scheduling hostlist download\n"); +#endif + ti_check_download = GNUNET_SCHEDULER_add_now (&task_check, NULL); +} + + +static int +process_stat (void *cls, const char *subsystem, const char *name, + uint64_t value, int is_persistent) +{ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Initial time between hostlist downloads is %llums\n"), + (unsigned long long) value); + hostlist_delay.rel_value = value; + return GNUNET_OK; +} + +/** + * Method to load persistent hostlist file during hostlist client startup + */ +static void +load_hostlist_file () +{ + char *filename; + char *uri; + char *emsg; + struct Hostlist *hostlist; + + uri = NULL; + uint32_t times_used; + uint32_t hellos_returned; + uint64_t quality; + uint64_t last_used; + uint64_t created; + uint32_t counter; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", "HOSTLISTFILE", + &filename)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("No `%s' specified in `%s' configuration, cannot load hostlists from file.\n"), + "HOSTLISTFILE", "HOSTLIST"); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Loading saved hostlist entries from file `%s' \n"), filename); + if (GNUNET_NO == GNUNET_DISK_file_test (filename)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Hostlist file `%s' is not existing\n"), filename); + GNUNET_free (filename); + return; + } + + struct GNUNET_BIO_ReadHandle *rh = GNUNET_BIO_read_open (filename); + + if (NULL == rh) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _ + ("Could not open file `%s' for reading to load hostlists: %s\n"), + filename, STRERROR (errno)); + GNUNET_free (filename); + return; + } + + counter = 0; + while ((GNUNET_OK == GNUNET_BIO_read_string (rh, "url", &uri, MAX_URL_LEN)) && + (NULL != uri) && (GNUNET_OK == GNUNET_BIO_read_int32 (rh, ×_used)) + && (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &quality)) && + (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &last_used)) && + (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &created)) && + (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &hellos_returned))) + { + hostlist = GNUNET_malloc (sizeof (struct Hostlist) + strlen (uri) + 1); + hostlist->hello_count = hellos_returned; + hostlist->hostlist_uri = (const char *) &hostlist[1]; + memcpy (&hostlist[1], uri, strlen (uri) + 1); + hostlist->quality = quality; + hostlist->time_creation.abs_value = created; + hostlist->time_last_usage.abs_value = last_used; + GNUNET_CONTAINER_DLL_insert (linked_list_head, linked_list_tail, hostlist); + linked_list_size++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Added hostlist entry eith URI `%s' \n", + hostlist->hostlist_uri); + GNUNET_free (uri); + uri = NULL; + counter++; + if (counter >= MAX_NUMBER_HOSTLISTS) + break; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("%u hostlist URIs loaded from file\n"), + counter); + GNUNET_STATISTICS_set (stats, gettext_noop ("# hostlist URIs read from file"), + counter, GNUNET_YES); + GNUNET_STATISTICS_set (stats, gettext_noop ("# advertised hostlist URIs"), + linked_list_size, GNUNET_NO); + + GNUNET_free_non_null (uri); + emsg = NULL; + GNUNET_BIO_read_close (rh, &emsg); + if (emsg != NULL) + GNUNET_free (emsg); + GNUNET_free (filename); +} + + +/** + * Method to save persistent hostlist file during hostlist client shutdown + * @param shutdown set if called because of shutdown, entries in linked list will be destroyed + */ +static void +save_hostlist_file (int shutdown) +{ + char *filename; + struct Hostlist *pos; + struct GNUNET_BIO_WriteHandle *wh; + int ok; + uint32_t counter; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", "HOSTLISTFILE", + &filename)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("No `%s' specified in `%s' configuration, cannot save hostlists to file.\n"), + "HOSTLISTFILE", "HOSTLIST"); + return; + } + if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename)) + { + GNUNET_free (filename); + return; + } + wh = GNUNET_BIO_write_open (filename); + if (NULL == wh) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("Could not open file `%s' for writing to save hostlists: %s\n"), + filename, STRERROR (errno)); + GNUNET_free (filename); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Writing %u hostlist URIs to `%s'\n"), + linked_list_size, filename); + /* add code to write hostlists to file using bio */ + ok = GNUNET_YES; + counter = 0; + while (NULL != (pos = linked_list_head)) + { + if (GNUNET_YES == shutdown) + { + GNUNET_CONTAINER_DLL_remove (linked_list_head, linked_list_tail, pos); + linked_list_size--; + } + if (GNUNET_YES == ok) + { + if ((GNUNET_OK != GNUNET_BIO_write_string (wh, pos->hostlist_uri)) || + (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pos->times_used)) || + (GNUNET_OK != GNUNET_BIO_write_int64 (wh, pos->quality)) || + (GNUNET_OK != + GNUNET_BIO_write_int64 (wh, pos->time_last_usage.abs_value)) || + (GNUNET_OK != + GNUNET_BIO_write_int64 (wh, pos->time_creation.abs_value)) || + (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pos->hello_count))) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Error writing hostlist URIs to file `%s'\n"), filename); + ok = GNUNET_NO; + } + } + + if (GNUNET_YES == shutdown) + GNUNET_free (pos); + counter++; + if (counter >= MAX_NUMBER_HOSTLISTS) + break; + } + GNUNET_STATISTICS_set (stats, + gettext_noop ("# hostlist URIs written to file"), + counter, GNUNET_YES); + + if (GNUNET_OK != GNUNET_BIO_write_close (wh)) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Error writing hostlist URIs to file `%s'\n"), filename); + GNUNET_free (filename); +} + +/** + * Start downloading hostlists from hostlist servers as necessary. + */ +int +GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_STATISTICS_Handle *st, + GNUNET_CORE_ConnectEventHandler *ch, + GNUNET_CORE_DisconnectEventHandler *dh, + GNUNET_CORE_MessageCallback *msgh, int learn) +{ + char *filename; + int result; + + if (0 != curl_global_init (CURL_GLOBAL_WIN32)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + transport = GNUNET_TRANSPORT_connect (c, NULL, NULL, NULL, NULL, NULL); + if (NULL == transport) + { + curl_global_cleanup (); + return GNUNET_SYSERR; + } + cfg = c; + stats = st; + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "HTTP-PROXY", + &proxy)) + proxy = NULL; + stat_learning = learn; + *ch = &handler_connect; + *dh = &handler_disconnect; + linked_list_head = NULL; + linked_list_tail = NULL; + stat_use_bootstrap = GNUNET_YES; + stat_testing_hostlist = GNUNET_NO; + stat_testing_allowed = GNUNET_YES; + + if (GNUNET_YES == stat_learning) + { + *msgh = &handler_advertisement; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Learning is enabled on this peer\n")); + load_hostlist_file (); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Hostlists will be saved to file again in %llums\n"), + (unsigned long long) SAVING_INTERVALL.rel_value); + ti_saving_task = + GNUNET_SCHEDULER_add_delayed (SAVING_INTERVALL, &task_hostlist_saving, + NULL); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Learning is not enabled on this peer\n")); + *msgh = NULL; + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", + "HOSTLISTFILE", &filename)) + { + if (GNUNET_YES == GNUNET_DISK_file_test (filename)) + { + result = remove (filename); + if (result == 0) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _ + ("Since learning is not enabled on this peer, hostlist file `%s' was removed\n"), + filename); + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Hostlist file `%s' could not be removed\n"), filename); + } + } + GNUNET_free (filename); + } + GNUNET_STATISTICS_get (stats, "hostlist", + gettext_noop + ("# milliseconds between hostlist downloads"), + GNUNET_TIME_UNIT_MINUTES, &primary_task, &process_stat, + NULL); + return GNUNET_OK; +} + + +/** + * Stop downloading hostlists from hostlist servers as necessary. + */ +void +GNUNET_HOSTLIST_client_stop () +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist client shutdown\n"); +#if DEBUG_HOSTLIST_CLIENT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist client shutdown\n"); +#endif + if (GNUNET_YES == stat_learning) + save_hostlist_file (GNUNET_YES); + + if (ti_saving_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (ti_saving_task); + } + + if (ti_download_dispatcher_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (ti_download_dispatcher_task); + } + if (ti_testing_intervall_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (ti_testing_intervall_task); + } + if (ti_download != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (ti_download); + } + if (ti_check_download != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (ti_check_download); + curl_global_cleanup (); + } + if (transport != NULL) + { + GNUNET_TRANSPORT_disconnect (transport); + transport = NULL; + } + GNUNET_assert (NULL == transport); + GNUNET_free_non_null (proxy); + proxy = NULL; + cfg = NULL; +} + +/* end of hostlist-client.c */ diff --git a/src/hostlist/hostlist-client.h b/src/hostlist/hostlist-client.h new file mode 100644 index 0000000..3def865 --- /dev/null +++ b/src/hostlist/hostlist-client.h @@ -0,0 +1,108 @@ +/* + 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 hostlist/hostlist-client.h + * @brief hostlist support. Downloads HELLOs via HTTP. + * @author Christian Grothoff + */ + +#ifndef HOSTLIST_CLIENT_H +#define HOSTLIST_CLIENT_H + +#include "gnunet_core_service.h" +#include "gnunet_statistics_service.h" +#include "gnunet_util_lib.h" +#include "gnunet_time_lib.h" + +/** + * Maximum number of hostlist that are saved + */ +#define MAX_NUMBER_HOSTLISTS 30 + +/** + * Time intervall hostlists are saved to disk + */ +#define SAVING_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30) + +/** + * Time interval between two hostlist tests + */ +#define TESTING_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3) + +/** + * Time interval for download dispatcher before a download is re-scheduled + */ +#define WAITING_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) + +/** + * Defines concerning the hostlist quality metric + */ + +/** + * Initial quality of a new created hostlist + */ +#define HOSTLIST_INITIAL 10000 + +/** + * Value subtracted each time a hostlist download fails + */ +#define HOSTLIST_FAILED_DOWNLOAD 100 + +/** + * Value added each time a hostlist download is successful + */ +#define HOSTLIST_SUCCESSFUL_DOWNLOAD 100 + +/** + * Value added for each valid HELLO recived during a hostlist download + */ +#define HOSTLIST_SUCCESSFUL_HELLO 1 + + + +/** + * Start downloading hostlists from hostlist servers as necessary. + * + * @param c the configuration to use + * @param st hande for publishing statistics + * @param ch set to handler for connect notifications + * @param dh set to handler for disconnect notifications + * @param msgh set to handler for message handler notifications + * @param learn set if client is learning new hostlists + * @return GNUNET_OK on success + */ +int +GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_STATISTICS_Handle *st, + GNUNET_CORE_ConnectEventHandler *ch, + GNUNET_CORE_DisconnectEventHandler *dh, + GNUNET_CORE_MessageCallback *msgh, int learn); + + +/** + * Stop downloading hostlists from hostlist servers as necessary. + */ +void +GNUNET_HOSTLIST_client_stop (void); + + +#endif +/* end of hostlist-client.h */ diff --git a/src/hostlist/hostlist-server.c b/src/hostlist/hostlist-server.c new file mode 100644 index 0000000..8e79ace --- /dev/null +++ b/src/hostlist/hostlist-server.c @@ -0,0 +1,700 @@ +/* + This file is part of GNUnet. + (C) 2008, 2009, 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 hostlist/hostlist-server.c + * @author Christian Grothoff, Matthias Wachs + * @brief application to provide an integrated hostlist HTTP server + */ + +#include "platform.h" +#include <microhttpd.h> +#include "hostlist-server.h" +#include "gnunet_hello_lib.h" +#include "gnunet_peerinfo_service.h" +#include "gnunet-daemon-hostlist.h" +#include "gnunet_resolver_service.h" + +#define DEBUG_HOSTLIST_SERVER GNUNET_EXTRA_LOGGING + +/** + * Handle to the HTTP server as provided by libmicrohttpd for IPv6. + */ +static struct MHD_Daemon *daemon_handle_v6; + +/** + * Handle to the HTTP server as provided by libmicrohttpd for IPv4. + */ +static struct MHD_Daemon *daemon_handle_v4; + +/** + * Our configuration. + */ +static const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * For keeping statistics. + */ +static struct GNUNET_STATISTICS_Handle *stats; + +/** + * Handle to the core service (NULL until we've connected to it). + */ +static struct GNUNET_CORE_Handle *core; + +/** + * Handle to the peerinfo notify service (NULL until we've connected to it). + */ +static struct GNUNET_PEERINFO_NotifyContext *notify; + +/** + * Our primary task for IPv4. + */ +static GNUNET_SCHEDULER_TaskIdentifier hostlist_task_v4; + +/** + * Our primary task for IPv6. + */ +static GNUNET_SCHEDULER_TaskIdentifier hostlist_task_v6; + +/** + * Our canonical response. + */ +static struct MHD_Response *response; + +/** + * NULL if we are not currenlty iterating over peer information. + */ +static struct GNUNET_PEERINFO_IteratorContext *pitr; + +/** + * Handle for accessing peerinfo service. + */ +static struct GNUNET_PEERINFO_Handle *peerinfo; + +/** + * Context for host processor. + */ +struct HostSet +{ + unsigned int size; + + char *data; +}; + +/** + * Set if we are allowed to advertise our hostlist to others. + */ +static int advertising; + +/** + * Buffer for the hostlist address + */ +static char *hostlist_uri; + + +/** + * Function that assembles our response. + */ +static void +finish_response (struct HostSet *results) +{ + if (response != NULL) + MHD_destroy_response (response); +#if DEBUG_HOSTLIST_SERVER + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Creating hostlist response with %u bytes\n", + (unsigned int) results->size); +#endif + response = + MHD_create_response_from_data (results->size, results->data, MHD_YES, + MHD_NO); + if ((daemon_handle_v4 == NULL) && (daemon_handle_v6 == NULL)) + { + MHD_destroy_response (response); + response = NULL; + } + GNUNET_STATISTICS_set (stats, gettext_noop ("bytes in hostlist"), + results->size, GNUNET_YES); + GNUNET_free (results); +} + + +/** + * Set 'cls' to GNUNET_YES (we have an address!). + * + * @param cls closure, an 'int*' + * @param address the address (ignored) + * @param expiration expiration time (call is ignored if this is in the past) + * @return GNUNET_SYSERR to stop iterating (unless expiration has occured) + */ +static int +check_has_addr (void *cls, const struct GNUNET_HELLO_Address *address, + struct GNUNET_TIME_Absolute expiration) +{ + int *arg = cls; + + if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value == 0) + { + GNUNET_STATISTICS_update (stats, + gettext_noop ("expired addresses encountered"), 1, + GNUNET_YES); + return GNUNET_YES; /* ignore this address */ + } + *arg = GNUNET_YES; + return GNUNET_SYSERR; +} + + +/** + * Callback that processes each of the known HELLOs for the + * hostlist response construction. + */ +static void +host_processor (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Message *hello, const char *err_msg) +{ + struct HostSet *results = cls; + size_t old; + size_t s; + int has_addr; + + if (err_msg != NULL) + { + GNUNET_assert (NULL == peer); + pitr = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + _("Error in communication with PEERINFO service: %s\n"), + err_msg); + return; + } + if (peer == NULL) + { + pitr = NULL; + finish_response (results); + return; + } + if (hello == NULL) + return; + has_addr = GNUNET_NO; + GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &check_has_addr, &has_addr); + if (GNUNET_NO == has_addr) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "HELLO for peer `%4s' has no address, not suitable for hostlist!\n", + GNUNET_i2s (peer)); + GNUNET_STATISTICS_update (stats, + gettext_noop + ("HELLOs without addresses encountered (ignored)"), + 1, GNUNET_NO); + return; + } + old = results->size; + s = GNUNET_HELLO_size (hello); +#if DEBUG_HOSTLIST_SERVER + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received %u bytes of `%s' from peer `%s' for hostlist.\n", + (unsigned int) s, "HELLO", GNUNET_i2s (peer)); +#endif + if ((old + s >= GNUNET_MAX_MALLOC_CHECKED) || + (old + s >= MAX_BYTES_PER_HOSTLISTS)) + { + GNUNET_STATISTICS_update (stats, + gettext_noop + ("bytes not included in hostlist (size limit)"), + s, GNUNET_NO); + return; /* too large, skip! */ + } +#if DEBUG_HOSTLIST_SERVER + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Adding peer `%s' to hostlist (%u bytes)\n", GNUNET_i2s (peer), + (unsigned int) s); +#endif + GNUNET_array_grow (results->data, results->size, old + s); + memcpy (&results->data[old], hello, s); +} + + + +/** + * Hostlist access policy (very permissive, allows everything). + */ +static int +accept_policy_callback (void *cls, const struct sockaddr *addr, + socklen_t addrlen) +{ + if (NULL == response) + { +#if DEBUG_HOSTLIST_SERVER + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received request for hostlist, but I am not yet ready; rejecting!\n"); +#endif + return MHD_NO; + } + return MHD_YES; /* accept all */ +} + + +/** + * Main request handler. + */ +static int +access_handler_callback (void *cls, struct MHD_Connection *connection, + const char *url, const char *method, + const char *version, const char *upload_data, + size_t * upload_data_size, void **con_cls) +{ + static int dummy; + + if (0 != strcmp (method, MHD_HTTP_METHOD_GET)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Refusing `%s' request to hostlist server\n"), method); + GNUNET_STATISTICS_update (stats, + gettext_noop + ("hostlist requests refused (not HTTP GET)"), 1, + GNUNET_YES); + return MHD_NO; + } + if (NULL == *con_cls) + { + (*con_cls) = &dummy; +#if DEBUG_HOSTLIST_SERVER + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Sending 100 CONTINUE reply\n")); +#endif + return MHD_YES; /* send 100 continue */ + } + if (*upload_data_size != 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Refusing `%s' request with %llu bytes of upload data\n"), + method, (unsigned long long) *upload_data_size); + GNUNET_STATISTICS_update (stats, + gettext_noop + ("hostlist requests refused (upload data)"), 1, + GNUNET_YES); + return MHD_NO; /* do not support upload data */ + } + if (response == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("Could not handle hostlist request since I do not have a response yet\n")); + GNUNET_STATISTICS_update (stats, + gettext_noop + ("hostlist requests refused (not ready)"), 1, + GNUNET_YES); + return MHD_NO; /* internal error, no response yet */ + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Received request for our hostlist\n")); + GNUNET_STATISTICS_update (stats, gettext_noop ("hostlist requests processed"), + 1, GNUNET_YES); + return MHD_queue_response (connection, MHD_HTTP_OK, response); +} + + +/** + * Handler called by core when core is ready to transmit message + * @param cls closure + * @param size size of buffer to copy message to + * @param buf buffer to copy message to + */ +static size_t +adv_transmit_ready (void *cls, size_t size, void *buf) +{ + static uint64_t hostlist_adv_count; + + size_t transmission_size; + size_t uri_size; /* Including \0 termination! */ + struct GNUNET_MessageHeader header; + char *cbuf; + + if (buf == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Transmission failed, buffer invalid!\n"); + return 0; + } + uri_size = strlen (hostlist_uri) + 1; + transmission_size = sizeof (struct GNUNET_MessageHeader) + uri_size; + header.type = htons (GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT); + header.size = htons (transmission_size); + GNUNET_assert (size >= transmission_size); + memcpy (buf, &header, sizeof (struct GNUNET_MessageHeader)); + cbuf = buf; + memcpy (&cbuf[sizeof (struct GNUNET_MessageHeader)], hostlist_uri, uri_size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Sent advertisement message: Copied %u bytes into buffer!\n", + (unsigned int) transmission_size); + hostlist_adv_count++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " # Sent advertisement message: %u\n", + hostlist_adv_count); + GNUNET_STATISTICS_update (stats, + gettext_noop ("# hostlist advertisements send"), 1, + GNUNET_NO); + return transmission_size; +} + + +/** + * Method called whenever a given peer connects. + * + * @param cls closure + * @param peer peer identity this notification is about + * @param atsi performance data + * @param atsi_count number of records in 'atsi' + */ +static void +connect_handler (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *atsi, + unsigned int atsi_count) +{ + size_t size; + + if (!advertising) + return; + if (hostlist_uri == NULL) + return; + size = strlen (hostlist_uri) + 1; + if (size + sizeof (struct GNUNET_MessageHeader) >= + GNUNET_SERVER_MAX_MESSAGE_SIZE) + { + GNUNET_break (0); + return; + } + size += sizeof (struct GNUNET_MessageHeader); + if (NULL == core) + { + GNUNET_break (0); + return; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Asked core to transmit advertisement message with a size of %u bytes to peer `%s'\n", + size, GNUNET_i2s (peer)); + if (NULL == + GNUNET_CORE_notify_transmit_ready (core, GNUNET_YES, 0, + GNUNET_ADV_TIMEOUT, peer, size, + &adv_transmit_ready, NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Advertisement message could not be queued by core\n")); + } +} + + +/** + * Method called whenever a given peer disconnects. + * + * @param cls closure + * @param peer peer identity this notification is about + */ +static void +disconnect_handler (void *cls, const struct GNUNET_PeerIdentity *peer) +{ + /* nothing to do */ +} + +/** + * PEERINFO calls this function to let us know about a possible peer + * that we might want to connect to. + * + * @param cls closure (not used) + * @param peer potential peer to connect to + * @param hello HELLO for this peer (or NULL) + * @param err_msg NULL if successful, otherwise contains error message + */ +static void +process_notify (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_HELLO_Message *hello, const char *err_msg) +{ + struct HostSet *results; + +#if DEBUG_HOSTLIST_SERVER + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peerinfo is notifying us to rebuild our hostlist\n"); +#endif + if (err_msg != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + _("Error in communication with PEERINFO service\n")); + /* return; */ + } + results = GNUNET_malloc (sizeof (struct HostSet)); + GNUNET_assert (peerinfo != NULL); + pitr = + GNUNET_PEERINFO_iterate (peerinfo, NULL, GNUNET_TIME_UNIT_MINUTES, + &host_processor, results); +} + +/** + * Function that queries MHD's select sets and + * starts the task waiting for them. + */ +static GNUNET_SCHEDULER_TaskIdentifier +prepare_daemon (struct MHD_Daemon *daemon_handle); + + +/** + * Call MHD to process pending requests and then go back + * and schedule the next run. + */ +static void +run_daemon (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct MHD_Daemon *daemon_handle = cls; + + if (daemon_handle == daemon_handle_v4) + hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK; + else + hostlist_task_v6 = GNUNET_SCHEDULER_NO_TASK; + + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + GNUNET_assert (MHD_YES == MHD_run (daemon_handle)); + if (daemon_handle == daemon_handle_v4) + hostlist_task_v4 = prepare_daemon (daemon_handle); + else + hostlist_task_v6 = prepare_daemon (daemon_handle); +} + + +/** + * Function that queries MHD's select sets and + * starts the task waiting for them. + */ +static GNUNET_SCHEDULER_TaskIdentifier +prepare_daemon (struct MHD_Daemon *daemon_handle) +{ + GNUNET_SCHEDULER_TaskIdentifier ret; + fd_set rs; + fd_set ws; + fd_set es; + struct GNUNET_NETWORK_FDSet *wrs; + struct GNUNET_NETWORK_FDSet *wws; + struct GNUNET_NETWORK_FDSet *wes; + int max; + unsigned long long timeout; + int haveto; + struct GNUNET_TIME_Relative tv; + + FD_ZERO (&rs); + FD_ZERO (&ws); + FD_ZERO (&es); + wrs = GNUNET_NETWORK_fdset_create (); + wes = GNUNET_NETWORK_fdset_create (); + wws = GNUNET_NETWORK_fdset_create (); + max = -1; + GNUNET_assert (MHD_YES == MHD_get_fdset (daemon_handle, &rs, &ws, &es, &max)); + haveto = MHD_get_timeout (daemon_handle, &timeout); + if (haveto == MHD_YES) + tv.rel_value = (uint64_t) timeout; + else + tv = GNUNET_TIME_UNIT_FOREVER_REL; + GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1); + GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); + GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); + ret = + GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, + GNUNET_SCHEDULER_NO_TASK, tv, wrs, wws, + &run_daemon, daemon_handle); + GNUNET_NETWORK_fdset_destroy (wrs); + GNUNET_NETWORK_fdset_destroy (wws); + GNUNET_NETWORK_fdset_destroy (wes); + return ret; +} + + + +/** + * Start server offering our hostlist. + * + * @return GNUNET_OK on success + */ +int +GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_STATISTICS_Handle *st, + struct GNUNET_CORE_Handle *co, + GNUNET_CORE_ConnectEventHandler *server_ch, + GNUNET_CORE_DisconnectEventHandler *server_dh, + int advertise) +{ + unsigned long long port; + char *hostname; + size_t size; + + advertising = advertise; + if (!advertising) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Advertising not enabled on this hostlist server\n"); + else + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Advertising enabled on this hostlist server\n"); + cfg = c; + stats = st; + peerinfo = GNUNET_PEERINFO_connect (cfg); + if (peerinfo == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Could not access PEERINFO service. Exiting.\n")); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_number (cfg, "HOSTLIST", "HTTPPORT", + &port)) + return GNUNET_SYSERR; + if ((port == 0) || (port > UINT16_MAX)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Invalid port number %llu. Exiting.\n"), port); + return GNUNET_SYSERR; + } + + if (GNUNET_SYSERR == + GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", + "EXTERNAL_DNS_NAME", &hostname)) + hostname = GNUNET_RESOLVER_local_fqdn_get (); + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Hostlist service starts on %s:%llu\n"), + hostname, port); + if (NULL != hostname) + { + size = strlen (hostname); + if (size + 15 > MAX_URL_LEN) + { + GNUNET_break (0); + } + else + { + GNUNET_asprintf (&hostlist_uri, "http://%s:%u/", hostname, + (unsigned int) port); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Address to obtain hostlist: `%s'\n"), hostlist_uri); + } + GNUNET_free (hostname); + } + daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 +#if DEBUG_HOSTLIST_SERVER + | MHD_USE_DEBUG +#endif + , (unsigned short) port, + &accept_policy_callback, NULL, + &access_handler_callback, NULL, + MHD_OPTION_CONNECTION_LIMIT, + (unsigned int) 16, + MHD_OPTION_PER_IP_CONNECTION_LIMIT, + (unsigned int) 1, + MHD_OPTION_CONNECTION_TIMEOUT, + (unsigned int) 16, + MHD_OPTION_CONNECTION_MEMORY_LIMIT, + (size_t) (16 * 1024), MHD_OPTION_END); + daemon_handle_v4 = MHD_start_daemon (MHD_NO_FLAG +#if DEBUG_HOSTLIST_SERVER + | MHD_USE_DEBUG +#endif + , (unsigned short) port, + &accept_policy_callback, NULL, + &access_handler_callback, NULL, + MHD_OPTION_CONNECTION_LIMIT, + (unsigned int) 16, + MHD_OPTION_PER_IP_CONNECTION_LIMIT, + (unsigned int) 1, + MHD_OPTION_CONNECTION_TIMEOUT, + (unsigned int) 16, + MHD_OPTION_CONNECTION_MEMORY_LIMIT, + (size_t) (16 * 1024), MHD_OPTION_END); + + if ((daemon_handle_v6 == NULL) && (daemon_handle_v4 == NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Could not start hostlist HTTP server on port %u\n"), + (unsigned short) port); + return GNUNET_SYSERR; + } + + core = co; + + *server_ch = &connect_handler; + *server_dh = &disconnect_handler; + + if (daemon_handle_v4 != NULL) + hostlist_task_v4 = prepare_daemon (daemon_handle_v4); + if (daemon_handle_v6 != NULL) + hostlist_task_v6 = prepare_daemon (daemon_handle_v6); + + notify = GNUNET_PEERINFO_notify (cfg, process_notify, NULL); + + return GNUNET_OK; +} + +/** + * Stop server offering our hostlist. + */ +void +GNUNET_HOSTLIST_server_stop () +{ +#if DEBUG_HOSTLIST_SERVER + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n"); +#endif + if (NULL != notify) + { + GNUNET_PEERINFO_notify_cancel (notify); + notify = NULL; + } + if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v6) + { + GNUNET_SCHEDULER_cancel (hostlist_task_v6); + hostlist_task_v6 = GNUNET_SCHEDULER_NO_TASK; + } + if (GNUNET_SCHEDULER_NO_TASK != hostlist_task_v4) + { + GNUNET_SCHEDULER_cancel (hostlist_task_v4); + hostlist_task_v4 = GNUNET_SCHEDULER_NO_TASK; + } + if (pitr != NULL) + { + GNUNET_PEERINFO_iterate_cancel (pitr); + pitr = NULL; + } + if (NULL != daemon_handle_v4) + { + MHD_stop_daemon (daemon_handle_v4); + daemon_handle_v4 = NULL; + } + if (NULL != daemon_handle_v6) + { + MHD_stop_daemon (daemon_handle_v6); + daemon_handle_v6 = NULL; + } + if (response != NULL) + { + MHD_destroy_response (response); + response = NULL; + } + if (peerinfo != NULL) + { + GNUNET_PEERINFO_disconnect (peerinfo); + peerinfo = NULL; + } + cfg = NULL; + stats = NULL; + core = NULL; +} + +/* end of hostlist-server.c */ diff --git a/src/hostlist/hostlist-server.h b/src/hostlist/hostlist-server.h new file mode 100644 index 0000000..e0f8eb4 --- /dev/null +++ b/src/hostlist/hostlist-server.h @@ -0,0 +1,58 @@ +/* + 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 hostlist/hostlist-server.h + * @brief hostlist support. Downloads HELLOs via HTTP. + * @author Christian Grothoff + */ + +#ifndef HOSTLIST_SERVER_H +#define HOSTLIST_SERVER_H + +#include "gnunet_core_service.h" +#include "gnunet_statistics_service.h" +#include "gnunet_util_lib.h" + +#define GNUNET_ADV_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) + +/** + * Start server offering our hostlist. + * + * @return GNUNET_OK on success + */ +int +GNUNET_HOSTLIST_server_start (const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_STATISTICS_Handle *st, + struct GNUNET_CORE_Handle *core, + GNUNET_CORE_ConnectEventHandler *server_ch, + GNUNET_CORE_DisconnectEventHandler *server_dh, + int advertise); + + +/** + * Stop server offering our hostlist. + */ +void +GNUNET_HOSTLIST_server_stop (void); + + +#endif +/* end of hostlist-server.h */ diff --git a/src/hostlist/hostlist.conf b/src/hostlist/hostlist.conf new file mode 100644 index 0000000..b13e1e5 --- /dev/null +++ b/src/hostlist/hostlist.conf @@ -0,0 +1,14 @@ +[hostlist] +# port for hostlist http server +HTTPPORT = 8080 +HOME = $SERVICEHOME +HOSTLISTFILE = $SERVICEHOME/hostlist/learned.data +CONFIG = $DEFAULTCONFIG +BINARY = gnunet-daemon-hostlist +# consider having "-e" as default as well once implemented +OPTIONS = -b +SERVERS = http://v9.gnunet.org:58080/ http://ioerror.gnunet.org:65535/ +# proxy for downloading hostlists +HTTP-PROXY = + + diff --git a/src/hostlist/learning_data.conf b/src/hostlist/learning_data.conf new file mode 100644 index 0000000..e3a3897 --- /dev/null +++ b/src/hostlist/learning_data.conf @@ -0,0 +1,14 @@ +@INLINE@ test_hostlist_defaults.conf +[hostlist] +HTTPPORT = 28080 +OPTIONS = -b -e +SERVERS = http://gnunet.org:8080/ +PORT = 23354 +HOSTNAME = localhost + +[datastore] +AUTOSTART = YES + +[fs] +AUTOSTART = YES + diff --git a/src/hostlist/test_gnunet_daemon_hostlist.c b/src/hostlist/test_gnunet_daemon_hostlist.c new file mode 100644 index 0000000..da3ab8b --- /dev/null +++ b/src/hostlist/test_gnunet_daemon_hostlist.c @@ -0,0 +1,255 @@ +/* + 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 hostlist/test_gnunet_daemon_hostlist.c + * @brief test for gnunet_daemon_hostslist.c + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_arm_service.h" +#include "gnunet_transport_service.h" + +#define VERBOSE GNUNET_NO + +#define START_ARM GNUNET_YES + + +/** + * How long until we give up on transmitting the message? + */ +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 150) + +static int ok; + +static GNUNET_SCHEDULER_TaskIdentifier timeout_task; + +struct PeerContext +{ + struct GNUNET_CONFIGURATION_Handle *cfg; + struct GNUNET_TRANSPORT_Handle *th; + struct GNUNET_MessageHeader *hello; + struct GNUNET_TRANSPORT_GetHelloHandle *ghh; +#if START_ARM + struct GNUNET_OS_Process *arm_proc; +#endif +}; + +static struct PeerContext p1; + +static struct PeerContext p2; + + +static void +clean_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (p1.th != NULL) + { + if (p1.ghh != NULL) + { + GNUNET_TRANSPORT_get_hello_cancel (p1.ghh); + p1.ghh = NULL; + } + GNUNET_TRANSPORT_disconnect (p1.th); + p1.th = NULL; + } + if (p2.th != NULL) + { + if (p2.ghh != NULL) + { + GNUNET_TRANSPORT_get_hello_cancel (p2.ghh); + p2.ghh = NULL; + } + GNUNET_TRANSPORT_disconnect (p2.th); + p2.th = NULL; + } + GNUNET_SCHEDULER_shutdown (); +} + +/** + * Timeout, give up. + */ +static void +timeout_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Timeout trying to connect peers, test failed.\n"); + clean_up (NULL, tc); +} + + +/** + * Function called to notify transport users that another + * peer connected to us. + * + * @param cls closure + * @param peer the peer that connected + * @param latency current latency of the connection + * @param distance in overlay hops, as given by transport plugin + */ +static void +notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *ats, uint32_t ats_count) +{ + if (peer == NULL) + return; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peers connected, shutting down.\n"); + ok = 0; + if (timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&clean_up, NULL); +} + + +static void +process_hello (void *cls, const struct GNUNET_MessageHeader *message) +{ + struct PeerContext *p = cls; + + GNUNET_TRANSPORT_get_hello_cancel (p->ghh); + p->ghh = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received HELLO, starting hostlist service.\n"); +} + + +static void +setup_peer (struct PeerContext *p, const char *cfgname) +{ + p->cfg = GNUNET_CONFIGURATION_create (); +#if START_ARM + p->arm_proc = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", +#if VERBOSE + "-L", "DEBUG", +#endif + "-c", cfgname, NULL); +#endif + GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); + p->th = + GNUNET_TRANSPORT_connect (p->cfg, NULL, p, NULL, ¬ify_connect, NULL); + GNUNET_assert (p->th != NULL); + p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &process_hello, p); +} + + +static void +waitpid_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PeerContext *p = cls; + +#if START_ARM + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Killing ARM process.\n"); + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", + GNUNET_OS_process_get_pid (p->arm_proc)); + GNUNET_OS_process_close (p->arm_proc); + p->arm_proc = NULL; +#endif + GNUNET_CONFIGURATION_destroy (p->cfg); +} + + +static void +stop_arm (struct PeerContext *p) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking ARM to stop core service\n"); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &waitpid_task, p); +} + + +/** + * Try again to connect to transport service. + */ +static void +shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + stop_arm (&p1); + stop_arm (&p2); +} + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + GNUNET_assert (ok == 1); + ok++; + timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_error, NULL); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, + NULL); + setup_peer (&p1, "test_gnunet_daemon_hostlist_peer1.conf"); + setup_peer (&p2, "test_gnunet_daemon_hostlist_peer2.conf"); +} + + +static int +check () +{ + char *const argv[] = { "test-gnunet-daemon-hostlist", + "-c", "test_gnunet_daemon_hostlist_data.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + ok = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, + "test-gnunet-daemon-hostlist", "nohelp", options, &run, + &ok); + return ok; +} + + +int +main (int argc, char *argv[]) +{ + + int ret; + + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist"); + GNUNET_log_setup ("test-gnunet-daemon-hostlist", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + ret = check (); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist"); + return ret; +} + +/* end of test_gnunet_daemon_hostlist.c */ diff --git a/src/hostlist/test_gnunet_daemon_hostlist_data.conf b/src/hostlist/test_gnunet_daemon_hostlist_data.conf new file mode 100644 index 0000000..74d16be --- /dev/null +++ b/src/hostlist/test_gnunet_daemon_hostlist_data.conf @@ -0,0 +1,29 @@ +@INLINE@ test_hostlist_defaults.conf +[transport-tcp] +PORT = 12968 + +[arm] +PORT = 12966 +DEFAULTSERVICES = hostlist topology + +[statistics] +PORT = 12967 + +[resolver] +PORT = 12964 + +[peerinfo] +PORT = 12969 + +[transport] +PORT = 12965 + +[core] +PORT = 12970 + +[hostlist] +HTTPPORT = 28080 +SERVERS = http://gnunet.org:8080/ +PORT = 23354 +HOSTNAME = localhost + diff --git a/src/hostlist/test_gnunet_daemon_hostlist_learning.c b/src/hostlist/test_gnunet_daemon_hostlist_learning.c new file mode 100644 index 0000000..9ef8812 --- /dev/null +++ b/src/hostlist/test_gnunet_daemon_hostlist_learning.c @@ -0,0 +1,533 @@ +/* + This file is part of GNUnet + (C) 2009, 2010, 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 hostlist/test_gnunet_daemon_hostlist.c + * @brief test for gnunet_daemon_hostslist.c + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_arm_service.h" +#include "gnunet_core_service.h" +#include "gnunet_transport_service.h" +#include "gnunet_resolver_service.h" +#include "gnunet_statistics_service.h" + +#define VERBOSE GNUNET_NO + +#define START_ARM GNUNET_YES + +#define MAX_URL_LEN 1000 + +/** + * How long until wait until testcases fails + */ +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 180) + +#define CHECK_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) + + +struct PeerContext +{ + struct GNUNET_CONFIGURATION_Handle *cfg; + struct GNUNET_TRANSPORT_Handle *th; + struct GNUNET_MessageHeader *hello; + struct GNUNET_CORE_Handle *core; + struct GNUNET_STATISTICS_Handle *stats; +#if START_ARM + struct GNUNET_OS_Process *arm_proc; +#endif +}; + +static int timeout; + +static int adv_sent; + +static int adv_arrived; + +static int learned_hostlist_saved; + +static int learned_hostlist_downloaded; + +static char *current_adv_uri; + +static const struct GNUNET_CONFIGURATION_Handle *cfg; + +static GNUNET_SCHEDULER_TaskIdentifier timeout_task; + +static GNUNET_SCHEDULER_TaskIdentifier check_task; + +static struct PeerContext adv_peer; + +static struct PeerContext learn_peer; + +static struct GNUNET_STATISTICS_GetHandle *download_stats; + +static struct GNUNET_STATISTICS_GetHandle *urisrecv_stat; + +static struct GNUNET_STATISTICS_GetHandle *advsent_stat; + + +static void +shutdown_testcase () +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown testcase....\n"); + if (timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != download_stats) + { + GNUNET_STATISTICS_get_cancel (download_stats); + download_stats = NULL; + } + if (NULL != urisrecv_stat) + { + GNUNET_STATISTICS_get_cancel (urisrecv_stat); + urisrecv_stat = NULL; + } + if (NULL != advsent_stat) + { + GNUNET_STATISTICS_get_cancel (advsent_stat); + advsent_stat = NULL; + } + if (check_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (check_task); + check_task = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != current_adv_uri) + { + GNUNET_free (current_adv_uri); + current_adv_uri = NULL; + } + if (adv_peer.th != NULL) + { + GNUNET_TRANSPORT_disconnect (adv_peer.th); + adv_peer.th = NULL; + } + if (learn_peer.th != NULL) + { + GNUNET_TRANSPORT_disconnect (learn_peer.th); + learn_peer.th = NULL; + } + if (adv_peer.core != NULL) + { + GNUNET_CORE_disconnect (adv_peer.core); + adv_peer.core = NULL; + } + if (learn_peer.core != NULL) + { + GNUNET_CORE_disconnect (learn_peer.core); + learn_peer.core = NULL; + } +#if START_ARM + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Killing hostlist server ARM process.\n"); + if (0 != GNUNET_OS_process_kill (adv_peer.arm_proc, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + if (GNUNET_OS_process_wait (adv_peer.arm_proc) != GNUNET_OK) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); + GNUNET_OS_process_close (adv_peer.arm_proc); + adv_peer.arm_proc = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Killing hostlist client ARM process.\n"); + if (0 != GNUNET_OS_process_kill (learn_peer.arm_proc, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + if (GNUNET_OS_process_wait (learn_peer.arm_proc) != GNUNET_OK) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); + GNUNET_OS_process_close (learn_peer.arm_proc); + learn_peer.arm_proc = NULL; +#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown complete....\n"); +} + +/** + * Timeout, give up. + */ +static void +timeout_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Timeout while executing testcase, test failed.\n"); + timeout = GNUNET_YES; + shutdown_testcase (); +} + + +static void +process_downloads_done (void *cls, int success) +{ + download_stats = NULL; +} + + +static int +process_downloads (void *cls, const char *subsystem, const char *name, + uint64_t value, int is_persistent) +{ + if ((value >= 2) && (learned_hostlist_downloaded == GNUNET_NO)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Peer has successfully downloaded advertised URI\n"); + learned_hostlist_downloaded = GNUNET_YES; + if ((learned_hostlist_saved == GNUNET_YES) && (adv_sent == GNUNET_YES)) + shutdown_testcase (); + } + return GNUNET_OK; +} + + +static void +process_uris_recv_done (void *cls, int success) +{ + urisrecv_stat = NULL; +} + + +static int +process_uris_recv (void *cls, const char *subsystem, const char *name, + uint64_t value, int is_persistent) +{ + if (((struct PeerContext *) cls == &learn_peer) && (value == 1) && + (learned_hostlist_saved == GNUNET_NO)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Peer has successfully saved advertised URI\n"); + learned_hostlist_saved = GNUNET_YES; + if ((learned_hostlist_downloaded == GNUNET_YES) && (adv_sent == GNUNET_YES)) + shutdown_testcase (); + } + return GNUNET_OK; +} + + +static void +process_adv_sent_done (void *cls, int success) +{ + advsent_stat = NULL; +} + + +static int +process_adv_sent (void *cls, const char *subsystem, const char *name, + uint64_t value, int is_persistent) +{ + if ((value >= 1) && (adv_sent == GNUNET_NO)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Server has successfully sent advertisement\n"); + adv_sent = GNUNET_YES; + if ((learned_hostlist_downloaded == GNUNET_YES) && + (learned_hostlist_saved == GNUNET_YES)) + shutdown_testcase (); + } + return GNUNET_OK; +} + + +/** + * Check the server statistics regularly + */ +static void +check_statistics (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + char *stat; + + check_task = GNUNET_SCHEDULER_NO_TASK; + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + GNUNET_asprintf (&stat, gettext_noop ("# advertised URI `%s' downloaded"), + current_adv_uri); + if (NULL != learn_peer.stats) + { + if (NULL != download_stats) + GNUNET_STATISTICS_get_cancel (download_stats); + download_stats = + GNUNET_STATISTICS_get (learn_peer.stats, "hostlist", stat, + GNUNET_TIME_UNIT_MINUTES, + &process_downloads_done, &process_downloads, + &learn_peer); + if (NULL != urisrecv_stat) + GNUNET_STATISTICS_get_cancel (urisrecv_stat); + urisrecv_stat = + GNUNET_STATISTICS_get (learn_peer.stats, "hostlist", + gettext_noop ("# advertised hostlist URIs"), + GNUNET_TIME_UNIT_MINUTES, + &process_uris_recv_done, &process_uris_recv, + &learn_peer); + } + GNUNET_free (stat); + if (NULL != adv_peer.stats) + { + if (NULL != advsent_stat) + GNUNET_STATISTICS_get_cancel (advsent_stat); + advsent_stat = + GNUNET_STATISTICS_get (adv_peer.stats, "hostlist", + gettext_noop ("# hostlist advertisements send"), + GNUNET_TIME_UNIT_MINUTES, &process_adv_sent_done, + &process_adv_sent, NULL); + } + check_task = + GNUNET_SCHEDULER_add_delayed (CHECK_INTERVALL, &check_statistics, NULL); +} + + +/** + * Core handler for p2p hostlist advertisements + */ +static int +ad_arrive_handler (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message, + const struct GNUNET_ATS_Information *atsi, + unsigned int atsi_count) +{ + char *hostname; + char *expected_uri; + unsigned long long port; + const struct GNUNET_MessageHeader *incoming; + const char *end; + + if (-1 == + GNUNET_CONFIGURATION_get_value_number (adv_peer.cfg, "HOSTLIST", + "HTTPPORT", &port)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not read advertising server's configuration\n"); + return GNUNET_SYSERR; + } + + if (GNUNET_SYSERR == + GNUNET_CONFIGURATION_get_value_string (adv_peer.cfg, "HOSTLIST", + "EXTERNAL_DNS_NAME", &hostname)) + hostname = GNUNET_RESOLVER_local_fqdn_get (); + GNUNET_asprintf (&expected_uri, "http://%s:%u/", + hostname != NULL ? hostname : "localhost", + (unsigned int) port); + incoming = (const struct GNUNET_MessageHeader *) message; + end = (const char *) &incoming[1]; + if ('\0' != + end[ntohs (message->size) - sizeof (struct GNUNET_MessageHeader) - 1]) + { + GNUNET_break (0); + GNUNET_free (expected_uri); + GNUNET_free_non_null (hostname); + return GNUNET_SYSERR; + } + current_adv_uri = GNUNET_strdup (end); + if (0 == strcmp (expected_uri, current_adv_uri)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Received hostlist advertisement with URI `%s' as expected\n", + current_adv_uri); + adv_arrived = GNUNET_YES; + adv_sent = GNUNET_YES; + } + else + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Expected URI `%s' and recieved URI `%s' differ\n", + expected_uri, current_adv_uri); + GNUNET_free (expected_uri); + GNUNET_free_non_null (hostname); + return GNUNET_OK; +} + + +/** + * List of handlers if we are learning. + */ +static struct GNUNET_CORE_MessageHandler learn_handlers[] = { + {&ad_arrive_handler, GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT, 0}, + {NULL, 0, 0} +}; + + +static void +setup_learn_peer (struct PeerContext *p, const char *cfgname) +{ + char *filename; + unsigned int result; + + p->cfg = GNUNET_CONFIGURATION_create (); +#if START_ARM + p->arm_proc = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", +#if VERBOSE + "-L", "DEBUG", +#endif + "-c", cfgname, NULL); +#endif + GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); + if (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_string (p->cfg, "HOSTLIST", "HOSTLISTFILE", + &filename)) + { + if (GNUNET_YES == GNUNET_DISK_file_test (filename)) + { + result = UNLINK (filename); + if (result == 0) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Hostlist file `%s' was removed\n"), filename); + } + GNUNET_free (filename); + } + p->core = + GNUNET_CORE_connect (p->cfg, 1, NULL, NULL, NULL, NULL, NULL, GNUNET_NO, + NULL, GNUNET_NO, learn_handlers); + GNUNET_assert (NULL != p->core); + p->stats = GNUNET_STATISTICS_create ("hostlist", p->cfg); + GNUNET_assert (NULL != p->stats); +} + + +static void +setup_adv_peer (struct PeerContext *p, const char *cfgname) +{ + p->cfg = GNUNET_CONFIGURATION_create (); +#if START_ARM + p->arm_proc = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", +#if VERBOSE + "-L", "DEBUG", +#endif + "-c", cfgname, NULL); +#endif + GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); + p->stats = GNUNET_STATISTICS_create ("hostlist", p->cfg); + GNUNET_assert (NULL != p->stats); +} + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + timeout = GNUNET_NO; + adv_sent = GNUNET_NO; + + adv_arrived = 0; + learned_hostlist_saved = GNUNET_NO; + learned_hostlist_downloaded = GNUNET_NO; + + cfg = c; + + setup_adv_peer (&adv_peer, "test_learning_adv_peer.conf"); + setup_learn_peer (&learn_peer, "test_learning_learn_peer.conf"); + timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_error, NULL); + + check_task = + GNUNET_SCHEDULER_add_delayed (CHECK_INTERVALL, &check_statistics, NULL); +} + + +static int +check () +{ + unsigned int failed; + + char *const argv[] = { + "test-gnunet-daemon-hostlist-learning", + "-c", "learning_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-gnunet-daemon-hostlist-learning", "nohelp", options, + &run, NULL); + failed = GNUNET_NO; + if (timeout == GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Testcase timeout\n"); + failed = GNUNET_YES; + } + if (adv_arrived != GNUNET_YES) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Learning peer did not receive advertisement from server\n"); + failed = GNUNET_YES; + } + if (learned_hostlist_saved == GNUNET_NO) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Advertised hostlist was not saved in datastore\n"); + failed = GNUNET_YES; + } + if (learned_hostlist_downloaded == GNUNET_NO) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Advertised hostlist could not be downloaded from server\n"); + failed = GNUNET_YES; + } + if (adv_sent == GNUNET_NO) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Advertised was not sent from server to client\n"); + failed = GNUNET_YES; + } + if (GNUNET_YES == failed) + return GNUNET_YES; + return GNUNET_NO; +} + + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); + GNUNET_log_setup ("test-gnunet-daemon-hostlist", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); +#if !WINDOWS + system ("gnunet-peerinfo -s -c test_learning_adv_peer.conf > /dev/null"); + system ("gnunet-peerinfo -s -c test_learning_learn_peer.conf > /dev/null"); +#else + system ("gnunet-peerinfo -s -c test_learning_adv_peer.conf > NUL"); + system ("gnunet-peerinfo -s -c test_learning_learn_peer.conf > NUL"); +#endif + ret = check (); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); + if (GNUNET_YES == GNUNET_DISK_file_test ("hostlists_learn_peer.file")) + { + if (0 == UNLINK ("hostlists_learn_peer.file")) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Hostlist file hostlists_learn_peer.file was removed\n"); + } + return ret; +} + +/* end of test_gnunet_daemon_hostlist.c */ diff --git a/src/hostlist/test_gnunet_daemon_hostlist_peer1.conf b/src/hostlist/test_gnunet_daemon_hostlist_peer1.conf new file mode 100644 index 0000000..535b60e --- /dev/null +++ b/src/hostlist/test_gnunet_daemon_hostlist_peer1.conf @@ -0,0 +1,43 @@ +@INLINE@ test_hostlist_defaults.conf +[PATHS] +SERVICEHOME = /tmp/test-gnunet-hostlist-peer-1/ +DEFAULTCONFIG = test_gnunet_daemon_hostlist_peer1.conf + +[transport-tcp] +PORT = 12968 + +[arm] +PORT = 12966 +DEFAULTSERVICES = hostlist topology +UNIXPATH = /tmp/gnunet-p1-service-arm.sock + +[statistics] +PORT = 12967 +UNIXPATH = /tmp/gnunet-p1-service-statistics.sock + +[resolver] +PORT = 12964 +UNIXPATH = /tmp/gnunet-p1-service-resolver.sock + +[peerinfo] +PORT = 12969 +UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock + +[transport] +PORT = 12965 +UNIXPATH = /tmp/gnunet-p1-service-transport.sock +DEBUG = NO + +[core] +PORT = 12970 +UNIXPATH = /tmp/gnunet-p1-service-core.sock + +[hostlist] +HTTPPORT = 12980 +HOSTLISTFILE = hostlists_peer1.file +OPTIONS = -b -p +SERVERS = http://localhost:12981/ + +PORT = 12971 +UNIXPATH = /tmp/gnunet-p1-service-ats.sock + diff --git a/src/hostlist/test_gnunet_daemon_hostlist_peer2.conf b/src/hostlist/test_gnunet_daemon_hostlist_peer2.conf new file mode 100644 index 0000000..41862da --- /dev/null +++ b/src/hostlist/test_gnunet_daemon_hostlist_peer2.conf @@ -0,0 +1,43 @@ +@INLINE@ test_hostlist_defaults.conf +[PATHS] +SERVICEHOME = /tmp/test-gnunet-hostlist-peer-2/ +DEFAULTCONFIG = test_gnunet_daemon_hostlist_peer2.conf + +[transport-tcp] +PORT = 22968 + +[arm] +PORT = 22966 +DEFAULTSERVICES = hostlist topology +UNIXPATH = /tmp/gnunet-p2-service-arm.sock + +[statistics] +PORT = 22967 +UNIXPATH = /tmp/gnunet-p2-service-statistics.sock + +[resolver] +PORT = 22964 +UNIXPATH = /tmp/gnunet-p2-service-resolver.sock + +[peerinfo] +PORT = 22969 +UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock + +[transport] +PORT = 22965 +UNIXPATH = /tmp/gnunet-p2-service-transport.sock + +[core] +PORT = 22970 +UNIXPATH = /tmp/gnunet-p2-service-core.sock + +[hostlist] +HTTPPORT = 12981 +HOSTLISTFILE = hostlists_peer2.file +OPTIONS = -b -p +SERVERS = http://localhost:12980/ + +[ats] +PORT = 22971 +UNIXPATH = /tmp/gnunet-p2-service-ats.sock + diff --git a/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c b/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c new file mode 100644 index 0000000..a991557 --- /dev/null +++ b/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c @@ -0,0 +1,266 @@ +/* + 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 hostlist/test_gnunet_daemon_hostlist_reconnect.c + * @brief test for gnunet_daemon_hostslist.c; tries to re-start the peers + * and connect a second time + * @author Christian Grothoff + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_arm_service.h" +#include "gnunet_transport_service.h" + +#define VERBOSE GNUNET_NO + +#define START_ARM GNUNET_YES + + +/** + * How long until we give up on transmitting the message? + */ +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 150) + +static int ok; + +static GNUNET_SCHEDULER_TaskIdentifier timeout_task; + +struct PeerContext +{ + struct GNUNET_CONFIGURATION_Handle *cfg; + struct GNUNET_TRANSPORT_Handle *th; + struct GNUNET_MessageHeader *hello; + struct GNUNET_TRANSPORT_GetHelloHandle *ghh; +#if START_ARM + struct GNUNET_OS_Process *arm_proc; +#endif +}; + +static struct PeerContext p1; + +static struct PeerContext p2; + + +static void +clean_up (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + if (NULL != p1.ghh) + { + GNUNET_TRANSPORT_get_hello_cancel (p1.ghh); + p1.ghh = NULL; + } + if (p1.th != NULL) + { + GNUNET_TRANSPORT_disconnect (p1.th); + p1.th = NULL; + } + if (NULL != p2.ghh) + { + GNUNET_TRANSPORT_get_hello_cancel (p2.ghh); + p2.ghh = NULL; + } + if (p2.th != NULL) + { + GNUNET_TRANSPORT_disconnect (p2.th); + p2.th = NULL; + } + GNUNET_SCHEDULER_shutdown (); +} + +/** + * Timeout, give up. + */ +static void +timeout_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Timeout trying to connect peers, test failed.\n"); + clean_up (NULL, tc); +} + + +/** + * Function called to notify transport users that another + * peer connected to us. + * + * @param cls closure + * @param peer the peer that connected + * @param latency current latency of the connection + * @param distance in overlay hops, as given by transport plugin + */ +static void +notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_ATS_Information *ats, uint32_t ats_count) +{ + if (peer == NULL) + return; +#if VERBOSE + FPRINTF (stderr, "Peer %s connected\n", GNUNET_i2s (peer)); +#endif + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peers connected, shutting down.\n"); + ok = 0; + if (timeout_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + GNUNET_SCHEDULER_add_now (&clean_up, NULL); +} + + +static void +process_hello (void *cls, const struct GNUNET_MessageHeader *message) +{ + struct PeerContext *p = cls; + + GNUNET_TRANSPORT_get_hello_cancel (p->ghh); + p->ghh = NULL; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received HELLO, starting hostlist service.\n"); +} + + +static void +setup_peer (struct PeerContext *p, const char *cfgname) +{ + p->cfg = GNUNET_CONFIGURATION_create (); +#if START_ARM + p->arm_proc = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", +#if VERBOSE + "-L", "DEBUG", +#endif + "-c", cfgname, NULL); +#endif + GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); + p->th = + GNUNET_TRANSPORT_connect (p->cfg, NULL, p, NULL, ¬ify_connect, NULL); + GNUNET_assert (p->th != NULL); + p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &process_hello, p); +} + + +static void +waitpid_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct PeerContext *p = cls; + +#if START_ARM + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Killing ARM process.\n"); + if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", + GNUNET_OS_process_get_pid (p->arm_proc)); + GNUNET_OS_process_close (p->arm_proc); + p->arm_proc = NULL; +#endif + GNUNET_CONFIGURATION_destroy (p->cfg); +} + + +static void +stop_arm (struct PeerContext *p) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking ARM to stop core service\n"); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &waitpid_task, p); +} + + +/** + * Try again to connect to transport service. + */ +static void +shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + stop_arm (&p1); + stop_arm (&p2); +} + + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + GNUNET_assert (ok == 1); + ok++; + timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &timeout_error, NULL); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, + NULL); + setup_peer (&p1, "test_gnunet_daemon_hostlist_peer1.conf"); + setup_peer (&p2, "test_gnunet_daemon_hostlist_peer2.conf"); +} + + +static int +check () +{ + char *const argv[] = { "test-gnunet-daemon-hostlist", + "-c", "test_gnunet_daemon_hostlist_data.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + ok = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, + "test-gnunet-daemon-hostlist", "nohelp", options, &run, + &ok); + return ok; +} + + +int +main (int argc, char *argv[]) +{ + + int ret; + + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-3"); + GNUNET_log_setup ("test-gnunet-daemon-hostlist", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + ret = check (); + if (ret == 0) + { + FPRINTF (stderr, "%s", "."); + /* now do it again */ + ret = check (); + FPRINTF (stderr, "%s", ".\n"); + } + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-1"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-2"); + GNUNET_DISK_directory_remove ("/tmp/test-gnunet-hostlist-peer-3"); + return ret; +} + +/* end of test_gnunet_daemon_hostlist_reconnect.c */ diff --git a/src/hostlist/test_hostlist_defaults.conf b/src/hostlist/test_hostlist_defaults.conf new file mode 100644 index 0000000..5772250 --- /dev/null +++ b/src/hostlist/test_hostlist_defaults.conf @@ -0,0 +1,62 @@ +[PATHS] +SERVICEHOME = /tmp/test-gnunet-hostlist/ +DEFAULTCONFIG = test_hostlist_default.conf + +[resolver] +PORT = 12464 + +[transport] +PORT = 12465 +PLUGINS = tcp + +[arm] +PORT = 12466 +DEFAULTSERVICES = hostlist + +[statistics] +PORT = 12467 + +[tcp] +PORT = 12468 + +[peerinfo] +PORT = 12469 + +[core] +PORT = 12470 + +[testing] +WEAKRANDOM = YES + +[hostlist] +HTTP-PROXY = + +[mesh] +AUTOSTART = NO + +[dns] +AUTOSTART = NO + +[nse] +AUTOSTART = NO + +[datastore] +AUTOSTART = NO + +[fs] +AUTOSTART = NO + +[dht] +AUTOSTART = NO + +[dv] +AUTOSTART = NO + +[chat] +AUTOSTART = NO + +[gns] +AUTOSTART = NO + +[vpn] +AUTOSTART = NO diff --git a/src/hostlist/test_learning_adv_peer.conf b/src/hostlist/test_learning_adv_peer.conf new file mode 100644 index 0000000..fe50bd5 --- /dev/null +++ b/src/hostlist/test_learning_adv_peer.conf @@ -0,0 +1,47 @@ +@INLINE@ test_hostlist_defaults.conf +[PATHS] +SERVICEHOME = /tmp/test-gnunet-hostlist-peer-1/ +DEFAULTCONFIG = test_learning_adv_peer.conf + +[transport-tcp] +PORT = 22968 + +[arm] +PORT = 22966 +DEFAULTSERVICES = topology hostlist +UNIXPATH = /tmp/gnunet-hostlist-p2-service-arm.sock + +[statistics] +PORT = 22967 +UNIXPATH = /tmp/gnunet-hostlist-p2-service-statistics.sock + +[resolver] +PORT = 22964 +UNIXPATH = /tmp/gnunet-hostlist-p2-service-resolver.sock + +[peerinfo] +PORT = 22969 +UNIXPATH = /tmp/gnunet-hostlist-p2-service-peerinfo.sock + +[transport] +PORT = 22965 +UNIXPATH = /tmp/gnunet-hostlist-p2-service-transport.sock + +[core] +PORT = 22970 +UNIXPATH = /tmp/gnunet-hostlist-p2-service-core.sock + +[hostlist] +HTTPPORT = 12981 +HOSTLISTFILE = hostlists_adv_peer.file +OPTIONS = -p -a +SERVERS = http://localhost:12981/ +EXTERNAL_DNS_NAME = localhost + +[dht] +AUTOSTART = NO + + +[ats] +PORT = 22971 +UNIXPATH = /tmp/gnunet-ats-p2-service-core.sock diff --git a/src/hostlist/test_learning_learn_peer.conf b/src/hostlist/test_learning_learn_peer.conf new file mode 100644 index 0000000..0136d77 --- /dev/null +++ b/src/hostlist/test_learning_learn_peer.conf @@ -0,0 +1,46 @@ +@INLINE@ test_hostlist_defaults.conf +[PATHS] +SERVICEHOME = /tmp/test-gnunet-hostlist-peer-2/ +DEFAULTCONFIG = test_learning_learn_peer.conf + +[transport-tcp] +PORT = 12968 + +[arm] +PORT = 12966 +DEFAULTSERVICES = topology hostlist +UNIXPATH = /tmp/gnunet-hostlist-p1-service-arm.sock + +[statistics] +PORT = 12967 +UNIXPATH = /tmp/gnunet-hostlist-p1-service-statistics.sock + +[resolver] +PORT = 12964 +UNIXPATH = /tmp/gnunet-hostlist-p1-service-resolver.sock + +[peerinfo] +PORT = 12969 +UNIXPATH = /tmp/gnunet-hostlist-p1-service-peerinfo.sock + +[transport] +PORT = 12965 +UNIXPATH = /tmp/gnunet-hostlist-p1-service-transport.sock + +[core] +PORT = 12970 +UNIXPATH = /tmp/gnunet-hostlist-p1-service-core.sock + +[hostlist] +HTTPPORT = 12980 +HOSTLISTFILE = hostlists_learn_peer.file +OPTIONS = -b -e +SERVERS = http://localhost:12981/ + +[dht] +AUTOSTART = NO + + +[ats] +PORT = 12971 +UNIXPATH = /tmp/gnunet-ats-p1-service-core.sock diff --git a/src/hostlist/test_learning_learn_peer2.conf b/src/hostlist/test_learning_learn_peer2.conf new file mode 100644 index 0000000..4fd54bb --- /dev/null +++ b/src/hostlist/test_learning_learn_peer2.conf @@ -0,0 +1,39 @@ +@INLINE@ test_hostlist_defaults.conf +[PATHS] +SERVICEHOME = /tmp/test-gnunet-hostlist-peer-3/ +DEFAULTCONFIG = test_learning_learn_peer2.conf + +[transport-tcp] +PORT = 32968 + +[arm] +PORT = 32966 +DEFAULTSERVICES = topology hostlist +UNIXPATH = /tmp/gnunet-p3-service-arm.sock + +[statistics] +PORT = 32967 +UNIXPATH = /tmp/gnunet-p3-service-statistics.sock + +[resolver] +PORT = 32964 +UNIXPATH = /tmp/gnunet-p3-service-resolver.sock + +[peerinfo] +PORT = 32969 +UNIXPATH = /tmp/gnunet-p3-service-peerinfo.sock + +[transport] +PORT = 32965 +UNIXPATH = /tmp/gnunet-p3-service-transport.sock + +[core] +PORT = 32970 +UNIXPATH = /tmp/gnunet-p3-service-core.sock + +[hostlist] +HTTPPORT = 32980 +HOSTLISTFILE = hostlists_learn_peer2.file +OPTIONS = -b -e +SERVERS = http://localhost:12981/ + |