aboutsummaryrefslogtreecommitdiff
path: root/src/ats
diff options
context:
space:
mode:
Diffstat (limited to 'src/ats')
-rw-r--r--src/ats/Makefile.am196
-rw-r--r--src/ats/Makefile.in735
-rw-r--r--src/ats/ats.conf.in15
-rw-r--r--src/ats/ats.h15
-rw-r--r--src/ats/ats_api_performance.c294
-rw-r--r--src/ats/ats_api_scheduling.c371
-rw-r--r--src/ats/gnunet-service-ats.c15
-rw-r--r--src/ats/gnunet-service-ats_addresses.c1541
-rw-r--r--src/ats/gnunet-service-ats_addresses.h232
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.c231
-rw-r--r--src/ats/gnunet-service-ats_addresses_mlp.h96
-rw-r--r--src/ats/gnunet-service-ats_addresses_simplistic.c1377
-rw-r--r--src/ats/gnunet-service-ats_addresses_simplistic.h151
-rw-r--r--src/ats/gnunet-service-ats_performance.c393
-rw-r--r--src/ats/gnunet-service-ats_performance.h26
-rw-r--r--src/ats/gnunet-service-ats_reservations.c4
-rw-r--r--src/ats/gnunet-service-ats_scheduling.c97
-rw-r--r--src/ats/gnunet-service-ats_scheduling.h18
-rw-r--r--src/ats/perf_ats_mlp.c372
-rw-r--r--src/ats/test_ats_api.conf13
-rw-r--r--src/ats/test_ats_api_common.c139
-rw-r--r--src/ats/test_ats_api_common.h75
-rw-r--r--src/ats/test_ats_api_performance.c596
-rw-r--r--src/ats/test_ats_api_reset_backoff.c308
-rw-r--r--src/ats/test_ats_api_scheduling.c253
-rw-r--r--src/ats/test_ats_api_scheduling_add_address.c199
-rw-r--r--src/ats/test_ats_api_scheduling_add_session.c237
-rw-r--r--src/ats/test_ats_api_scheduling_block_and_reset.c364
-rw-r--r--src/ats/test_ats_api_scheduling_check_min_bw_alt.c417
-rw-r--r--src/ats/test_ats_api_scheduling_destroy_address.c218
-rw-r--r--src/ats/test_ats_api_scheduling_destroy_inbound_connection.c223
-rw-r--r--src/ats/test_ats_api_scheduling_destroy_session.c235
-rw-r--r--src/ats/test_ats_api_scheduling_init.c141
-rw-r--r--src/ats/test_ats_api_scheduling_min_bw.c185
-rw-r--r--src/ats/test_ats_api_scheduling_update_address.c247
-rw-r--r--src/ats/test_ats_mlp.c195
-rw-r--r--src/ats/test_ats_mlp_averaging.c178
-rw-r--r--src/ats/test_ats_simplistic.c380
-rw-r--r--src/ats/test_ats_simplistic_change_preference.c418
-rw-r--r--src/ats/test_ats_simplistic_pref_aging.c448
-rw-r--r--src/ats/test_ats_simplistic_switch_networks.c451
41 files changed, 9693 insertions, 2406 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am
index 2e85848..f9a1ec4 100644
--- a/src/ats/Makefile.am
+++ b/src/ats/Makefile.am
@@ -2,6 +2,8 @@ INCLUDES = -I$(top_srcdir)/src/include
pkgcfgdir= $(pkgdatadir)/config.d/
+libexecdir= $(pkglibdir)/libexec/
+
pkgcfg_DATA = \
ats.conf
@@ -28,19 +30,21 @@ libgnunetats_la_SOURCES = \
ats_api_performance.c
libgnunetats_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(LTLIBINTL)
libgnunetats_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) \
- -version-info 2:0:2
+ -version-info 4:0:0
-bin_PROGRAMS = \
+libexec_PROGRAMS = \
gnunet-service-ats
gnunet_service_ats_SOURCES = \
gnunet-service-ats.c gnunet-service-ats.h\
gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \
+ gnunet-service-ats_addresses_simplistic.c gnunet-service-ats_addresses_simplistic.h \
$(GN_MLP_SRC) \
gnunet-service-ats_performance.c gnunet-service-ats_performance.h \
gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \
@@ -48,16 +52,31 @@ gnunet_service_ats_SOURCES = \
gnunet_service_ats_LDADD = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetats.la \
$(GN_LIBGLPK) \
$(GN_LIBINTL)
-
+gnunet_service_ats_DEPENDENCIES = \
+ libgnunetats.la
check_PROGRAMS = \
- test_ats_api_scheduling \
- test_ats_api_reset_backoff \
- $(GN_MLP_TEST) \
- $(GN_MLP_TEST_AVG) \
- $(GN_MLP_PERF)
+ test_ats_api_scheduling_init \
+ test_ats_api_scheduling_add_address \
+ test_ats_api_scheduling_add_session \
+ test_ats_api_scheduling_min_bw \
+ test_ats_api_scheduling_check_min_bw_alt \
+ test_ats_api_scheduling_update_address \
+ test_ats_api_scheduling_destroy_address \
+ test_ats_api_scheduling_destroy_session \
+ test_ats_api_scheduling_destroy_inbound_connection \
+ test_ats_api_scheduling_block_and_reset \
+ test_ats_simplistic \
+ test_ats_simplistic_switch_networks \
+ test_ats_simplistic_change_preference \
+ test_ats_simplistic_pref_aging \
+ test_ats_api_performance
+# $(GN_MLP_TEST) \
+# $(GN_MLP_TEST_AVG) \
+# $(GN_MLP_PERF)
# test_ats_api_scheduling_get_type
# test_ats_api_bandwidth_consumption
@@ -65,60 +84,147 @@ if ENABLE_TEST_RUN
TESTS = $(check_PROGRAMS)
endif
-if HAVE_LIBGLPK
-test_ats_mlp_SOURCES = \
- $(GN_MLP_SRC) \
- test_ats_mlp.c
-test_ats_mlp_LDADD = \
- $(GN_LIBGLPK) \
+test_ats_api_scheduling_init_SOURCES = \
+ test_ats_api_scheduling_init.c \
+ test_ats_api_common.c test_ats_api_common.h
+test_ats_api_scheduling_init_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/statistics/libgnunetstatistics.la
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
-test_ats_mlp_averaging_SOURCES = \
- $(GN_MLP_SRC) \
- test_ats_mlp_averaging.c
-test_ats_mlp_averaging_LDADD = \
- $(GN_LIBGLPK) \
+test_ats_api_scheduling_add_address_SOURCES = \
+ test_ats_api_scheduling_add_address.c \
+ test_ats_api_common.c test_ats_api_common.h
+test_ats_api_scheduling_add_address_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/statistics/libgnunetstatistics.la
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
-perf_ats_mlp_SOURCES = \
- $(GN_MLP_SRC) \
- perf_ats_mlp.c
-perf_ats_mlp_LDADD = \
- $(GN_LIBGLPK) \
+test_ats_api_scheduling_add_session_SOURCES = \
+ test_ats_api_scheduling_add_session.c test_ats_api_common.c
+test_ats_api_scheduling_add_session_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/statistics/libgnunetstatistics.la
-endif
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_scheduling_min_bw_SOURCES = \
+ test_ats_api_scheduling_min_bw.c test_ats_api_common.c
+test_ats_api_scheduling_min_bw_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_scheduling_check_min_bw_alt_SOURCES = \
+ test_ats_api_scheduling_check_min_bw_alt.c test_ats_api_common.c
+test_ats_api_scheduling_check_min_bw_alt_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+
+test_ats_api_scheduling_update_address_SOURCES = \
+ test_ats_api_scheduling_update_address.c test_ats_api_common.c
+test_ats_api_scheduling_update_address_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
-test_ats_api_scheduling_SOURCES = \
- test_ats_api_scheduling.c
-test_ats_api_scheduling_LDADD = \
+test_ats_api_scheduling_destroy_address_SOURCES = \
+ test_ats_api_scheduling_destroy_address.c test_ats_api_common.c
+test_ats_api_scheduling_destroy_address_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/ats/libgnunetats.la
-test_ats_api_reset_backoff_SOURCES = \
- test_ats_api_reset_backoff.c
-test_ats_api_reset_backoff_LDADD = \
+test_ats_api_scheduling_destroy_session_SOURCES = \
+ test_ats_api_scheduling_destroy_session.c test_ats_api_common.c
+test_ats_api_scheduling_destroy_session_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_scheduling_destroy_inbound_connection_SOURCES = \
+ test_ats_api_scheduling_destroy_inbound_connection.c test_ats_api_common.c
+test_ats_api_scheduling_destroy_inbound_connection_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_scheduling_block_and_reset_SOURCES = \
+ test_ats_api_scheduling_block_and_reset.c test_ats_api_common.c
+test_ats_api_scheduling_block_and_reset_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_performance_SOURCES = \
+ test_ats_api_performance.c
+test_ats_api_performance_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_simplistic_SOURCES = \
+ test_ats_simplistic.c test_ats_api_common.c
+test_ats_simplistic_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_simplistic_switch_networks_SOURCES = \
+ test_ats_simplistic_switch_networks.c test_ats_api_common.c
+test_ats_simplistic_switch_networks_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_simplistic_change_preference_SOURCES = \
+ test_ats_simplistic_change_preference.c test_ats_api_common.c
+test_ats_simplistic_change_preference_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_simplistic_pref_aging_SOURCES = \
+ test_ats_simplistic_pref_aging.c test_ats_api_common.c
+test_ats_simplistic_pref_aging_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/ats/libgnunetats.la
-#test_ats_api_scheduling_get_type_SOURCES = \
-# test_ats_api_scheduling_get_type.c
-#test_ats_api_scheduling_get_type_LDADD = \
+if HAVE_LIBGLPK
+#test_ats_mlp_SOURCES = \
+# $(GN_MLP_SRC) \
+# test_ats_mlp.c
+#test_ats_mlp_LDADD = \
+# $(GN_LIBGLPK) \
# $(top_builddir)/src/util/libgnunetutil.la \
-# $(top_builddir)/src/ats/libgnunetats.la
+# $(top_builddir)/src/statistics/libgnunetstatistics.la
+
+#test_ats_mlp_averaging_SOURCES = \
+# $(GN_MLP_SRC) \
+# test_ats_mlp_averaging.c
+#test_ats_mlp_averaging_LDADD = \
+# $(GN_LIBGLPK) \
+# $(top_builddir)/src/util/libgnunetutil.la \
+# $(top_builddir)/src/statistics/libgnunetstatistics.la
+
+#perf_ats_mlp_SOURCES = \
+# $(GN_MLP_SRC) \
+# perf_ats_mlp.c
+#perf_ats_mlp_LDADD = \
+# $(GN_LIBGLPK) \
+# $(top_builddir)/src/util/libgnunetutil.la \
+# $(top_builddir)/src/statistics/libgnunetstatistics.la
+endif
#test_ats_api_bandwidth_consumption_SOURCES = \
# test_ats_api_bandwidth_consumption.c
#test_ats_api_bandwidth_consumption_LDADD = \
# $(top_builddir)/src/util/libgnunetutil.la \
-# $(top_builddir)/src/ats/libgnunetats.la
-
-#test_ats_api_update_address_SOURCES = \
-# test_ats_api_update_address.c
-#test_ats_api_update_address_LDADD = \
-# $(top_builddir)/src/util/libgnunetutil.la \
+# $(top_builddir)/src/testing/libgnunettesting.la \
# $(top_builddir)/src/ats/libgnunetats.la
diff --git a/src/ats/Makefile.in b/src/ats/Makefile.in
index 7f74064..e9a1c3a 100644
--- a/src/ats/Makefile.in
+++ b/src/ats/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -18,6 +18,23 @@
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -37,24 +54,37 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-bin_PROGRAMS = gnunet-service-ats$(EXEEXT)
-check_PROGRAMS = test_ats_api_scheduling$(EXEEXT) \
- test_ats_api_reset_backoff$(EXEEXT) $(am__EXEEXT_1) \
- $(am__EXEEXT_2) $(am__EXEEXT_3)
+libexec_PROGRAMS = gnunet-service-ats$(EXEEXT)
+check_PROGRAMS = test_ats_api_scheduling_init$(EXEEXT) \
+ test_ats_api_scheduling_add_address$(EXEEXT) \
+ test_ats_api_scheduling_add_session$(EXEEXT) \
+ test_ats_api_scheduling_min_bw$(EXEEXT) \
+ test_ats_api_scheduling_check_min_bw_alt$(EXEEXT) \
+ test_ats_api_scheduling_update_address$(EXEEXT) \
+ test_ats_api_scheduling_destroy_address$(EXEEXT) \
+ test_ats_api_scheduling_destroy_session$(EXEEXT) \
+ test_ats_api_scheduling_destroy_inbound_connection$(EXEEXT) \
+ test_ats_api_scheduling_block_and_reset$(EXEEXT) \
+ test_ats_simplistic$(EXEEXT) \
+ test_ats_simplistic_switch_networks$(EXEEXT) \
+ test_ats_simplistic_change_preference$(EXEEXT) \
+ test_ats_simplistic_pref_aging$(EXEEXT) \
+ test_ats_api_performance$(EXEEXT)
subdir = src/ats
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/ats.conf.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \
$(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \
- $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
- $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
- $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \
- $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glib-2.0.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/libunistring.m4 \
+ $(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \
$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -84,28 +114,35 @@ am__nobase_list = $(am__nobase_strip_setup); \
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" \
"$(DESTDIR)$(pkgcfgdir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
libgnunetats_la_DEPENDENCIES = \
- $(top_builddir)/src/util/libgnunetutil.la
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(am__DEPENDENCIES_1)
am_libgnunetats_la_OBJECTS = ats_api_scheduling.lo \
ats_api_performance.lo
libgnunetats_la_OBJECTS = $(am_libgnunetats_la_OBJECTS)
-AM_V_lt = $(am__v_lt_$(V))
-am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
libgnunetats_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(libgnunetats_la_LDFLAGS) $(LDFLAGS) \
-o $@
-@HAVE_LIBGLPK_TRUE@am__EXEEXT_1 = test_ats_mlp$(EXEEXT)
-@HAVE_LIBGLPK_TRUE@am__EXEEXT_2 = test_ats_mlp_averaging$(EXEEXT)
-@HAVE_LIBGLPK_TRUE@am__EXEEXT_3 = perf_ats_mlp$(EXEEXT)
-PROGRAMS = $(bin_PROGRAMS)
+PROGRAMS = $(libexec_PROGRAMS)
am__gnunet_service_ats_SOURCES_DIST = gnunet-service-ats.c \
gnunet-service-ats.h gnunet-service-ats_addresses.c \
gnunet-service-ats_addresses.h \
+ gnunet-service-ats_addresses_simplistic.c \
+ gnunet-service-ats_addresses_simplistic.h \
gnunet-service-ats_addresses_mlp.c \
gnunet-service-ats_addresses_mlp.h \
gnunet-service-ats_performance.c \
@@ -117,57 +154,145 @@ am__gnunet_service_ats_SOURCES_DIST = gnunet-service-ats.c \
@HAVE_LIBGLPK_TRUE@am__objects_1 = \
@HAVE_LIBGLPK_TRUE@ gnunet-service-ats_addresses_mlp.$(OBJEXT)
am_gnunet_service_ats_OBJECTS = gnunet-service-ats.$(OBJEXT) \
- gnunet-service-ats_addresses.$(OBJEXT) $(am__objects_1) \
- gnunet-service-ats_performance.$(OBJEXT) \
+ gnunet-service-ats_addresses.$(OBJEXT) \
+ gnunet-service-ats_addresses_simplistic.$(OBJEXT) \
+ $(am__objects_1) gnunet-service-ats_performance.$(OBJEXT) \
gnunet-service-ats_scheduling.$(OBJEXT) \
gnunet-service-ats_reservations.$(OBJEXT)
gnunet_service_ats_OBJECTS = $(am_gnunet_service_ats_OBJECTS)
-am__DEPENDENCIES_1 =
-gnunet_service_ats_DEPENDENCIES = \
- $(top_builddir)/src/statistics/libgnunetstatistics.la \
+am_test_ats_api_performance_OBJECTS = \
+ test_ats_api_performance.$(OBJEXT)
+test_ats_api_performance_OBJECTS = \
+ $(am_test_ats_api_performance_OBJECTS)
+test_ats_api_performance_DEPENDENCIES = \
$(top_builddir)/src/util/libgnunetutil.la \
- $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
-am__perf_ats_mlp_SOURCES_DIST = gnunet-service-ats_addresses_mlp.c \
- gnunet-service-ats_addresses_mlp.h perf_ats_mlp.c
-@HAVE_LIBGLPK_TRUE@am_perf_ats_mlp_OBJECTS = $(am__objects_1) \
-@HAVE_LIBGLPK_TRUE@ perf_ats_mlp.$(OBJEXT)
-perf_ats_mlp_OBJECTS = $(am_perf_ats_mlp_OBJECTS)
-@HAVE_LIBGLPK_TRUE@perf_ats_mlp_DEPENDENCIES = $(am__DEPENDENCIES_1) \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/util/libgnunetutil.la \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la
-am_test_ats_api_reset_backoff_OBJECTS = \
- test_ats_api_reset_backoff.$(OBJEXT)
-test_ats_api_reset_backoff_OBJECTS = \
- $(am_test_ats_api_reset_backoff_OBJECTS)
-test_ats_api_reset_backoff_DEPENDENCIES = \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_api_scheduling_add_address_OBJECTS = \
+ test_ats_api_scheduling_add_address.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_api_scheduling_add_address_OBJECTS = \
+ $(am_test_ats_api_scheduling_add_address_OBJECTS)
+test_ats_api_scheduling_add_address_DEPENDENCIES = \
$(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/ats/libgnunetats.la
-am_test_ats_api_scheduling_OBJECTS = \
- test_ats_api_scheduling.$(OBJEXT)
-test_ats_api_scheduling_OBJECTS = \
- $(am_test_ats_api_scheduling_OBJECTS)
-test_ats_api_scheduling_DEPENDENCIES = \
+am_test_ats_api_scheduling_add_session_OBJECTS = \
+ test_ats_api_scheduling_add_session.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_api_scheduling_add_session_OBJECTS = \
+ $(am_test_ats_api_scheduling_add_session_OBJECTS)
+test_ats_api_scheduling_add_session_DEPENDENCIES = \
$(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_api_scheduling_block_and_reset_OBJECTS = \
+ test_ats_api_scheduling_block_and_reset.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_api_scheduling_block_and_reset_OBJECTS = \
+ $(am_test_ats_api_scheduling_block_and_reset_OBJECTS)
+test_ats_api_scheduling_block_and_reset_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_api_scheduling_check_min_bw_alt_OBJECTS = \
+ test_ats_api_scheduling_check_min_bw_alt.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_api_scheduling_check_min_bw_alt_OBJECTS = \
+ $(am_test_ats_api_scheduling_check_min_bw_alt_OBJECTS)
+test_ats_api_scheduling_check_min_bw_alt_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_api_scheduling_destroy_address_OBJECTS = \
+ test_ats_api_scheduling_destroy_address.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_api_scheduling_destroy_address_OBJECTS = \
+ $(am_test_ats_api_scheduling_destroy_address_OBJECTS)
+test_ats_api_scheduling_destroy_address_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_api_scheduling_destroy_inbound_connection_OBJECTS = \
+ test_ats_api_scheduling_destroy_inbound_connection.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_api_scheduling_destroy_inbound_connection_OBJECTS = $(am_test_ats_api_scheduling_destroy_inbound_connection_OBJECTS)
+test_ats_api_scheduling_destroy_inbound_connection_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_api_scheduling_destroy_session_OBJECTS = \
+ test_ats_api_scheduling_destroy_session.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_api_scheduling_destroy_session_OBJECTS = \
+ $(am_test_ats_api_scheduling_destroy_session_OBJECTS)
+test_ats_api_scheduling_destroy_session_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_api_scheduling_init_OBJECTS = \
+ test_ats_api_scheduling_init.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_api_scheduling_init_OBJECTS = \
+ $(am_test_ats_api_scheduling_init_OBJECTS)
+test_ats_api_scheduling_init_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_api_scheduling_min_bw_OBJECTS = \
+ test_ats_api_scheduling_min_bw.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_api_scheduling_min_bw_OBJECTS = \
+ $(am_test_ats_api_scheduling_min_bw_OBJECTS)
+test_ats_api_scheduling_min_bw_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_api_scheduling_update_address_OBJECTS = \
+ test_ats_api_scheduling_update_address.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_api_scheduling_update_address_OBJECTS = \
+ $(am_test_ats_api_scheduling_update_address_OBJECTS)
+test_ats_api_scheduling_update_address_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_simplistic_OBJECTS = test_ats_simplistic.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_simplistic_OBJECTS = $(am_test_ats_simplistic_OBJECTS)
+test_ats_simplistic_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_simplistic_change_preference_OBJECTS = \
+ test_ats_simplistic_change_preference.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_simplistic_change_preference_OBJECTS = \
+ $(am_test_ats_simplistic_change_preference_OBJECTS)
+test_ats_simplistic_change_preference_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_simplistic_pref_aging_OBJECTS = \
+ test_ats_simplistic_pref_aging.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_simplistic_pref_aging_OBJECTS = \
+ $(am_test_ats_simplistic_pref_aging_OBJECTS)
+test_ats_simplistic_pref_aging_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+am_test_ats_simplistic_switch_networks_OBJECTS = \
+ test_ats_simplistic_switch_networks.$(OBJEXT) \
+ test_ats_api_common.$(OBJEXT)
+test_ats_simplistic_switch_networks_OBJECTS = \
+ $(am_test_ats_simplistic_switch_networks_OBJECTS)
+test_ats_simplistic_switch_networks_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/ats/libgnunetats.la
-am__test_ats_mlp_SOURCES_DIST = gnunet-service-ats_addresses_mlp.c \
- gnunet-service-ats_addresses_mlp.h test_ats_mlp.c
-@HAVE_LIBGLPK_TRUE@am_test_ats_mlp_OBJECTS = $(am__objects_1) \
-@HAVE_LIBGLPK_TRUE@ test_ats_mlp.$(OBJEXT)
-test_ats_mlp_OBJECTS = $(am_test_ats_mlp_OBJECTS)
-@HAVE_LIBGLPK_TRUE@test_ats_mlp_DEPENDENCIES = $(am__DEPENDENCIES_1) \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/util/libgnunetutil.la \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la
-am__test_ats_mlp_averaging_SOURCES_DIST = \
- gnunet-service-ats_addresses_mlp.c \
- gnunet-service-ats_addresses_mlp.h test_ats_mlp_averaging.c
-@HAVE_LIBGLPK_TRUE@am_test_ats_mlp_averaging_OBJECTS = \
-@HAVE_LIBGLPK_TRUE@ $(am__objects_1) \
-@HAVE_LIBGLPK_TRUE@ test_ats_mlp_averaging.$(OBJEXT)
-test_ats_mlp_averaging_OBJECTS = $(am_test_ats_mlp_averaging_OBJECTS)
-@HAVE_LIBGLPK_TRUE@test_ats_mlp_averaging_DEPENDENCIES = \
-@HAVE_LIBGLPK_TRUE@ $(am__DEPENDENCIES_1) \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/util/libgnunetutil.la \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -178,33 +303,60 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_$(V))
-am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_$(V))
-am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libgnunetats_la_SOURCES) $(gnunet_service_ats_SOURCES) \
- $(perf_ats_mlp_SOURCES) $(test_ats_api_reset_backoff_SOURCES) \
- $(test_ats_api_scheduling_SOURCES) $(test_ats_mlp_SOURCES) \
- $(test_ats_mlp_averaging_SOURCES)
+ $(test_ats_api_performance_SOURCES) \
+ $(test_ats_api_scheduling_add_address_SOURCES) \
+ $(test_ats_api_scheduling_add_session_SOURCES) \
+ $(test_ats_api_scheduling_block_and_reset_SOURCES) \
+ $(test_ats_api_scheduling_check_min_bw_alt_SOURCES) \
+ $(test_ats_api_scheduling_destroy_address_SOURCES) \
+ $(test_ats_api_scheduling_destroy_inbound_connection_SOURCES) \
+ $(test_ats_api_scheduling_destroy_session_SOURCES) \
+ $(test_ats_api_scheduling_init_SOURCES) \
+ $(test_ats_api_scheduling_min_bw_SOURCES) \
+ $(test_ats_api_scheduling_update_address_SOURCES) \
+ $(test_ats_simplistic_SOURCES) \
+ $(test_ats_simplistic_change_preference_SOURCES) \
+ $(test_ats_simplistic_pref_aging_SOURCES) \
+ $(test_ats_simplistic_switch_networks_SOURCES)
DIST_SOURCES = $(libgnunetats_la_SOURCES) \
$(am__gnunet_service_ats_SOURCES_DIST) \
- $(am__perf_ats_mlp_SOURCES_DIST) \
- $(test_ats_api_reset_backoff_SOURCES) \
- $(test_ats_api_scheduling_SOURCES) \
- $(am__test_ats_mlp_SOURCES_DIST) \
- $(am__test_ats_mlp_averaging_SOURCES_DIST)
+ $(test_ats_api_performance_SOURCES) \
+ $(test_ats_api_scheduling_add_address_SOURCES) \
+ $(test_ats_api_scheduling_add_session_SOURCES) \
+ $(test_ats_api_scheduling_block_and_reset_SOURCES) \
+ $(test_ats_api_scheduling_check_min_bw_alt_SOURCES) \
+ $(test_ats_api_scheduling_destroy_address_SOURCES) \
+ $(test_ats_api_scheduling_destroy_inbound_connection_SOURCES) \
+ $(test_ats_api_scheduling_destroy_session_SOURCES) \
+ $(test_ats_api_scheduling_init_SOURCES) \
+ $(test_ats_api_scheduling_min_bw_SOURCES) \
+ $(test_ats_api_scheduling_update_address_SOURCES) \
+ $(test_ats_simplistic_SOURCES) \
+ $(test_ats_simplistic_change_preference_SOURCES) \
+ $(test_ats_simplistic_pref_aging_SOURCES) \
+ $(test_ats_simplistic_switch_networks_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
DATA = $(pkgcfg_DATA)
ETAGS = etags
CTAGS = ctags
@@ -246,6 +398,10 @@ EXEEXT = @EXEEXT@
EXT_LIBS = @EXT_LIBS@
EXT_LIB_PATH = @EXT_LIB_PATH@
FGREP = @FGREP@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GNUNETDNS_GROUP = @GNUNETDNS_GROUP@
@@ -256,6 +412,7 @@ GN_LIBINTL = @GN_LIBINTL@
GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@
GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@
GN_USER_HOME_DIR = @GN_USER_HOME_DIR@
+GOBJECT_QUERY = @GOBJECT_QUERY@
GREP = @GREP@
HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@
INCLTDL = @INCLTDL@
@@ -278,6 +435,8 @@ LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@
LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBGTOP_CFLAGS = @LIBGTOP_CFLAGS@
+LIBGTOP_LIBS = @LIBGTOP_LIBS@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBLTDL = @LIBLTDL@
@@ -299,6 +458,7 @@ LT_CONFIG_H = @LT_CONFIG_H@
LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MONKEYPREFIX = @MONKEYPREFIX@
MSGFMT = @MSGFMT@
@@ -308,6 +468,7 @@ MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@
MYSQL_LDFLAGS = @MYSQL_LDFLAGS@
NM = @NM@
NMEDIT = @NMEDIT@
+NSS_DIR = @NSS_DIR@
OBJC = @OBJC@
OBJCDEPMODE = @OBJCDEPMODE@
OBJCFLAGS = @OBJCFLAGS@
@@ -323,6 +484,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@
POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@
POSUB = @POSUB@
@@ -354,6 +516,7 @@ abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
@@ -376,6 +539,7 @@ datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
+gitcommand = @gitcommand@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -386,10 +550,9 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
-libexecdir = @libexecdir@
+libexecdir = $(pkglibdir)/libexec/
localedir = @localedir@
localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
ltdl_LIBOBJS = @ltdl_LIBOBJS@
ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@
mandir = @mandir@
@@ -407,6 +570,7 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
+svnversioncommand = @svnversioncommand@
sys_symbol_underscore = @sys_symbol_underscore@
sysconfdir = @sysconfdir@
target = @target@
@@ -435,15 +599,17 @@ libgnunetats_la_SOURCES = \
ats_api_performance.c
libgnunetats_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(LTLIBINTL)
libgnunetats_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) \
- -version-info 2:0:2
+ -version-info 4:0:0
gnunet_service_ats_SOURCES = \
gnunet-service-ats.c gnunet-service-ats.h\
gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \
+ gnunet-service-ats_addresses_simplistic.c gnunet-service-ats_addresses_simplistic.h \
$(GN_MLP_SRC) \
gnunet-service-ats_performance.c gnunet-service-ats_performance.h \
gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \
@@ -452,70 +618,173 @@ gnunet_service_ats_SOURCES = \
gnunet_service_ats_LDADD = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetats.la \
$(GN_LIBGLPK) \
$(GN_LIBINTL)
+gnunet_service_ats_DEPENDENCIES = \
+ libgnunetats.la
+
+# $(GN_MLP_TEST) \
+# $(GN_MLP_TEST_AVG) \
+# $(GN_MLP_PERF)
# test_ats_api_scheduling_get_type
# test_ats_api_bandwidth_consumption
@ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS)
-@HAVE_LIBGLPK_TRUE@test_ats_mlp_SOURCES = \
-@HAVE_LIBGLPK_TRUE@ $(GN_MLP_SRC) \
-@HAVE_LIBGLPK_TRUE@ test_ats_mlp.c
+test_ats_api_scheduling_init_SOURCES = \
+ test_ats_api_scheduling_init.c \
+ test_ats_api_common.c test_ats_api_common.h
-@HAVE_LIBGLPK_TRUE@test_ats_mlp_LDADD = \
-@HAVE_LIBGLPK_TRUE@ $(GN_LIBGLPK) \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/util/libgnunetutil.la \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la
+test_ats_api_scheduling_init_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
-@HAVE_LIBGLPK_TRUE@test_ats_mlp_averaging_SOURCES = \
-@HAVE_LIBGLPK_TRUE@ $(GN_MLP_SRC) \
-@HAVE_LIBGLPK_TRUE@ test_ats_mlp_averaging.c
+test_ats_api_scheduling_add_address_SOURCES = \
+ test_ats_api_scheduling_add_address.c \
+ test_ats_api_common.c test_ats_api_common.h
-@HAVE_LIBGLPK_TRUE@test_ats_mlp_averaging_LDADD = \
-@HAVE_LIBGLPK_TRUE@ $(GN_LIBGLPK) \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/util/libgnunetutil.la \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la
+test_ats_api_scheduling_add_address_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
-@HAVE_LIBGLPK_TRUE@perf_ats_mlp_SOURCES = \
-@HAVE_LIBGLPK_TRUE@ $(GN_MLP_SRC) \
-@HAVE_LIBGLPK_TRUE@ perf_ats_mlp.c
+test_ats_api_scheduling_add_session_SOURCES = \
+ test_ats_api_scheduling_add_session.c test_ats_api_common.c
-@HAVE_LIBGLPK_TRUE@perf_ats_mlp_LDADD = \
-@HAVE_LIBGLPK_TRUE@ $(GN_LIBGLPK) \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/util/libgnunetutil.la \
-@HAVE_LIBGLPK_TRUE@ $(top_builddir)/src/statistics/libgnunetstatistics.la
+test_ats_api_scheduling_add_session_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
-test_ats_api_scheduling_SOURCES = \
- test_ats_api_scheduling.c
+test_ats_api_scheduling_min_bw_SOURCES = \
+ test_ats_api_scheduling_min_bw.c test_ats_api_common.c
-test_ats_api_scheduling_LDADD = \
+test_ats_api_scheduling_min_bw_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/ats/libgnunetats.la
-test_ats_api_reset_backoff_SOURCES = \
- test_ats_api_reset_backoff.c
+test_ats_api_scheduling_check_min_bw_alt_SOURCES = \
+ test_ats_api_scheduling_check_min_bw_alt.c test_ats_api_common.c
+
+test_ats_api_scheduling_check_min_bw_alt_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_scheduling_update_address_SOURCES = \
+ test_ats_api_scheduling_update_address.c test_ats_api_common.c
+
+test_ats_api_scheduling_update_address_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_scheduling_destroy_address_SOURCES = \
+ test_ats_api_scheduling_destroy_address.c test_ats_api_common.c
+
+test_ats_api_scheduling_destroy_address_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_scheduling_destroy_session_SOURCES = \
+ test_ats_api_scheduling_destroy_session.c test_ats_api_common.c
+
+test_ats_api_scheduling_destroy_session_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_scheduling_destroy_inbound_connection_SOURCES = \
+ test_ats_api_scheduling_destroy_inbound_connection.c test_ats_api_common.c
+
+test_ats_api_scheduling_destroy_inbound_connection_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_scheduling_block_and_reset_SOURCES = \
+ test_ats_api_scheduling_block_and_reset.c test_ats_api_common.c
+
+test_ats_api_scheduling_block_and_reset_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_api_performance_SOURCES = \
+ test_ats_api_performance.c
+
+test_ats_api_performance_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_simplistic_SOURCES = \
+ test_ats_simplistic.c test_ats_api_common.c
+
+test_ats_simplistic_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_simplistic_switch_networks_SOURCES = \
+ test_ats_simplistic_switch_networks.c test_ats_api_common.c
-test_ats_api_reset_backoff_LDADD = \
+test_ats_simplistic_switch_networks_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_simplistic_change_preference_SOURCES = \
+ test_ats_simplistic_change_preference.c test_ats_api_common.c
+
+test_ats_simplistic_change_preference_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/ats/libgnunetats.la
+
+test_ats_simplistic_pref_aging_SOURCES = \
+ test_ats_simplistic_pref_aging.c test_ats_api_common.c
+
+test_ats_simplistic_pref_aging_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/ats/libgnunetats.la
-#test_ats_api_scheduling_get_type_SOURCES = \
-# test_ats_api_scheduling_get_type.c
-#test_ats_api_scheduling_get_type_LDADD = \
+#test_ats_mlp_SOURCES = \
+# $(GN_MLP_SRC) \
+# test_ats_mlp.c
+#test_ats_mlp_LDADD = \
+# $(GN_LIBGLPK) \
# $(top_builddir)/src/util/libgnunetutil.la \
-# $(top_builddir)/src/ats/libgnunetats.la
+# $(top_builddir)/src/statistics/libgnunetstatistics.la
+
+#test_ats_mlp_averaging_SOURCES = \
+# $(GN_MLP_SRC) \
+# test_ats_mlp_averaging.c
+#test_ats_mlp_averaging_LDADD = \
+# $(GN_LIBGLPK) \
+# $(top_builddir)/src/util/libgnunetutil.la \
+# $(top_builddir)/src/statistics/libgnunetstatistics.la
+
+#perf_ats_mlp_SOURCES = \
+# $(GN_MLP_SRC) \
+# perf_ats_mlp.c
+#perf_ats_mlp_LDADD = \
+# $(GN_LIBGLPK) \
+# $(top_builddir)/src/util/libgnunetutil.la \
+# $(top_builddir)/src/statistics/libgnunetstatistics.la
#test_ats_api_bandwidth_consumption_SOURCES = \
# test_ats_api_bandwidth_consumption.c
#test_ats_api_bandwidth_consumption_LDADD = \
# $(top_builddir)/src/util/libgnunetutil.la \
-# $(top_builddir)/src/ats/libgnunetats.la
-
-#test_ats_api_update_address_SOURCES = \
-# test_ats_api_update_address.c
-#test_ats_api_update_address_LDADD = \
-# $(top_builddir)/src/util/libgnunetutil.la \
+# $(top_builddir)/src/testing/libgnunettesting.la \
# $(top_builddir)/src/ats/libgnunetats.la
EXTRA_DIST = \
ats.h \
@@ -559,7 +828,6 @@ ats.conf: $(top_builddir)/config.status $(srcdir)/ats.conf.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -567,6 +835,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
@@ -588,12 +858,24 @@ clean-libLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libgnunetats.la: $(libgnunetats_la_OBJECTS) $(libgnunetats_la_DEPENDENCIES)
+libgnunetats.la: $(libgnunetats_la_OBJECTS) $(libgnunetats_la_DEPENDENCIES) $(EXTRA_libgnunetats_la_DEPENDENCIES)
$(AM_V_CCLD)$(libgnunetats_la_LINK) -rpath $(libdir) $(libgnunetats_la_OBJECTS) $(libgnunetats_la_LIBADD) $(LIBS)
-install-binPROGRAMS: $(bin_PROGRAMS)
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
@$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
- @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \
+ fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p || test -f $$p1; \
@@ -610,56 +892,77 @@ install-binPROGRAMS: $(bin_PROGRAMS)
while read type dir files; do \
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
test -z "$$files" || { \
- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \
} \
; done
-uninstall-binPROGRAMS:
+uninstall-libexecPROGRAMS:
@$(NORMAL_UNINSTALL)
- @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
files=`for p in $$list; do echo "$$p"; done | \
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
-e 's/$$/$(EXEEXT)/' `; \
test -n "$$list" || exit 0; \
- echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(bindir)" && rm -f $$files
+ echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(libexecdir)" && rm -f $$files
-clean-binPROGRAMS:
- @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+clean-libexecPROGRAMS:
+ @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
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-service-ats$(EXEEXT): $(gnunet_service_ats_OBJECTS) $(gnunet_service_ats_DEPENDENCIES)
+gnunet-service-ats$(EXEEXT): $(gnunet_service_ats_OBJECTS) $(gnunet_service_ats_DEPENDENCIES) $(EXTRA_gnunet_service_ats_DEPENDENCIES)
@rm -f gnunet-service-ats$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(gnunet_service_ats_OBJECTS) $(gnunet_service_ats_LDADD) $(LIBS)
-perf_ats_mlp$(EXEEXT): $(perf_ats_mlp_OBJECTS) $(perf_ats_mlp_DEPENDENCIES)
- @rm -f perf_ats_mlp$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(perf_ats_mlp_OBJECTS) $(perf_ats_mlp_LDADD) $(LIBS)
-test_ats_api_reset_backoff$(EXEEXT): $(test_ats_api_reset_backoff_OBJECTS) $(test_ats_api_reset_backoff_DEPENDENCIES)
- @rm -f test_ats_api_reset_backoff$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(test_ats_api_reset_backoff_OBJECTS) $(test_ats_api_reset_backoff_LDADD) $(LIBS)
-test_ats_api_scheduling$(EXEEXT): $(test_ats_api_scheduling_OBJECTS) $(test_ats_api_scheduling_DEPENDENCIES)
- @rm -f test_ats_api_scheduling$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_OBJECTS) $(test_ats_api_scheduling_LDADD) $(LIBS)
-test_ats_mlp$(EXEEXT): $(test_ats_mlp_OBJECTS) $(test_ats_mlp_DEPENDENCIES)
- @rm -f test_ats_mlp$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(test_ats_mlp_OBJECTS) $(test_ats_mlp_LDADD) $(LIBS)
-test_ats_mlp_averaging$(EXEEXT): $(test_ats_mlp_averaging_OBJECTS) $(test_ats_mlp_averaging_DEPENDENCIES)
- @rm -f test_ats_mlp_averaging$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(test_ats_mlp_averaging_OBJECTS) $(test_ats_mlp_averaging_LDADD) $(LIBS)
+test_ats_api_performance$(EXEEXT): $(test_ats_api_performance_OBJECTS) $(test_ats_api_performance_DEPENDENCIES) $(EXTRA_test_ats_api_performance_DEPENDENCIES)
+ @rm -f test_ats_api_performance$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_performance_OBJECTS) $(test_ats_api_performance_LDADD) $(LIBS)
+test_ats_api_scheduling_add_address$(EXEEXT): $(test_ats_api_scheduling_add_address_OBJECTS) $(test_ats_api_scheduling_add_address_DEPENDENCIES) $(EXTRA_test_ats_api_scheduling_add_address_DEPENDENCIES)
+ @rm -f test_ats_api_scheduling_add_address$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_add_address_OBJECTS) $(test_ats_api_scheduling_add_address_LDADD) $(LIBS)
+test_ats_api_scheduling_add_session$(EXEEXT): $(test_ats_api_scheduling_add_session_OBJECTS) $(test_ats_api_scheduling_add_session_DEPENDENCIES) $(EXTRA_test_ats_api_scheduling_add_session_DEPENDENCIES)
+ @rm -f test_ats_api_scheduling_add_session$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_add_session_OBJECTS) $(test_ats_api_scheduling_add_session_LDADD) $(LIBS)
+test_ats_api_scheduling_block_and_reset$(EXEEXT): $(test_ats_api_scheduling_block_and_reset_OBJECTS) $(test_ats_api_scheduling_block_and_reset_DEPENDENCIES) $(EXTRA_test_ats_api_scheduling_block_and_reset_DEPENDENCIES)
+ @rm -f test_ats_api_scheduling_block_and_reset$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_block_and_reset_OBJECTS) $(test_ats_api_scheduling_block_and_reset_LDADD) $(LIBS)
+test_ats_api_scheduling_check_min_bw_alt$(EXEEXT): $(test_ats_api_scheduling_check_min_bw_alt_OBJECTS) $(test_ats_api_scheduling_check_min_bw_alt_DEPENDENCIES) $(EXTRA_test_ats_api_scheduling_check_min_bw_alt_DEPENDENCIES)
+ @rm -f test_ats_api_scheduling_check_min_bw_alt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_check_min_bw_alt_OBJECTS) $(test_ats_api_scheduling_check_min_bw_alt_LDADD) $(LIBS)
+test_ats_api_scheduling_destroy_address$(EXEEXT): $(test_ats_api_scheduling_destroy_address_OBJECTS) $(test_ats_api_scheduling_destroy_address_DEPENDENCIES) $(EXTRA_test_ats_api_scheduling_destroy_address_DEPENDENCIES)
+ @rm -f test_ats_api_scheduling_destroy_address$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_destroy_address_OBJECTS) $(test_ats_api_scheduling_destroy_address_LDADD) $(LIBS)
+test_ats_api_scheduling_destroy_inbound_connection$(EXEEXT): $(test_ats_api_scheduling_destroy_inbound_connection_OBJECTS) $(test_ats_api_scheduling_destroy_inbound_connection_DEPENDENCIES) $(EXTRA_test_ats_api_scheduling_destroy_inbound_connection_DEPENDENCIES)
+ @rm -f test_ats_api_scheduling_destroy_inbound_connection$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_destroy_inbound_connection_OBJECTS) $(test_ats_api_scheduling_destroy_inbound_connection_LDADD) $(LIBS)
+test_ats_api_scheduling_destroy_session$(EXEEXT): $(test_ats_api_scheduling_destroy_session_OBJECTS) $(test_ats_api_scheduling_destroy_session_DEPENDENCIES) $(EXTRA_test_ats_api_scheduling_destroy_session_DEPENDENCIES)
+ @rm -f test_ats_api_scheduling_destroy_session$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_destroy_session_OBJECTS) $(test_ats_api_scheduling_destroy_session_LDADD) $(LIBS)
+test_ats_api_scheduling_init$(EXEEXT): $(test_ats_api_scheduling_init_OBJECTS) $(test_ats_api_scheduling_init_DEPENDENCIES) $(EXTRA_test_ats_api_scheduling_init_DEPENDENCIES)
+ @rm -f test_ats_api_scheduling_init$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_init_OBJECTS) $(test_ats_api_scheduling_init_LDADD) $(LIBS)
+test_ats_api_scheduling_min_bw$(EXEEXT): $(test_ats_api_scheduling_min_bw_OBJECTS) $(test_ats_api_scheduling_min_bw_DEPENDENCIES) $(EXTRA_test_ats_api_scheduling_min_bw_DEPENDENCIES)
+ @rm -f test_ats_api_scheduling_min_bw$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_min_bw_OBJECTS) $(test_ats_api_scheduling_min_bw_LDADD) $(LIBS)
+test_ats_api_scheduling_update_address$(EXEEXT): $(test_ats_api_scheduling_update_address_OBJECTS) $(test_ats_api_scheduling_update_address_DEPENDENCIES) $(EXTRA_test_ats_api_scheduling_update_address_DEPENDENCIES)
+ @rm -f test_ats_api_scheduling_update_address$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_api_scheduling_update_address_OBJECTS) $(test_ats_api_scheduling_update_address_LDADD) $(LIBS)
+test_ats_simplistic$(EXEEXT): $(test_ats_simplistic_OBJECTS) $(test_ats_simplistic_DEPENDENCIES) $(EXTRA_test_ats_simplistic_DEPENDENCIES)
+ @rm -f test_ats_simplistic$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_simplistic_OBJECTS) $(test_ats_simplistic_LDADD) $(LIBS)
+test_ats_simplistic_change_preference$(EXEEXT): $(test_ats_simplistic_change_preference_OBJECTS) $(test_ats_simplistic_change_preference_DEPENDENCIES) $(EXTRA_test_ats_simplistic_change_preference_DEPENDENCIES)
+ @rm -f test_ats_simplistic_change_preference$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_simplistic_change_preference_OBJECTS) $(test_ats_simplistic_change_preference_LDADD) $(LIBS)
+test_ats_simplistic_pref_aging$(EXEEXT): $(test_ats_simplistic_pref_aging_OBJECTS) $(test_ats_simplistic_pref_aging_DEPENDENCIES) $(EXTRA_test_ats_simplistic_pref_aging_DEPENDENCIES)
+ @rm -f test_ats_simplistic_pref_aging$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_simplistic_pref_aging_OBJECTS) $(test_ats_simplistic_pref_aging_LDADD) $(LIBS)
+test_ats_simplistic_switch_networks$(EXEEXT): $(test_ats_simplistic_switch_networks_OBJECTS) $(test_ats_simplistic_switch_networks_DEPENDENCIES) $(EXTRA_test_ats_simplistic_switch_networks_DEPENDENCIES)
+ @rm -f test_ats_simplistic_switch_networks$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_ats_simplistic_switch_networks_OBJECTS) $(test_ats_simplistic_switch_networks_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -672,38 +975,47 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats_addresses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats_addresses_mlp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats_addresses_simplistic.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats_performance.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats_reservations.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-ats_scheduling.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf_ats_mlp.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_reset_backoff.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_mlp.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_mlp_averaging.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_performance.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling_add_address.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling_add_session.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling_block_and_reset.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling_check_min_bw_alt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling_destroy_address.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling_destroy_inbound_connection.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling_destroy_session.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling_init.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling_min_bw.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_api_scheduling_update_address.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_simplistic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_simplistic_change_preference.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_simplistic_pref_aging.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ats_simplistic_switch_networks.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
@@ -712,8 +1024,11 @@ clean-libtool:
-rm -rf .libs _libs
install-pkgcfgDATA: $(pkgcfg_DATA)
@$(NORMAL_INSTALL)
- test -z "$(pkgcfgdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)"
@list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgcfgdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)" || exit 1; \
+ fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
@@ -727,9 +1042,7 @@ uninstall-pkgcfgDATA:
@$(NORMAL_UNINSTALL)
@list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
- test -n "$$files" || exit 0; \
- echo " ( cd '$(DESTDIR)$(pkgcfgdir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(pkgcfgdir)" && rm -f $$files
+ dir='$(DESTDIR)$(pkgcfgdir)'; $(am__uninstall_files_from_dir)
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -864,14 +1177,15 @@ check-TESTS: $(TESTS)
fi; \
dashes=`echo "$$dashes" | sed s/./=/g`; \
if test "$$failed" -eq 0; then \
- echo "$$grn$$dashes"; \
+ col="$$grn"; \
else \
- echo "$$red$$dashes"; \
+ col="$$red"; \
fi; \
- echo "$$banner"; \
- test -z "$$skipped" || echo "$$skipped"; \
- test -z "$$report" || echo "$$report"; \
- echo "$$dashes$$std"; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
test "$$failed" -eq 0; \
else :; fi
@@ -910,10 +1224,8 @@ check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA)
-install-binPROGRAMS: install-libLTLIBRARIES
-
installdirs:
- for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(pkgcfgdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -926,10 +1238,15 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
@@ -943,8 +1260,8 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
- clean-libLTLIBRARIES clean-libtool mostlyclean-am
+clean-am: clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
+ clean-libexecPROGRAMS clean-libtool mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
@@ -970,7 +1287,7 @@ install-dvi: install-dvi-am
install-dvi-am:
-install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
+install-exec-am: install-libLTLIBRARIES install-libexecPROGRAMS
install-html: install-html-am
@@ -1010,27 +1327,27 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
+uninstall-am: uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS \
uninstall-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-libLTLIBRARIES clean-libtool ctags distclean \
+ clean-checkPROGRAMS clean-generic clean-libLTLIBRARIES \
+ clean-libexecPROGRAMS 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-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-libLTLIBRARIES install-man install-pdf \
- install-pdf-am install-pkgcfgDATA install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am \
- uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
- uninstall-pkgcfgDATA
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-libLTLIBRARIES install-libexecPROGRAMS install-man \
+ install-pdf install-pdf-am install-pkgcfgDATA install-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-libLTLIBRARIES \
+ uninstall-libexecPROGRAMS uninstall-pkgcfgDATA
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/ats/ats.conf.in b/src/ats/ats.conf.in
index f81016e..bdc064e 100644
--- a/src/ats/ats.conf.in
+++ b/src/ats/ats.conf.in
@@ -3,7 +3,6 @@ AUTOSTART = YES
@UNIXONLY@ PORT = 2098
HOSTNAME = localhost
HOME = $SERVICEHOME
-CONFIG = $DEFAULTCONFIG
BINARY = gnunet-service-ats
ACCEPT_FROM = 127.0.0.1;
ACCEPT_FROM6 = ::1;
@@ -11,9 +10,12 @@ UNIXPATH = /tmp/gnunet-service-ats.sock
UNIX_MATCH_UID = YES
UNIX_MATCH_GID = YES
-# Enable MLP mode (default: NO)
-MLP = NO
+# Designated assigment mode: simplistic / MLP
+MODE = simplistic
+
# Network specific inbound/outbound quotas
+UNSPECIFIED_QUOTA_IN = 64 KiB
+UNSPECIFIED_QUOTA_OUT = 64 KiB
# LOOPBACK
LOOPBACK_QUOTA_IN = unlimited
LOOPBACK_QUOTA_OUT = unlimited
@@ -28,6 +30,13 @@ WLAN_QUOTA_IN = 1 MiB
WLAN_QUOTA_OUT = 1 MiB
# ATS options
+
+# MLP specific settings
+# MAX_DURATION = 3 s
+# MAX_ITERATIONS = 1024
+
+
+
DUMP_MLP = NO
DUMP_SOLUTION = NO
DUMP_OVERWRITE = NO
diff --git a/src/ats/ats.h b/src/ats/ats.h
index f4c3d9f..70b8826 100644
--- a/src/ats/ats.h
+++ b/src/ats/ats.h
@@ -170,6 +170,10 @@ struct PeerInformationMessage
uint32_t ats_count GNUNET_PACKED;
+ uint32_t address_active GNUNET_PACKED;
+
+ uint32_t id GNUNET_PACKED;
+
struct GNUNET_PeerIdentity peer;
uint16_t address_length GNUNET_PACKED;
@@ -188,6 +192,17 @@ struct PeerInformationMessage
};
+struct AddressListRequestMessage
+{
+ struct GNUNET_MessageHeader header;
+
+ uint32_t id GNUNET_PACKED;
+
+ int32_t all GNUNET_PACKED;
+
+ struct GNUNET_PeerIdentity peer;
+};
+
struct ReservationRequestMessage
{
diff --git a/src/ats/ats_api_performance.c b/src/ats/ats_api_performance.c
index c98e1c2..25b4926 100644
--- a/src/ats/ats_api_performance.c
+++ b/src/ats/ats_api_performance.c
@@ -106,6 +106,58 @@ struct GNUNET_ATS_ReservationContext
/**
+ * Linked list of pending reservations.
+ */
+struct GNUNET_ATS_AddressListHandle
+{
+
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_ATS_AddressListHandle *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_ATS_AddressListHandle *prev;
+
+ /**
+ * Performance handle
+ */
+ struct GNUNET_ATS_PerformanceHandle *ph;
+
+ /**
+ * Callback
+ */
+ GNUNET_ATS_PeerInformationCallback cb;
+
+ /**
+ * Callback closure
+ */
+ void *cb_cls;
+
+ /**
+ * Target peer.
+ */
+ struct GNUNET_PeerIdentity peer;
+
+ /**
+ * Return all or specific peer only
+ */
+ int all_peers;
+
+ /**
+ * Return all or used address only
+ */
+ int all_addresses;
+
+ /**
+ * Request multiplexing
+ */
+ uint32_t id;
+};
+
+/**
* ATS Handle to obtain and/or modify performance information.
*/
struct GNUNET_ATS_PerformanceHandle
@@ -152,6 +204,16 @@ struct GNUNET_ATS_PerformanceHandle
struct GNUNET_ATS_ReservationContext *reservation_tail;
/**
+ * Head of linked list of pending address list requests.
+ */
+ struct GNUNET_ATS_AddressListHandle *addresslist_head;
+
+ /**
+ * Tail of linked list of pending address list requests.
+ */
+ struct GNUNET_ATS_AddressListHandle *addresslist_tail;
+
+ /**
* Current request for transmission to ATS.
*/
struct GNUNET_CLIENT_TransmitHandle *th;
@@ -161,6 +223,10 @@ struct GNUNET_ATS_PerformanceHandle
*/
GNUNET_SCHEDULER_TaskIdentifier task;
+ /**
+ * Request multiplexing
+ */
+ uint32_t id;
};
@@ -276,16 +342,12 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph,
uint16_t plugin_name_length;
uint32_t ats_count;
- if (ph->infocb == NULL)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
if (ntohs (msg->size) < sizeof (struct PeerInformationMessage))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
+
pi = (const struct PeerInformationMessage *) msg;
ats_count = ntohl (pi->ats_count);
plugin_address_length = ntohs (pi->address_length);
@@ -303,6 +365,11 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph,
GNUNET_break (0);
return GNUNET_SYSERR;
}
+ if (ph->infocb == NULL)
+ {
+ return GNUNET_OK;
+ }
+
address.peer = pi->peer;
address.address = plugin_address;
address.address_length = plugin_address_length;
@@ -364,6 +431,110 @@ process_rr_message (struct GNUNET_ATS_PerformanceHandle *ph,
/**
+ * We received a reservation result message. Validate and process it.
+ *
+ * @param ph our context with the callback
+ * @param msg the message
+ * @return GNUNET_OK if the message was well-formed
+ */
+static int
+process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph,
+ const struct GNUNET_MessageHeader *msg)
+{
+ const struct PeerInformationMessage *pi;
+ struct GNUNET_ATS_AddressListHandle *alh;
+ struct GNUNET_ATS_AddressListHandle *next;
+ const struct GNUNET_ATS_Information *atsi;
+ const char *plugin_address;
+ const char *plugin_name;
+ struct GNUNET_HELLO_Address address;
+ struct GNUNET_PeerIdentity allzeros;
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_zero;
+ uint16_t plugin_address_length;
+ uint16_t plugin_name_length;
+ uint32_t ats_count;
+ uint32_t active;
+ uint32_t id;
+
+ if (ntohs (msg->size) < sizeof (struct PeerInformationMessage))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ _("Received %s message\n"), "ATS_ADDRESSLIST_RESPONSE");
+
+ pi = (const struct PeerInformationMessage *) msg;
+ id = ntohl (pi->id);
+ ats_count = ntohl (pi->ats_count);
+ active = ntohl (pi->address_active);
+ plugin_address_length = ntohs (pi->address_length);
+ plugin_name_length = ntohs (pi->plugin_name_length);
+ atsi = (const struct GNUNET_ATS_Information *) &pi[1];
+ plugin_address = (const char *) &atsi[ats_count];
+ plugin_name = &plugin_address[plugin_address_length];
+ if ((plugin_address_length + plugin_name_length +
+ ats_count * sizeof (struct GNUNET_ATS_Information) +
+ sizeof (struct PeerInformationMessage) != ntohs (msg->size)) ||
+ (ats_count >
+ GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information))
+ || (plugin_name[plugin_name_length - 1] != '\0'))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ next = ph->addresslist_head;
+ while (NULL != (alh = next))
+ {
+ next = alh->next;
+ if (alh->id == id)
+ break;
+ }
+ if (NULL == alh)
+ {
+ /* was canceled */
+ return GNUNET_SYSERR;
+ }
+
+ memset (&allzeros, '\0', sizeof (allzeros));
+ if ((0 == memcmp (&allzeros, &pi->peer, sizeof (allzeros))) &&
+ (0 == plugin_name_length) &&
+ (0 == plugin_address_length) &&
+ (0 == ats_count))
+ {
+ /* Done */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ _("Received last message for %s \n"), "ATS_ADDRESSLIST_RESPONSE");
+ bandwidth_zero.value__ = htonl (0);
+ if (NULL != alh->cb)
+ alh->cb (ph->infocb_cls,
+ NULL,
+ bandwidth_zero, bandwidth_zero,
+ NULL, 0);
+ GNUNET_CONTAINER_DLL_remove (ph->addresslist_head, ph->addresslist_tail, alh);
+ GNUNET_free (alh);
+ return GNUNET_OK;
+ }
+
+ address.peer = pi->peer;
+ address.address = plugin_address;
+ address.address_length = plugin_address_length;
+ address.transport_name = plugin_name;
+
+ if ((GNUNET_YES == alh->all_addresses) || (GNUNET_YES == active))
+ {
+ if (NULL != alh->cb)
+ alh->cb (ph->infocb_cls,
+ &address,
+ pi->bandwidth_out, pi->bandwidth_in,
+ atsi, ats_count);
+ }
+ return GNUNET_OK;
+}
+
+
+/**
* Type of a function to call when we receive a message
* from the service.
*
@@ -387,6 +558,10 @@ process_ats_message (void *cls, const struct GNUNET_MessageHeader *msg)
if (GNUNET_OK != process_rr_message (ph, msg))
goto reconnect;
break;
+ case GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE:
+ if (GNUNET_OK != process_ar_message (ph, msg))
+ goto reconnect;
+ break;
default:
GNUNET_break (0);
goto reconnect;
@@ -395,6 +570,11 @@ process_ats_message (void *cls, const struct GNUNET_MessageHeader *msg)
GNUNET_TIME_UNIT_FOREVER_REL);
return;
reconnect:
+ if (NULL != ph->th)
+ {
+ GNUNET_CLIENT_notify_transmit_ready_cancel (ph->th);
+ ph->th = NULL;
+ }
GNUNET_CLIENT_disconnect (ph->client);
ph->client = NULL;
ph->task =
@@ -458,6 +638,7 @@ GNUNET_ATS_performance_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
ph->cfg = cfg;
ph->infocb = infocb;
ph->infocb_cls = infocb_cls;
+ ph->id = 0;
reconnect (ph);
return ph;
}
@@ -473,12 +654,19 @@ GNUNET_ATS_performance_done (struct GNUNET_ATS_PerformanceHandle *ph)
{
struct PendingMessage *p;
struct GNUNET_ATS_ReservationContext *rc;
+ struct GNUNET_ATS_AddressListHandle *alh;
while (NULL != (p = ph->pending_head))
{
GNUNET_CONTAINER_DLL_remove (ph->pending_head, ph->pending_tail, p);
GNUNET_free (p);
}
+ while (NULL != (alh = ph->addresslist_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (ph->addresslist_head, ph->addresslist_tail,
+ alh);
+ GNUNET_free (alh);
+ }
while (NULL != (rc = ph->reservation_head))
{
GNUNET_CONTAINER_DLL_remove (ph->reservation_head, ph->reservation_tail,
@@ -560,6 +748,102 @@ GNUNET_ATS_reserve_bandwidth_cancel (struct GNUNET_ATS_ReservationContext *rc)
rc->rcb = NULL;
}
+/**
+ * Get information about addresses known to the ATS subsystem.
+ *
+ * @param handle the performance handle to use
+ * @param peer peer idm can be NULL for all peers
+ * @param all GNUNET_YES to get information about all addresses or GNUNET_NO to
+ * get only address currently used
+ * @param infocb callback to call with the addresses,
+ * will callback with address == NULL when done
+ * @param infocb_cls closure for infocb
+ * @return ats performance context
+ */
+struct GNUNET_ATS_AddressListHandle*
+GNUNET_ATS_performance_list_addresses (struct GNUNET_ATS_PerformanceHandle *handle,
+ const struct GNUNET_PeerIdentity *peer,
+ int all,
+ GNUNET_ATS_PeerInformationCallback infocb,
+ void *infocb_cls)
+{
+ struct GNUNET_ATS_AddressListHandle *alh;
+ struct PendingMessage *p;
+ struct AddressListRequestMessage *m;
+
+ GNUNET_assert (NULL != handle);
+ if (NULL == infocb)
+ return NULL;
+
+ alh = GNUNET_malloc (sizeof (struct GNUNET_ATS_AddressListHandle));
+ alh->id = handle->id;
+ handle->id ++;
+ alh->cb = infocb;
+ alh->cb_cls = infocb_cls;
+ alh->ph = handle;
+ alh->all_addresses = all;
+ if (NULL == peer)
+ alh->all_peers = GNUNET_YES;
+ else
+ {
+ alh->all_peers = GNUNET_NO;
+ alh->peer = (*peer);
+ }
+
+ GNUNET_CONTAINER_DLL_insert (handle->addresslist_head, handle->addresslist_tail, alh);
+
+ p = GNUNET_malloc (sizeof (struct PendingMessage) +
+ sizeof (struct AddressListRequestMessage));
+ p->size = sizeof (struct AddressListRequestMessage);
+ m = (struct AddressListRequestMessage *) &p[1];
+ m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_REQUEST);
+ m->header.size = htons (sizeof (struct AddressListRequestMessage));
+ m->all = htonl (all);
+ m->id = htonl (alh->id);
+ if (NULL != peer)
+ m->peer = *peer;
+ else
+ {
+ memset (&m->peer, '\0', sizeof (struct GNUNET_PeerIdentity));
+ }
+ GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail, p);
+
+ do_transmit (handle);
+
+ return alh;
+}
+
+
+/**
+ * Cancel a pending address listing operation
+ *
+ * @param handle the GNUNET_ATS_AddressListHandle handle to cancel
+ */
+void
+GNUNET_ATS_performance_list_addresses_cancel (struct GNUNET_ATS_AddressListHandle *handle)
+{
+ GNUNET_assert (NULL != handle);
+
+ GNUNET_CONTAINER_DLL_remove (handle->ph->addresslist_head, handle->ph->addresslist_tail, handle);
+ GNUNET_free (handle);
+}
+
+
+/**
+ * Convert a GNUNET_ATS_PreferenceType to a string
+ *
+ * @param type the preference type
+ * @return a string or NULL if invalid
+ */
+const char *
+GNUNET_ATS_print_preference_type (uint32_t type)
+{
+ char *prefs[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString;
+ if (type < GNUNET_ATS_PreferenceCount)
+ return prefs[type];
+ return NULL;
+}
+
/**
* Change preferences for the given peer. Preference changes are forgotten if peers
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index 5a4e883..dce267e 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -30,6 +30,8 @@
#define INTERFACE_PROCESSING_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
+#define NOT_FOUND 0
+
/**
* Message in linked list we should send to the ATS service. The
* actual binary message follows this struct.
@@ -92,6 +94,15 @@ struct ATS_Network
socklen_t length;
};
+/**
+ * Handle for address suggestions
+ */
+struct GNUNET_ATS_SuggestHandle
+{
+ struct GNUNET_ATS_SuggestHandle *prev;
+ struct GNUNET_ATS_SuggestHandle *next;
+ struct GNUNET_PeerIdentity id;
+};
/**
@@ -116,6 +127,16 @@ struct GNUNET_ATS_SchedulingHandle
void *suggest_cb_cls;
/**
+ * DLL for suggestions head
+ */
+ struct GNUNET_ATS_SuggestHandle *sug_head;
+
+ /**
+ * DLL for suggestions tail
+ */
+ struct GNUNET_ATS_SuggestHandle *sug_tail;
+
+ /**
* Connection to ATS service.
*/
struct GNUNET_CLIENT_Connection *client;
@@ -344,13 +365,28 @@ find_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id,
sh->reconnect = GNUNET_YES;
return NULL;
}
+ /* This check exploits the fact that first field of a session object
+ * is peer identity.
+ */
+ if (0 !=
+ memcmp (peer, sh->session_array[session_id].session,
+ sizeof (struct GNUNET_PeerIdentity)))
+ {
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api",
+ "Session %p belongs to peer `%s'\n",
+ sh->session_array[session_id].session, GNUNET_i2s_full ((struct GNUNET_PeerIdentity *) &sh->session_array[session_id].peer));
+/*
+ GNUNET_break (0);
+ sh->reconnect = GNUNET_YES;
+ return NULL;
+*/
+ }
return sh->session_array[session_id].session;
}
/**
- * Get the ID for the given session object. If we do not have an ID for
- * the given session object, allocate one.
+ * Get an available session ID for the given session object.
*
* @param sh our handle
* @param session session object
@@ -358,29 +394,21 @@ find_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id,
* @return the session id
*/
static uint32_t
-get_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session,
+find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session,
const struct GNUNET_PeerIdentity *peer)
{
unsigned int i;
unsigned int f;
-
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api",
"Get session ID for session %p from peer %s in %p\n", session,
GNUNET_i2s (peer), sh);
if (NULL == session)
- return 0;
+ return NOT_FOUND;
f = 0;
for (i = 1; i < sh->session_array_size; i++)
{
- if (session == sh->session_array[i].session)
- {
- GNUNET_assert (0 ==
- memcmp (peer, &sh->session_array[i].peer,
- sizeof (struct GNUNET_PeerIdentity)));
- return i;
- }
if ((f == 0) && (sh->session_array[i].slot_used == GNUNET_NO))
f = i;
}
@@ -404,6 +432,48 @@ get_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session,
/**
+ * Get the ID for the given session object.
+ *
+ * @param sh our handle
+ * @param session session object
+ * @param peer peer the session belongs to
+ * @return the session id or NOT_FOUND for error
+ */
+static uint32_t
+find_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session,
+ const struct GNUNET_PeerIdentity *peer)
+{
+ unsigned int i;
+ char * p2;
+
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api",
+ "Get session ID for session %p from peer %s in %p\n", session,
+ GNUNET_i2s (peer), sh);
+
+ if (NULL == session)
+ return NOT_FOUND;
+ for (i = 1; i < sh->session_array_size; i++)
+ {
+ if (session == sh->session_array[i].session)
+ {
+ if (0 != memcmp (peer, &sh->session_array[i].peer,
+ sizeof (struct GNUNET_PeerIdentity)))
+ {
+ p2 = strdup (GNUNET_i2s (&sh->session_array[i].peer));
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "ats-scheduling-api",
+ "Session %p did not match: old session was for peer `%s' new session is for `%s'\n",
+ session, GNUNET_i2s (peer), p2);
+ GNUNET_free (p2);
+ return NOT_FOUND;
+ }
+ return i;
+ }
+ }
+ return NOT_FOUND;
+}
+
+
+/**
* Remove the session of the given session ID from the session
* table (it is no longer valid).
*
@@ -424,12 +494,19 @@ remove_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id,
if (0 == session_id)
return;
+
GNUNET_assert (session_id < sh->session_array_size);
GNUNET_assert (GNUNET_YES == sh->session_array[session_id].slot_used);
- GNUNET_assert (0 ==
- memcmp (peer, &sh->session_array[session_id].peer,
- sizeof (struct GNUNET_PeerIdentity)));
+ GNUNET_assert (0 == memcmp (peer,
+ &sh->session_array[session_id].peer,
+ sizeof (struct GNUNET_PeerIdentity)));
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api",
+ "Session %p for peer `%s' removed from slot %u \n",
+ sh->session_array[session_id].session,
+ GNUNET_i2s (peer),
+ session_id);
sh->session_array[session_id].session = NULL;
+
}
@@ -750,6 +827,21 @@ get_addresses (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
sh);
}
+/**
+ * Convert a GNUNET_ATS_NetworkType to a string
+ *
+ * @param net the network type
+ * @return a string or NULL if invalid
+ */
+const char *
+GNUNET_ATS_print_network_type (uint32_t net)
+{
+ char *networks[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkTypeString;
+ if (net < GNUNET_ATS_NetworkTypeCount)
+ return networks[net];
+ return NULL;
+}
+
/**
* Returns where the address is located: LAN or WAN or ...
@@ -763,9 +855,10 @@ struct GNUNET_ATS_Information
GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const struct sockaddr * addr, socklen_t addrlen)
{
GNUNET_assert (sh != NULL);
- struct GNUNET_ATS_Information ats;
struct ATS_Network * cur = sh->net_head;
+
int type = GNUNET_ATS_NET_UNSPECIFIED;
+ struct GNUNET_ATS_Information ats;
if (addr->sa_family == AF_UNIX)
{
@@ -804,15 +897,7 @@ GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const stru
struct sockaddr_in * mask4 = (struct sockaddr_in *) cur->netmask;
if (((a4->sin_addr.s_addr & mask4->sin_addr.s_addr)) == net4->sin_addr.s_addr)
- {
- char * net = GNUNET_strdup (GNUNET_a2s ((const struct sockaddr *) net4, addrlen));
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api",
- "`%s' is in network `%s'\n",
- GNUNET_a2s ((const struct sockaddr *)a4, addrlen),
- net);
- GNUNET_free (net);
type = GNUNET_ATS_NET_LAN;
- }
}
if (addr->sa_family == AF_INET6)
{
@@ -830,14 +915,7 @@ GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const stru
res = GNUNET_NO;
if (res == GNUNET_YES)
- {
- char * net = GNUNET_strdup (GNUNET_a2s ((const struct sockaddr *) net6, addrlen));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "`%s' is in network `%s'\n",
- GNUNET_a2s ((const struct sockaddr *) a6, addrlen),
- net);
- GNUNET_free (net);
type = GNUNET_ATS_NET_LAN;
- }
}
cur = cur->next;
}
@@ -847,7 +925,12 @@ GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle * sh, const stru
type = GNUNET_ATS_NET_WAN;
ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
ats.value = htonl (type);
- return (const struct GNUNET_ATS_Information) ats;
+
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api",
+ "`%s' is in network `%s'\n",
+ GNUNET_a2s ((const struct sockaddr *) addr, addrlen),
+ GNUNET_ATS_print_network_type(type));
+ return ats;
}
@@ -889,7 +972,8 @@ void
GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh)
{
struct PendingMessage *p;
-
+ struct GNUNET_ATS_SuggestHandle *cur;
+ struct GNUNET_ATS_SuggestHandle *next;
while (NULL != (p = sh->pending_head))
{
GNUNET_CONTAINER_DLL_remove (sh->pending_head, sh->pending_tail, p);
@@ -906,6 +990,14 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh)
sh->task = GNUNET_SCHEDULER_NO_TASK;
}
+ next = sh->sug_head;
+ while (NULL != (cur = next))
+ {
+ next = cur->next;
+ GNUNET_CONTAINER_DLL_remove (sh->sug_head, sh->sug_tail, cur);
+ GNUNET_free (cur);
+ }
+
delete_networks (sh);
if (sh->interface_task != GNUNET_SCHEDULER_NO_TASK)
{
@@ -950,13 +1042,15 @@ GNUNET_ATS_reset_backoff (struct GNUNET_ATS_SchedulingHandle *sh,
*
* @param sh handle
* @param peer identity of the peer we need an address for
+ * @return suggest handle
*/
-void
+struct GNUNET_ATS_SuggestHandle *
GNUNET_ATS_suggest_address (struct GNUNET_ATS_SchedulingHandle *sh,
const struct GNUNET_PeerIdentity *peer)
{
struct PendingMessage *p;
struct RequestAddressMessage *m;
+ struct GNUNET_ATS_SuggestHandle *s;
// FIXME: ATS needs to remember this in case of
// a disconnect!
@@ -971,6 +1065,10 @@ GNUNET_ATS_suggest_address (struct GNUNET_ATS_SchedulingHandle *sh,
m->peer = *peer;
GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p);
do_transmit (sh);
+ s = GNUNET_malloc (sizeof (struct GNUNET_ATS_SuggestHandle));
+ s->id = (*peer);
+ GNUNET_CONTAINER_DLL_insert_tail (sh->sug_head, sh->sug_tail, s);
+ return s;
}
@@ -986,6 +1084,21 @@ GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh,
{
struct PendingMessage *p;
struct RequestAddressMessage *m;
+ struct GNUNET_ATS_SuggestHandle *s;
+
+ for (s = sh->sug_head; NULL != s; s = s->next)
+ if (0 == memcmp(peer, &s->id, sizeof (s->id)))
+ break;
+ if (NULL == s)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ else
+ {
+ GNUNET_CONTAINER_DLL_remove (sh->sug_head, sh->sug_tail, s);
+ GNUNET_free (s);
+ }
p = GNUNET_malloc (sizeof (struct PendingMessage) +
sizeof (struct RequestAddressMessage));
@@ -1002,6 +1115,101 @@ GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh,
/**
+ * We have a new address ATS should know. Addresses have to be added with this
+ * function before they can be: updated, set in use and destroyed
+ *
+ * @param sh handle
+ * @param address the address
+ * @param session session handle, can be NULL
+ * @param ats performance data for the address
+ * @param ats_count number of performance records in 'ats'
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
+ */
+int
+GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
+ const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ const struct GNUNET_ATS_Information *ats,
+ uint32_t ats_count)
+{
+
+ struct PendingMessage *p;
+ struct AddressUpdateMessage *m;
+ struct GNUNET_ATS_Information *am;
+ char *pm;
+ size_t namelen;
+ size_t msize;
+ uint32_t s = 0;
+
+ if (address == NULL)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ namelen =
+ (address->transport_name ==
+ NULL) ? 0 : strlen (address->transport_name) + 1;
+ msize =
+ sizeof (struct AddressUpdateMessage) + address->address_length +
+ ats_count * sizeof (struct GNUNET_ATS_Information) + namelen;
+ if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
+ (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
+ (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
+ (ats_count >=
+ GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+
+ if (NULL != session)
+ {
+ s = find_session_id (sh, session, &address->peer);
+ if (NOT_FOUND != s)
+ {
+ /* Already existing, nothing todo */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding duplicate address for peer `%s', plugin `%s', session %p id %u\n",
+ GNUNET_i2s (&address->peer),
+ address->transport_name, session, s);
+ return GNUNET_SYSERR;
+ }
+ s = find_empty_session_slot (sh, session, &address->peer);
+ GNUNET_break (NOT_FOUND != s);
+ }
+
+ p = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
+ p->size = msize;
+ p->is_init = GNUNET_NO;
+ m = (struct AddressUpdateMessage *) &p[1];
+ m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD);
+ m->header.size = htons (msize);
+ m->ats_count = htonl (ats_count);
+ m->peer = address->peer;
+ m->address_length = htons (address->address_length);
+ m->plugin_name_length = htons (namelen);
+ m->session_id = htonl (s);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding address for peer `%s', plugin `%s', session %p id %u\n",
+ GNUNET_i2s (&address->peer),
+ address->transport_name, session, s);
+
+ am = (struct GNUNET_ATS_Information *) &m[1];
+ memcpy (am, ats, ats_count * sizeof (struct GNUNET_ATS_Information));
+ pm = (char *) &am[ats_count];
+ memcpy (pm, address->address, address->address_length);
+ if (NULL != address->transport_name)
+ memcpy (&pm[address->address_length], address->transport_name, namelen);
+ GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p);
+ do_transmit (sh);
+ return GNUNET_OK;
+
+}
+
+
+/**
* We have updated performance statistics for a given address. Note
* that this function can be called for addresses that are currently
* in use as well as addresses that are valid but not actively in use.
@@ -1011,7 +1219,7 @@ GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh,
*
* @param sh handle
* @param address the address
- * @param session session handle (if available)
+ * @param session session handle, can be NULL
* @param ats performance data for the address
* @param ats_count number of performance records in 'ats'
*/
@@ -1028,17 +1236,13 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh,
char *pm;
size_t namelen;
size_t msize;
+ uint32_t s = 0;
if (address == NULL)
{
GNUNET_break (0);
return;
}
- if ((address == NULL) && (session == NULL))
- {
- GNUNET_break (0);
- return;
- }
namelen =
(address->transport_name ==
@@ -1056,6 +1260,21 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh,
return;
}
+ if (NULL != session)
+ {
+ s = find_session_id (sh, session, &address->peer);
+ if (NOT_FOUND == s)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Update for unknown address for peer `%s', plugin `%s', session %p id %u\n",
+ GNUNET_i2s (&address->peer),
+ address->transport_name, session, s);
+
+ GNUNET_break (0);
+ return;
+ }
+ }
+
p = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
p->size = msize;
p->is_init = GNUNET_NO;
@@ -1066,7 +1285,14 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh,
m->peer = address->peer;
m->address_length = htons (address->address_length);
m->plugin_name_length = htons (namelen);
- m->session_id = htonl (get_session_id (sh, session, &address->peer));
+
+ m->session_id = htonl (s);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Updating address for peer `%s', plugin `%s', session %p id %u\n",
+ GNUNET_i2s (&address->peer),
+ address->transport_name, session, s);
+
am = (struct GNUNET_ATS_Information *) &m[1];
memcpy (am, ats, ats_count * sizeof (struct GNUNET_ATS_Information));
pm = (char *) &am[ats_count];
@@ -1074,6 +1300,7 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh,
memcpy (&pm[address->address_length], address->transport_name, namelen);
GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p);
do_transmit (sh);
+ return;
}
@@ -1082,7 +1309,7 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh,
*
* @param sh handle
* @param address the address
- * @param session session handle
+ * @param session session handle, can be NULL
* @param in_use GNUNET_YES if this address is now used, GNUNET_NO
* if address is not used any more
*/
@@ -1096,6 +1323,7 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh,
char *pm;
size_t namelen;
size_t msize;
+ uint32_t s = 0;
GNUNET_assert (NULL != address);
namelen =
@@ -1110,6 +1338,26 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh,
return;
}
+ if (session != NULL)
+ {
+ s = find_session_id (sh, session, &address->peer);
+ if ((s == NOT_FOUND) && (GNUNET_NO == in_use))
+ {
+ /* trying to set unknown address to NO */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Trying to set unknown address to unused for peer `%s', plugin `%s', session %p\n",
+ GNUNET_i2s (&address->peer), address->transport_name, session);
+ GNUNET_break (0);
+ return;
+ }
+ if ((s == NOT_FOUND) && (GNUNET_YES == in_use))
+ {
+ /* trying to set new address to YES */
+ s = find_empty_session_slot (sh, session, &address->peer);
+ GNUNET_assert (NOT_FOUND != s);
+ }
+ }
+
p = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
p->size = msize;
p->is_init = GNUNET_NO;
@@ -1120,12 +1368,19 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh,
m->in_use = htons (in_use);
m->address_length = htons (address->address_length);
m->plugin_name_length = htons (namelen);
- m->session_id = htonl (get_session_id (sh, session, &address->peer));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Setting address used to %s for peer `%s', plugin `%s', session %p\n",
+ (GNUNET_YES == in_use) ? "YES" : "NO",
+ GNUNET_i2s (&address->peer), address->transport_name, session);
+
+ m->session_id = htonl (s);
pm = (char *) &m[1];
memcpy (pm, address->address, address->address_length);
memcpy (&pm[address->address_length], address->transport_name, namelen);
GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p);
do_transmit (sh);
+ return;
}
@@ -1134,7 +1389,7 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh,
*
* @param sh handle
* @param address the address
- * @param session session handle that is no longer valid
+ * @param session session handle that is no longer valid, can be NULL
*/
void
GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh,
@@ -1146,7 +1401,13 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh,
char *pm;
size_t namelen;
size_t msize;
- uint32_t session_id;
+ uint32_t s = 0;
+
+ if (address == NULL)
+ {
+ GNUNET_break (0);
+ return;
+ }
GNUNET_assert (address->transport_name != NULL);
namelen = strlen (address->transport_name) + 1;
@@ -1162,6 +1423,16 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh,
return;
}
+ s = find_session_id (sh, session, &address->peer);
+ if ((NULL != session) && (NOT_FOUND == s))
+ {
+ /* trying to delete unknown address */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Trying to delete unknown address for peer `%s', plugin `%s', session %p\n",
+ GNUNET_i2s (&address->peer), address->transport_name, session);
+ return;
+ }
+
p = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
p->size = msize;
p->is_init = GNUNET_NO;
@@ -1172,14 +1443,18 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh,
m->peer = address->peer;
m->address_length = htons (address->address_length);
m->plugin_name_length = htons (namelen);
- session_id = get_session_id (sh, session, &address->peer);
- m->session_id = htonl (session_id);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Deleting address for peer `%s', plugin `%s', session %p\n",
+ GNUNET_i2s (&address->peer), address->transport_name, session);
+
+ m->session_id = htonl (s);
pm = (char *) &m[1];
memcpy (pm, address->address, address->address_length);
memcpy (&pm[address->address_length], address->transport_name, namelen);
GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p);
do_transmit (sh);
- remove_session (sh, session_id, &address->peer);
+ remove_session (sh, s, &address->peer);
}
/* end of ats_api_scheduling.c */
diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c
index aef72f1..3218769 100644
--- a/src/ats/gnunet-service-ats.c
+++ b/src/ats/gnunet-service-ats.c
@@ -41,6 +41,7 @@ struct GNUNET_STATISTICS_Handle *GSA_stats;
static struct GNUNET_SERVER_Handle *GSA_server;
+struct GAS_Addresses_Handle *GSA_addresses;
/**
* We have received a 'ClientStartMessage' from a client. Find out which
@@ -109,7 +110,7 @@ client_disconnect_handler (void *cls, struct GNUNET_SERVER_Client *client)
static void
cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- GAS_addresses_done ();
+ GAS_addresses_done (GSA_addresses);
GAS_scheduling_done ();
GAS_performance_done ();
GAS_reservations_done ();
@@ -142,6 +143,11 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
{&GAS_handle_request_address_cancel, NULL,
GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL,
sizeof (struct RequestAddressMessage)},
+ {&GAS_handle_request_address_list, NULL,
+ GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_REQUEST,
+ sizeof (struct AddressListRequestMessage)},
+ {&GAS_handle_address_add, NULL,
+ GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD, 0},
{&GAS_handle_address_update, NULL,
GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE, 0},
{&GAS_handle_address_in_use, NULL,
@@ -161,9 +167,10 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
GSA_server = server;
GSA_stats = GNUNET_STATISTICS_create ("ats", cfg);
GAS_reservations_init ();
- GAS_performance_init (server);
- GAS_scheduling_init (server);
- GAS_addresses_init (cfg, GSA_stats);
+ GSA_addresses = GAS_addresses_init (cfg, GSA_stats);
+ GAS_performance_init (server, GSA_addresses);
+ GAS_scheduling_init (server, GSA_addresses);
+
GNUNET_SERVER_disconnect_notify (server, &client_disconnect_handler, NULL);
GNUNET_SERVER_add_handlers (server, handlers);
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task,
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c
index 9bf5ca6..e890aaa 100644
--- a/src/ats/gnunet-service-ats_addresses.c
+++ b/src/ats/gnunet-service-ats_addresses.c
@@ -34,104 +34,244 @@
#if HAVE_LIBGLPK
#include "gnunet-service-ats_addresses_mlp.h"
#endif
+#include "gnunet-service-ats_addresses_simplistic.h"
-#define VERBOSE GNUNET_NO
+/**
+ * ATS address management
+ *
+ * Adding addresses:
+ *
+ * - If you add a new address without a session, a new address will be added
+ * - If you add this address again now with a session a, the existing address
+ * will be updated with this session
+ * - If you add this address again now with a session b, a new address object
+ * with this session will be added
-#define ATS_BLOCKING_DELTA GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 100)
+ * Destroying addresses:
+ *
+ * - If you destroy an address without a session, the address itself and all
+ * address instances with an session will be removed
+ * - If you destroy an address with a session, the session for this address
+ * will be removed
+ *
+ * Conclusion
+ * Addresses without a session will be updated with a new session and if the
+ * the session is destroyed the session is removed and address itself still
+ * exists for suggestion
+ *
+ */
+
+/**
+ * Available ressource assignment modes
+ */
enum ATS_Mode
{
/*
+ * Simplistic mode:
+ *
* Assign each peer an equal amount of bandwidth (bw)
*
* bw_per_peer = bw_total / #active addresses
*/
- SIMPLE,
+ MODE_SIMPLISTIC,
/*
- * Use MLP solver to assign bandwidth
+ * MLP mode:
+ *
+ * Solve ressource assignment as an optimization problem
+ * Uses an mixed integer programming solver
*/
- MLP
+ MODE_MLP
};
-static struct GNUNET_CONTAINER_MultiHashMap *addresses;
+/**
+ * Pending Address suggestion requests
+ */
+struct GAS_Addresses_Suggestion_Requests
+{
+ /**
+ * Next in DLL
+ */
+ struct GAS_Addresses_Suggestion_Requests *next;
-#if HAVE_LIBGLPK
-static struct GAS_MLP_Handle *mlp;
-#endif
+ /**
+ * Previous in DLL
+ */
+ struct GAS_Addresses_Suggestion_Requests *prev;
-static unsigned long long wan_quota_in;
+ /**
+ * Peer ID
+ */
+ struct GNUNET_PeerIdentity id;
+};
-static unsigned long long wan_quota_out;
+/**
+ * Handle for ATS address component
+ */
+struct GAS_Addresses_Handle
+{
+ /**
+ *
+ */
+ struct GNUNET_STATISTICS_Handle *stat;
-static unsigned int active_addr_count;
+ /**
+ * A multihashmap to store all addresses
+ */
+ struct GNUNET_CONTAINER_MultiHashMap *addresses;
-static int ats_mode;
+ /**
+ * Configure WAN quota in
+ */
+ unsigned long long wan_quota_in;
-static int running;
+ /**
+ * Configure WAN quota out
+ */
+ unsigned long long wan_quota_out;
+ /**
+ * Is ATS addresses running
+ */
+ int running;
-static void
-send_bw_notification (struct ATS_Address *aa)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New bandwidth for peer %s is %u/%u\n",
- GNUNET_i2s (&aa->peer), ntohl (aa->assigned_bw_in.value__),
- ntohl (aa->assigned_bw_out.value__));
- GAS_scheduling_transmit_address_suggestion (&aa->peer, aa->plugin, aa->addr,
- aa->addr_len, aa->session_id,
- aa->ats, aa->ats_count,
- aa->assigned_bw_out,
- aa->assigned_bw_in);
- GAS_reservations_set_bandwidth (&aa->peer, aa->assigned_bw_in);
- GAS_performance_notify_clients (&aa->peer, aa->plugin, aa->addr, aa->addr_len,
- aa->ats, aa->ats_count, aa->assigned_bw_out,
- aa->assigned_bw_in);
-}
+ /**
+ * Configured ATS solver
+ */
+ int ats_mode;
-/**
- * Update a bandwidth assignment for a peer. This trivial method currently
- * simply assigns the same share to all active connections.
- *
- * @param cls unused
- * @param key unused
- * @param value the 'struct ATS_Address'
- * @return GNUNET_OK (continue to iterate)
- */
-static int
-update_bw_simple_it (void *cls, const GNUNET_HashCode * key, void *value)
-{
- struct ATS_Address *aa = value;
+ /**
+ * Solver handle
+ */
+ void *solver;
+
+ /**
+ * Address suggestion requests DLL head
+ */
+ struct GAS_Addresses_Suggestion_Requests *r_head;
+
+ /**
+ * Address suggestion requests DLL tail
+ */
+ struct GAS_Addresses_Suggestion_Requests *r_tail;
+
+ /* Solver functions */
- if (GNUNET_YES != aa->active)
- return GNUNET_OK;
- GNUNET_assert (active_addr_count > 0);
+ /**
+ * Initialize solver
+ */
+ GAS_solver_init s_init;
+ /**
+ * Add an address to the solver
+ */
+ GAS_solver_address_add s_add;
- /* Simple method */
- aa->assigned_bw_in.value__ = htonl (wan_quota_in / active_addr_count);
- aa->assigned_bw_out.value__ = htonl (wan_quota_out / active_addr_count);
+ /**
+ * Update address in solver
+ */
+ GAS_solver_address_update s_update;
- send_bw_notification (aa);
+ /**
+ * Get address from solver
+ */
+ GAS_solver_get_preferred_address s_get;
- return GNUNET_OK;
-}
+ /**
+ * Delete address in solver
+ */
+ GAS_solver_address_delete s_del;
+ /**
+ * Change preference for quality in solver
+ */
+ GAS_solver_address_change_preference s_pref;
-/**
- * Some (significant) input changed, recalculate bandwidth assignment
- * for all peers.
- */
-static void
-recalculate_assigned_bw ()
+ /**
+ * Shutdown solver
+ */
+ GAS_solver_done s_done;
+};
+
+
+static unsigned int
+assemble_ats_information (const struct ATS_Address *aa, struct GNUNET_ATS_Information **dest)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Recalculating bandwidth for all active connections\n");
- GNUNET_STATISTICS_update (GSA_stats, "# bandwidth recalculations performed",
- 1, GNUNET_NO);
- GNUNET_STATISTICS_set (GSA_stats, "# active addresses", active_addr_count,
- GNUNET_NO);
+ unsigned int ats_count = GNUNET_ATS_PropertyCount - 1;
+ struct GNUNET_ATS_Information *ats = GNUNET_malloc (ats_count * sizeof (struct GNUNET_ATS_Information));
+ (*dest) = ats;
+
+ ats[0].type = ntohl(GNUNET_ATS_UTILIZATION_UP);
+ ats[0].value = aa->atsp_utilization_out.value__;
+ ats[1].type = ntohl(GNUNET_ATS_UTILIZATION_DOWN);
+ ats[1].value = aa->atsp_utilization_in.value__;
+ ats[2].type = ntohl(GNUNET_ATS_NETWORK_TYPE);
+ ats[2].value = ntohl(aa->atsp_network_type);
+ ats[3].type = ntohl(GNUNET_ATS_QUALITY_NET_DELAY);
+ ats[3].value = ntohl(aa->atsp_latency.rel_value);
+ ats[4].type = ntohl(GNUNET_ATS_QUALITY_NET_DISTANCE);
+ ats[4].value = ntohl(aa->atsp_distance);
+ ats[5].type = ntohl(GNUNET_ATS_COST_WAN);
+ ats[5].value = ntohl (aa->atsp_cost_wan);
+ ats[6].type = ntohl(GNUNET_ATS_COST_LAN);
+ ats[6].value = ntohl (aa->atsp_cost_lan);
+ ats[7].type = ntohl(GNUNET_ATS_COST_WLAN);
+ ats[7].value = ntohl (aa->atsp_cost_wlan);
+ return ats_count;
+}
- GNUNET_CONTAINER_multihashmap_iterate (addresses, &update_bw_simple_it, NULL);
+static unsigned int
+disassemble_ats_information (const struct GNUNET_ATS_Information *src,
+ uint32_t ats_count,
+ struct ATS_Address *dest)
+{
+ int i;
+ int res = 0;
+ for (i = 0; i < ats_count; i++)
+ switch (ntohl (src[i].type))
+ {
+ case GNUNET_ATS_UTILIZATION_UP:
+ dest->atsp_utilization_out.value__ = src[i].value;
+ res ++;
+ break;
+ case GNUNET_ATS_UTILIZATION_DOWN:
+ dest->atsp_utilization_in.value__ = src[i].value;
+ res ++;
+ break;
+ case GNUNET_ATS_QUALITY_NET_DELAY:
+ dest->atsp_latency.rel_value = ntohl (src[i].value);
+ res ++;
+ break;
+ case GNUNET_ATS_QUALITY_NET_DISTANCE:
+ dest->atsp_distance = ntohl (src[i].value);
+ res ++;
+ break;
+ case GNUNET_ATS_COST_WAN:
+ dest->atsp_cost_wan = ntohl (src[i].value);
+ res ++;
+ break;
+ case GNUNET_ATS_COST_LAN:
+ dest->atsp_cost_lan = ntohl (src[i].value);
+ res ++;
+ break;
+ case GNUNET_ATS_COST_WLAN:
+ dest->atsp_cost_wlan = ntohl (src[i].value);
+ res ++;
+ break;
+ case GNUNET_ATS_NETWORK_TYPE:
+ dest->atsp_network_type = ntohl (src[i].value);
+ res ++;
+ break;
+ case GNUNET_ATS_ARRAY_TERMINATOR:
+ break;
+ default:
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Received unsupported ATS type %u\n", ntohl (src[i].type));
+ GNUNET_break (0);
+ break;
+ }
+ return res;
}
/**
@@ -141,7 +281,6 @@ recalculate_assigned_bw ()
static void
free_address (struct ATS_Address *addr)
{
- GNUNET_free_non_null (addr->ats);
GNUNET_free (addr->plugin);
GNUNET_free (addr);
}
@@ -170,6 +309,11 @@ create_address (const struct GNUNET_PeerIdentity *peer,
memcpy (&aa[1], plugin_addr, plugin_addr_len);
aa->plugin = GNUNET_strdup (plugin_name);
aa->session_id = session_id;
+ aa->active = GNUNET_NO;
+ aa->used = GNUNET_NO;
+ aa->solver_information = NULL;
+ aa->assigned_bw_in = GNUNET_BANDWIDTH_value_init(0);
+ aa->assigned_bw_out = GNUNET_BANDWIDTH_value_init(0);
return aa;
}
@@ -177,31 +321,20 @@ create_address (const struct GNUNET_PeerIdentity *peer,
/**
* Destroy the given address.
*
+ * @param handle the address handle
* @param addr address to destroy
* @return GNUNET_YES if bandwidth allocations should be recalcualted
*/
static int
-destroy_address (struct ATS_Address *addr)
+destroy_address (struct GAS_Addresses_Handle *handle, struct ATS_Address *addr)
{
int ret;
ret = GNUNET_NO;
GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (addresses,
+ GNUNET_CONTAINER_multihashmap_remove (handle->addresses,
&addr->peer.hashPubKey,
addr));
-
-#if HAVE_LIBGLPK
- if (ats_mode == MLP)
- GAS_mlp_address_delete (mlp, addresses, addr);
-#endif
-
- if (GNUNET_YES == addr->active)
- {
- active_addr_count--;
- addr->active = GNUNET_NO;
- ret = GNUNET_YES;
- }
free_address (addr);
return ret;
}
@@ -219,39 +352,68 @@ struct CompareAddressContext
static int
-compare_address_it (void *cls, const GNUNET_HashCode * key, void *value)
+compare_address_it (void *cls, const struct GNUNET_HashCode * key, void *value)
{
struct CompareAddressContext *cac = cls;
struct ATS_Address *aa = value;
-/*
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Comparing to: %s %s %u session %u\n",
- GNUNET_i2s (&aa->peer), aa->plugin, aa->addr_len, aa->session_id);
-*/
- /* find an exact matching address: aa->addr == cac->search->addr && aa->session == cac->search->session */
+ /* Find an matching exact address:
+ *
+ * Compare by:
+ * aa->addr_len == cac->search->addr_len
+ * aa->plugin == cac->search->plugin
+ * aa->addr == cac->search->addr
+ * aa->session == cac->search->session
+ *
+ * return as exact address
+ */
if ((aa->addr_len == cac->search->addr_len) && (0 == strcmp (aa->plugin, cac->search->plugin)))
{
if ((0 == memcmp (aa->addr, cac->search->addr, aa->addr_len)) && (aa->session_id == cac->search->session_id))
- {
cac->exact_address = aa;
- }
}
- /* find an matching address: aa->addr == cac->search->addr && aa->session == 0 */
- /* this address can be used to be updated */
+ /* Find an matching base address:
+ *
+ * Properties:
+ *
+ * aa->session_id == 0
+ *
+ * Compare by:
+ * aa->addr_len == cac->search->addr_len
+ * aa->plugin == cac->search->plugin
+ * aa->addr == cac->search->addr
+ *
+ * return as base address
+ */
if ((aa->addr_len == cac->search->addr_len) && (0 == strcmp (aa->plugin, cac->search->plugin)))
{
if ((0 == memcmp (aa->addr, cac->search->addr, aa->addr_len)) && (aa->session_id == 0))
- {
cac->base_address = aa;
- }
+ }
+
+ /* Find an matching exact address based on session:
+ *
+ * Properties:
+ *
+ * cac->search->addr_len == 0
+ *
+ * Compare by:
+ * aa->plugin == cac->search->plugin
+ * aa->session_id == cac->search->session_id
+ *
+ * return as exact address
+ */
+ if (0 == cac->search->addr_len)
+ {
+ if ((0 == strcmp (aa->plugin, cac->search->plugin)) && (aa->session_id == cac->search->session_id))
+ cac->exact_address = aa;
}
if (cac->exact_address == NULL)
- return GNUNET_YES;
+ return GNUNET_YES; /* Continue iteration to find exact address */
else
- return GNUNET_NO;
+ return GNUNET_NO; /* Stop iteration since we have an exact address */
}
@@ -260,177 +422,204 @@ compare_address_it (void *cls, const GNUNET_HashCode * key, void *value)
* Compares by peer identity and network address OR by session ID
* (one of the two must match).
*
+ * @param handle the address handle
* @param peer peer to lookup addresses for
* @param addr existing address record
* @return existing address record, NULL for none
*/
struct ATS_Address *
-find_address (const struct GNUNET_PeerIdentity *peer,
- const struct ATS_Address *addr)
+find_equivalent_address (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
+ const struct ATS_Address *addr)
{
struct CompareAddressContext cac;
cac.exact_address = NULL;
cac.base_address = NULL;
cac.search = addr;
- GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
+ GNUNET_CONTAINER_multihashmap_get_multiple (handle->addresses, &peer->hashPubKey,
&compare_address_it, &cac);
-/*
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "exact address: %s base address: %s\n",
- (cac.exact_address != NULL) ? "YES" : "NO",
- (cac.base_address != NULL) ? "YES" : "NO");
-*/
if (cac.exact_address == NULL)
return cac.base_address;
return cac.exact_address;
}
-static int
-compare_address_session_it (void *cls, const GNUNET_HashCode * key, void *value)
+static struct ATS_Address *
+lookup_address (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
+ const char *plugin_name,
+ const void *plugin_addr,
+ size_t plugin_addr_len,
+ uint32_t session_id,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count)
{
- struct CompareAddressContext *cac = cls;
- struct ATS_Address *aa = value;
+ struct ATS_Address *aa;
+ struct ATS_Address *ea;
- if ((aa->addr_len == cac->search->addr_len) && (0 == strcmp (aa->plugin, cac->search->plugin)))
+ aa = create_address (peer,
+ plugin_name,
+ plugin_addr, plugin_addr_len,
+ session_id);
+
+ /* Get existing address or address with session == 0 */
+ ea = find_equivalent_address (handle, peer, aa);
+ free_address (aa);
+ if (ea == NULL)
{
- if ((0 == memcmp (aa->addr, cac->search->addr, aa->addr_len)) && (aa->session_id == cac->search->session_id))
- {
- cac->exact_address = aa;
- return GNUNET_NO;
- }
+ return NULL;
}
- return GNUNET_YES;
+ else if (ea->session_id != session_id)
+ {
+ return NULL;
+ }
+ return ea;
}
-/**
- * Find an existing equivalent address record.
- * Compares by peer identity and network address AND by session ID
- * (one of the two must match).
- *
- * @param peer peer to lookup addresses for
- * @param addr existing address record
- * @return existing address record, NULL for none
- */
-struct ATS_Address *
-find_exact_address (const struct GNUNET_PeerIdentity *peer,
- const struct ATS_Address *addr)
+void
+GAS_addresses_add (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
+ const char *plugin_name, const void *plugin_addr,
+ size_t plugin_addr_len, uint32_t session_id,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count)
{
- struct CompareAddressContext cac;
+ struct ATS_Address *aa;
+ struct ATS_Address *ea;
+ unsigned int ats_res;
- cac.exact_address = NULL;
- cac.search = addr;
- GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
- &compare_address_session_it, &cac);
- return cac.exact_address;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' for peer `%s'\n",
+ "ADDRESS ADD",
+ GNUNET_i2s (peer));
+
+ if (GNUNET_NO == handle->running)
+ return;
+
+ GNUNET_assert (NULL != handle->addresses);
+
+ aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len,
+ session_id);
+ if (atsi_count != (ats_res = disassemble_ats_information(atsi, atsi_count, aa)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "While adding address: had %u ATS elements to add, could only add %u\n",
+ atsi_count, ats_res);
+ }
+
+ /* Get existing address or address with session == 0 */
+ ea = find_equivalent_address (handle, peer, aa);
+ if (ea == NULL)
+ {
+ /* We have a new address */
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONTAINER_multihashmap_put (handle->addresses,
+ &peer->hashPubKey, aa,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' session id %u, %p\n",
+ GNUNET_i2s (peer), session_id, aa);
+ /* Tell solver about new address */
+ handle->s_add (handle->solver, handle->addresses, aa);
+ return;
+ }
+ GNUNET_free (aa->plugin);
+ GNUNET_free (aa);
+
+ if (ea->session_id != 0)
+ {
+ /* This address with the same session is already existing
+ * Should not happen */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Added already existing address for peer `%s' `%s' %p with new session %u\n",
+ GNUNET_i2s (peer), plugin_name, session_id);
+ GNUNET_break (0);
+ return;
+ }
+
+ /* We have an address without an session, update this address */
+
+ /* Notify solver about update with atsi information and session */
+ handle->s_update (handle->solver, handle->addresses, ea, session_id, ea->used, atsi, atsi_count);
+
+ /* Do the update */
+ ea->session_id = session_id;
+ if (atsi_count != (ats_res = disassemble_ats_information(atsi, atsi_count, ea)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "While updating address: had %u ATS elements to add, could only add %u\n",
+ atsi_count, ats_res);
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Updated existing address for peer `%s' %p with new session %u\n",
+ GNUNET_i2s (peer), ea, session_id);
}
void
-GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
+GAS_addresses_update (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
const char *plugin_name, const void *plugin_addr,
size_t plugin_addr_len, uint32_t session_id,
const struct GNUNET_ATS_Information *atsi,
uint32_t atsi_count)
{
struct ATS_Address *aa;
- struct ATS_Address *old;
- uint32_t i;
+ uint32_t ats_res;
- if (GNUNET_NO == running)
+ if (GNUNET_NO == handle->running)
return;
- GNUNET_assert (NULL != addresses);
+ GNUNET_assert (NULL != handle->addresses);
- aa = create_address (peer,
- plugin_name,
- plugin_addr, plugin_addr_len,
- session_id);
+ /* Get existing address */
+ aa = lookup_address (handle, peer, plugin_name, plugin_addr, plugin_addr_len,
+ session_id, atsi, atsi_count);
+ if (aa == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Tried to update unknown address for peer `%s' `%s' session id %u\n",
+ GNUNET_i2s (peer), plugin_name, session_id);
+ GNUNET_break (0);
+ return;
+ }
- aa->mlp_information = NULL;
- aa->ats = GNUNET_malloc (atsi_count * sizeof (struct GNUNET_ATS_Information));
- aa->ats_count = atsi_count;
- memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_ATS_Information));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' for peer `%s' address \n",
+ "ADDRESS UPDATE",
+ GNUNET_i2s (peer), aa);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' %u\n",
- GNUNET_i2s (peer),
- session_id);
+ /* Tell solver about update */
+ handle->s_update (handle->solver, handle->addresses, aa, session_id, aa->used, atsi, atsi_count);
- /* Get existing address or address with session == 0 */
- old = find_address (peer, aa);
- if (old == NULL)
+ /* Update address */
+ if (atsi_count != (ats_res = disassemble_ats_information (atsi, atsi_count, aa)))
{
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (addresses,
- &peer->hashPubKey, aa,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
-#if DEBUG_ATS
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %X\n",
- GNUNET_i2s (peer), aa);
-#endif
- old = aa;
- }
- else
- {
-#if DEBUG_ATS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Updated existing address for peer `%s' %p old session %u new session %u\n",
- GNUNET_i2s (peer), old,
- old->session_id, session_id);
-#endif
- GNUNET_free_non_null (old->ats);
- old->session_id = session_id;
- old->ats = NULL;
- old->ats_count = 0;
- old->ats = aa->ats;
- old->ats_count = aa->ats_count;
- GNUNET_free (aa->plugin);
- GNUNET_free (aa);
- }
- for (i = 0; i < atsi_count; i++)
- switch (ntohl (atsi[i].type))
- {
- case GNUNET_ATS_UTILIZATION_UP:
- old->atsp_utilization_out.value__ = atsi[i].value;
- break;
- case GNUNET_ATS_UTILIZATION_DOWN:
- old->atsp_utilization_in.value__ = atsi[i].value;
- break;
- case GNUNET_ATS_QUALITY_NET_DELAY:
- old->atsp_latency.rel_value = ntohl (atsi[i].value);
- break;
- case GNUNET_ATS_QUALITY_NET_DISTANCE:
- old->atsp_distance = ntohl (atsi[i].value);
- break;
- case GNUNET_ATS_COST_WAN:
- old->atsp_cost_wan = ntohl (atsi[i].value);
- break;
- case GNUNET_ATS_COST_LAN:
- old->atsp_cost_lan = ntohl (atsi[i].value);
- break;
- case GNUNET_ATS_COST_WLAN:
- old->atsp_cost_wlan = ntohl (atsi[i].value);
- break;
- case GNUNET_ATS_NETWORK_TYPE:
- old->atsp_network_type = ntohl (atsi[i].value);
- break;
-
- default:
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Received unsupported ATS type %u\n", ntohl (atsi[i].type));
- GNUNET_break (0);
- break;
- }
-#if HAVE_LIBGLPK
- if (ats_mode == MLP)
- GAS_mlp_address_update (mlp, addresses, old);
-#endif
+ "While adding address: had %u ATS elements to add, could only add %u\n",
+ atsi_count, ats_res);
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Updated %u ATS elements for address %p\n",
+ ats_res, aa);
}
+struct DestroyContext
+{
+ struct ATS_Address *aa;
+
+ struct GAS_Addresses_Handle *handle;
+
+ /**
+ * GNUNET_NO : full address
+ * GNUNET_YES : just session
+ */
+ int result;
+};
+
+
/**
* Delete an address
*
@@ -444,453 +633,576 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
* @return GNUNET_OK (continue to iterate)
*/
static int
-destroy_by_session_id (void *cls, const GNUNET_HashCode * key, void *value)
+destroy_by_session_id (void *cls, const struct GNUNET_HashCode * key, void *value)
{
- const struct ATS_Address *info = cls;
+ struct DestroyContext *dc = cls;
+ struct GAS_Addresses_Handle *handle = dc->handle;
+ const struct ATS_Address *des = dc->aa;
struct ATS_Address *aa = value;
- GNUNET_assert (0 ==
- memcmp (&aa->peer, &info->peer,
- sizeof (struct GNUNET_PeerIdentity)));
- /* session == 0, remove full address */
- if ((info->session_id == 0) && (0 == strcmp (info->plugin, aa->plugin)) &&
- (aa->addr_len == info->addr_len) &&
- (0 == memcmp (info->addr, aa->addr, aa->addr_len)))
- {
+ GNUNET_assert (0 == memcmp (&aa->peer, &des->peer,
+ sizeof (struct GNUNET_PeerIdentity)));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Deleting address for peer `%s': `%s' %u\n",
- GNUNET_i2s (&aa->peer), aa->plugin, aa->session_id);
-
- if (GNUNET_YES == destroy_address (aa))
- recalculate_assigned_bw ();
- return GNUNET_OK;
- }
- /* session != 0, just remove session */
- if (aa->session_id != info->session_id)
- return GNUNET_OK; /* irrelevant */
- if (aa->session_id != 0)
- GNUNET_break (0 == strcmp (info->plugin, aa->plugin));
- /* session died */
-#if VERBOSE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Deleting session for peer `%s': `%s' %u\n",
- GNUNET_i2s (&aa->peer), aa->plugin, aa->session_id);
-#endif
- aa->session_id = 0;
- if (GNUNET_YES == aa->active)
+ if (des->session_id == 0)
{
- aa->active = GNUNET_NO;
- active_addr_count--;
- recalculate_assigned_bw ();
- }
+ /* Session == 0, remove full address */
+ if ((0 == strcmp (des->plugin, aa->plugin)) &&
+ (aa->addr_len == des->addr_len) &&
+ (0 == memcmp (des->addr, aa->addr, aa->addr_len)))
+ {
- /* session == 0 and addrlen == 0 : destroy address */
- if (aa->addr_len == 0)
- {
-#if VERBOSE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Deleting session and address for peer `%s': `%s' %u\n",
- GNUNET_i2s (&aa->peer), aa->plugin, aa->session_id);
-#endif
- (void) destroy_address (aa);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Deleting full address for peer `%s' session %u %p\n",
+ GNUNET_i2s (&aa->peer), aa->session_id, aa);
+
+ /* Notify solver about deletion */
+ handle->s_del (handle->solver, handle->addresses, aa, GNUNET_NO);
+ destroy_address (handle, aa);
+ dc->result = GNUNET_NO;
+ return GNUNET_OK; /* Continue iteration */
+ }
}
else
{
- /* session was set to 0, update address */
-#if HAVE_LIBGLPK
- if (ats_mode == MLP)
- GAS_mlp_address_update (mlp, addresses, aa);
-#endif
- }
+ /* Session != 0, just remove session */
+ if (aa->session_id != des->session_id)
+ return GNUNET_OK; /* irrelevant */
+ if ((aa->session_id != 0) &&
+ (0 != strcmp (des->plugin, aa->plugin)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Different plugins during removal: `%s' vs `%s' \n",
+ des->plugin, aa->plugin);
+ GNUNET_break (0);
+ return GNUNET_OK;
+ }
+
+ if (aa->addr_len == 0)
+ {
+ /* Inbound connection died, delete full address */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Deleting inbound address for peer `%s': `%s' session %u\n",
+ GNUNET_i2s (&aa->peer), aa->plugin, aa->session_id);
+
+ /* Notify solver about deletion */
+ handle->s_del (handle->solver, handle->addresses, aa, GNUNET_NO);
+ destroy_address (handle, aa);
+ dc->result = GNUNET_NO;
+ return GNUNET_OK; /* Continue iteration */
+ }
+ else
+ {
+ /* Session died */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Deleting session for peer `%s': `%s' %u\n",
+ GNUNET_i2s (&aa->peer), aa->plugin, aa->session_id);
+ /* Notify solver to delete session */
+ handle->s_del (handle->solver, handle->addresses, aa, GNUNET_YES);
+ aa->session_id = 0;
+ return GNUNET_OK;
+ }
+ }
return GNUNET_OK;
}
void
-GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
+GAS_addresses_destroy (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
const char *plugin_name, const void *plugin_addr,
size_t plugin_addr_len, uint32_t session_id)
{
- struct ATS_Address *aa;
+ struct ATS_Address *ea;
+ struct DestroyContext dc;
- if (GNUNET_NO == running)
+ if (GNUNET_NO == handle->running)
return;
- GNUNET_break (0 < strlen (plugin_name));
- aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id);
-
- GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
- &destroy_by_session_id, aa);
-
- free_address (aa);
-}
-
-
-/**
- * Find a "good" address to use for a peer. If we already have an existing
- * address, we stick to it. Otherwise, we pick by lowest distance and then
- * by lowest latency.
- *
- * @param cls the 'struct ATS_Address**' where we store the result
- * @param key unused
- * @param value another 'struct ATS_Address*' to consider using
- * @return GNUNET_OK (continue to iterate)
- */
-static int
-find_address_it (void *cls, const GNUNET_HashCode * key, void *value)
-{
- struct ATS_Address **ap = cls;
- struct ATS_Address *aa = (struct ATS_Address *) value;
- struct ATS_Address *ab = *ap;
- struct GNUNET_TIME_Absolute now;
-
- now = GNUNET_TIME_absolute_get();
-
- if (aa->blocked_until.abs_value == GNUNET_TIME_absolute_max (now, aa->blocked_until).abs_value)
- {
- /* This address is blocked for suggestion */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Address %p blocked for suggestion for %llu ms \n",
- aa,
- GNUNET_TIME_absolute_get_difference(now, aa->blocked_until).rel_value);
- return GNUNET_OK;
- }
-
- aa->block_interval = GNUNET_TIME_relative_add (aa->block_interval, ATS_BLOCKING_DELTA);
- aa->blocked_until = GNUNET_TIME_absolute_add (now, aa->block_interval);
+ /* Get existing address */
+ ea = lookup_address (handle, peer, plugin_name, plugin_addr, plugin_addr_len,
+ session_id, NULL, 0);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Address %p ready for suggestion, block interval now %llu \n", aa, aa->block_interval);
+ "Received `%s' for peer `%s' address %p session %u\n",
+ "ADDRESS DESTROY",
+ GNUNET_i2s (peer), ea, session_id);
- /* FIXME this is a hack */
-
-
- if (NULL != ab)
+ if (ea == NULL)
{
- if ((0 == strcmp (ab->plugin, "tcp")) &&
- (0 == strcmp (aa->plugin, "tcp")))
- {
- if ((0 != ab->addr_len) &&
- (0 == aa->addr_len))
- {
- /* saved address was an outbound address, but we have an inbound address */
- *ap = aa;
- return GNUNET_OK;
- }
- if (0 == ab->addr_len)
- {
- /* saved address was an inbound address, so do not overwrite */
- return GNUNET_OK;
- }
- }
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Tried to destroy unknown address for peer `%s' `%s' session id %u\n",
+ GNUNET_i2s (peer), plugin_name, session_id);
+ return;
}
- /* FIXME end of hack */
- if (NULL == ab)
- {
- *ap = aa;
- return GNUNET_OK;
- }
- if ((ntohl (ab->assigned_bw_in.value__) == 0) &&
- (ntohl (aa->assigned_bw_in.value__) > 0))
- {
- /* stick to existing connection */
- *ap = aa;
- return GNUNET_OK;
- }
- if (ab->atsp_distance > aa->atsp_distance)
- {
- /* user shorter distance */
- *ap = aa;
- return GNUNET_OK;
- }
- if (ab->atsp_latency.rel_value > aa->atsp_latency.rel_value)
- {
- /* user lower latency */
- *ap = aa;
- return GNUNET_OK;
- }
- /* don't care */
- return GNUNET_OK;
+ GNUNET_break (0 < strlen (plugin_name));
+ dc.handle = handle;
+ dc.aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id);
+
+ GNUNET_CONTAINER_multihashmap_get_multiple (handle->addresses, &peer->hashPubKey,
+ &destroy_by_session_id, &dc);
+ free_address (dc.aa);
}
int
-GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer,
+GAS_addresses_in_use (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
const char *plugin_name, const void *plugin_addr,
size_t plugin_addr_len, uint32_t session_id, int in_use)
{
-#if DEBUG_ATS
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received `%s' message for peer `%s': %i\n", "ADDRESS_IN_USE",
- GNUNET_i2s (peer), in_use);
-#endif
+ struct ATS_Address *ea;
- struct ATS_Address *aa;
- struct ATS_Address *old;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' for peer `%s'\n",
+ "ADDRESS IN USE",
+ GNUNET_i2s (peer));
- if (GNUNET_NO == running)
+ if (GNUNET_NO == handle->running)
return GNUNET_SYSERR;
- aa = create_address (peer, plugin_name, plugin_addr, plugin_addr_len, session_id);
- old = find_exact_address (peer, aa);
- free_address (aa);
-
- if (NULL == old)
+ ea = lookup_address (handle, peer, plugin_name,
+ plugin_addr, plugin_addr_len,
+ session_id, NULL, 0);
+ if (NULL == ea)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Trying to set unknown address `%s', %s %u %s \n",
+ GNUNET_i2s (peer),
+ plugin_name, session_id,
+ (GNUNET_NO == in_use) ? "NO" : "YES");
GNUNET_break (0);
return GNUNET_SYSERR;
}
- if (old->used == in_use)
+ if (ea->used == in_use)
{
GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Address in use called multiple times for peer `%s': %s -> %s \n",
GNUNET_i2s (peer),
- (GNUNET_NO == old->used) ? "NO" : "YES",
+ (GNUNET_NO == ea->used) ? "NO" : "YES",
(GNUNET_NO == in_use) ? "NO" : "YES");
return GNUNET_SYSERR;
}
- old->used = in_use;
-#if HAVE_LIBGLPK
- if (ats_mode == MLP)
- GAS_mlp_address_update (mlp, addresses, old);
-#endif
+
+ /* Tell solver about update */
+ handle->s_update (handle->solver, handle->addresses, ea, session_id, in_use, NULL, 0);
+ ea->used = in_use;
+
return GNUNET_OK;
}
-void request_address_mlp (const struct GNUNET_PeerIdentity *peer)
+/**
+ * Cancel address suggestions for a peer
+ *
+ * @param handle the address handle
+ * @param peer the respective peer
+ */
+void
+GAS_addresses_request_address_cancel (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer)
{
- struct ATS_Address *aa;
- aa = NULL;
-
-#if HAVE_GLPK
- /* Get preferred address from MLP */
- struct ATS_PreferedAddress * paddr = NULL;
- paddr = GAS_mlp_get_preferred_address (mlp, addresses, peer);
- aa = paddr->address;
- aa->assigned_bw_out = GNUNET_BANDWIDTH_value_init(paddr->bandwidth_out);
- /* FIXME use bw in value */
- paddr->bandwidth_in = paddr->bandwidth_out;
- aa->assigned_bw_in = GNUNET_BANDWIDTH_value_init (paddr->bandwidth_in);
- GNUNET_free (paddr);
-#endif
+ struct GAS_Addresses_Suggestion_Requests *cur = handle->r_head;
- if (aa == NULL)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received request: `%s' for peer %s\n", "request_address_cancel", GNUNET_i2s (peer));
+
+ while (NULL != cur)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
- "Cannot suggest address for peer `%s'\n", GNUNET_i2s (peer));
- return;
+ if (0 == memcmp (peer, &cur->id, sizeof (cur->id)))
+ break; /* found */
+ cur = cur->next;
}
- if (aa->active == GNUNET_NO)
- {
- aa->active = GNUNET_YES;
- active_addr_count++;
- send_bw_notification (aa);
- }
- else
+ if (NULL == cur)
{
- /* just to be sure... */
- GAS_scheduling_transmit_address_suggestion (peer, aa->plugin, aa->addr,
- aa->addr_len, aa->session_id,
- aa->ats, aa->ats_count,
- aa->assigned_bw_out,
- aa->assigned_bw_in);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "No address requests pending for peer `%s', cannot remove!\n", GNUNET_i2s (peer));
+ return;
}
-
+ GAS_addresses_handle_backoff_reset (handle, peer);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Removed request pending for peer `%s\n", GNUNET_i2s (peer));
+ GNUNET_CONTAINER_DLL_remove (handle->r_head, handle->r_tail, cur);
+ GNUNET_free (cur);
}
-void request_address_simple (const struct GNUNET_PeerIdentity *peer)
+
+/**
+ * Add an address suggestions for a peer
+ *
+ * @param handle the address handle
+ * @param peer the respective peer
+ */
+void
+GAS_addresses_request_address (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer)
{
+ struct GAS_Addresses_Suggestion_Requests *cur = handle->r_head;
struct ATS_Address *aa;
- aa = NULL;
+ struct GNUNET_ATS_Information *ats;
+ unsigned int ats_count;
- /* Get address with: stick to current address, lower distance, lower latency */
- GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
- &find_address_it, &aa);
- if (aa == NULL)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' for peer `%s'\n",
+ "REQUEST ADDRESS",
+ GNUNET_i2s (peer));
+
+ if (GNUNET_NO == handle->running)
+ return;
+ while (NULL != cur)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+ if (0 == memcmp (peer, &cur->id, sizeof (cur->id)))
+ break; /* already suggesting */
+ cur = cur->next;
+ }
+ if (NULL == cur)
+ {
+ cur = GNUNET_malloc (sizeof (struct GAS_Addresses_Suggestion_Requests));
+ cur->id = (*peer);
+ GNUNET_CONTAINER_DLL_insert (handle->r_head, handle->r_tail, cur);
+ }
+
+ /* Get prefered address from solver */
+ aa = (struct ATS_Address *) handle->s_get (handle->solver, handle->addresses, peer);
+ if (NULL == aa)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Cannot suggest address for peer `%s'\n", GNUNET_i2s (peer));
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Suggesting address %p for peer `%s'\n", aa, GNUNET_i2s (peer));
- if (aa->active == GNUNET_NO)
- {
- aa->active = GNUNET_YES;
- active_addr_count++;
- if (ats_mode == SIMPLE)
- {
- recalculate_assigned_bw ();
- }
- }
- else
- {
- /* just to be sure... */
- GAS_scheduling_transmit_address_suggestion (peer, aa->plugin, aa->addr,
- aa->addr_len, aa->session_id,
- aa->ats, aa->ats_count,
- aa->assigned_bw_out,
- aa->assigned_bw_in);
- }
-}
+ ats_count = assemble_ats_information (aa, &ats);
+ GAS_scheduling_transmit_address_suggestion (peer,
+ aa->plugin,
+ aa->addr, aa->addr_len,
+ aa->session_id,
+ ats, ats_count,
+ aa->assigned_bw_out,
+ aa->assigned_bw_in);
+ aa->block_interval = GNUNET_TIME_relative_add (aa->block_interval, ATS_BLOCKING_DELTA);
+ aa->blocked_until = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), aa->block_interval);
-void
-GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer)
-{
- if (GNUNET_NO == running)
- return;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Address %p ready for suggestion, block interval now %llu \n",
+ aa, aa->block_interval);
- if (ats_mode == SIMPLE)
- {
- request_address_simple (peer);
- }
- if (ats_mode == MLP)
- {
- request_address_mlp(peer);
- }
+ GNUNET_free (ats);
}
static int
-reset_address_it (void *cls, const GNUNET_HashCode * key, void *value)
+reset_address_it (void *cls, const struct GNUNET_HashCode * key, void *value)
{
struct ATS_Address *aa = value;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Resetting interval for peer `%s' address %p from %llu to 0\n", GNUNET_i2s (&aa->peer), aa, aa->block_interval);
+ "Resetting interval for peer `%s' address %p from %llu to 0\n",
+ GNUNET_i2s (&aa->peer), aa, aa->block_interval);
aa->blocked_until = GNUNET_TIME_UNIT_ZERO_ABS;
aa->block_interval = GNUNET_TIME_UNIT_ZERO;
return GNUNET_OK;
}
+
void
-GAS_addresses_handle_backoff_reset (const struct GNUNET_PeerIdentity *peer)
+GAS_addresses_handle_backoff_reset (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer)
{
- GNUNET_break (GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_get_multiple (addresses,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' for peer `%s'\n",
+ "RESET BACKOFF",
+ GNUNET_i2s (peer));
+
+ GNUNET_break (GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_get_multiple (handle->addresses,
&peer->hashPubKey,
&reset_address_it,
NULL));
}
-
-// FIXME: this function should likely end up in the LP-subsystem and
-// not with 'addresses' in the future...
void
-GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer,
+GAS_addresses_change_preference (struct GAS_Addresses_Handle *handle,
+ void *client,
+ const struct GNUNET_PeerIdentity *peer,
enum GNUNET_ATS_PreferenceKind kind,
float score)
{
- if (GNUNET_NO == running)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s' for peer `%s' for client %p\n",
+ "CHANGE PREFERENCE",
+ GNUNET_i2s (peer), client);
+
+ if (GNUNET_NO == handle->running)
return;
-#if HAVE_LIBGLPK
- if (ats_mode == MLP)
- GAS_mlp_address_change_preference (mlp, peer, kind, score);
-#endif
-}
+ if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->addresses,
+ &peer->hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Received `%s' for unknown peer `%s' from client %p\n",
+ "CHANGE PREFERENCE",
+ GNUNET_i2s (peer), client);
+ return;
+ }
+ /* Tell solver about update */
+ handle->s_pref (handle->solver, client, peer, kind, score);
+}
-/**
- * Initialize address subsystem.
- *
- * @param cfg configuration to use
- * @param stats the statistics handle to use
- */
-void
-GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_STATISTICS_Handle *stats)
+static unsigned int
+load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned long long *out_dest, unsigned long long *in_dest, int dest_length)
{
- int mode;
+ char *network_str[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkTypeString;
+ char * entry_in = NULL;
+ char * entry_out = NULL;
+ char * quota_out_str;
+ char * quota_in_str;
+ int c;
+ int res;
+
+ for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
+ {
+ in_dest[c] = 0;
+ out_dest[c] = 0;
+ GNUNET_asprintf (&entry_out, "%s_QUOTA_OUT", network_str[c]);
+ GNUNET_asprintf (&entry_in, "%s_QUOTA_IN", network_str[c]);
- char *quota_wan_in_str;
- char *quota_wan_out_str;
+ /* quota out */
+ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, &quota_out_str))
+ {
+ res = GNUNET_NO;
+ if (0 == strcmp(quota_out_str, BIG_M_STRING))
+ {
+ out_dest[c] = GNUNET_ATS_MaxBandwidth;
+ res = GNUNET_YES;
+ }
+ if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &out_dest[c])))
+ res = GNUNET_YES;
+ if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, &out_dest[c])))
+ res = GNUNET_YES;
- running = GNUNET_NO;
+ if (GNUNET_NO == res)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
+ network_str[c], quota_out_str, GNUNET_ATS_DefaultBandwidth);
+ out_dest[c] = GNUNET_ATS_DefaultBandwidth;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Outbound quota configure for network `%s' is %llu\n"),
+ network_str[c], out_dest[c]);
+ }
+ GNUNET_free (quota_out_str);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
+ network_str[c], GNUNET_ATS_DefaultBandwidth);
+ out_dest[c] = GNUNET_ATS_DefaultBandwidth;
+ }
- addresses = GNUNET_CONTAINER_multihashmap_create (128);
- GNUNET_assert (NULL != addresses);
+ /* quota in */
+ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, &quota_in_str))
+ {
+ res = GNUNET_NO;
+ if (0 == strcmp(quota_in_str, BIG_M_STRING))
+ {
+ in_dest[c] = GNUNET_ATS_MaxBandwidth;
+ res = GNUNET_YES;
+ }
+ if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
+ res = GNUNET_YES;
+ if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, &in_dest[c])))
+ res = GNUNET_YES;
- if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_IN", &quota_wan_in_str))
- {
- if (0 == strcmp(quota_wan_in_str, "unlimited") ||
- (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_wan_in_str, &wan_quota_in)))
- wan_quota_in = (UINT32_MAX) /10;
+ if (GNUNET_NO == res)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
+ network_str[c], quota_in_str, GNUNET_ATS_DefaultBandwidth);
+ in_dest[c] = GNUNET_ATS_DefaultBandwidth;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Inbound quota configured for network `%s' is %llu\n"),
+ network_str[c], in_dest[c]);
+ }
+ GNUNET_free (quota_in_str);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
+ network_str[c], GNUNET_ATS_DefaultBandwidth);
+ out_dest[c] = GNUNET_ATS_DefaultBandwidth;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded quota for network `%s' (in/out): %llu %llu\n", network_str[c], in_dest[c], out_dest[c]);
+ GNUNET_free (entry_out);
+ GNUNET_free (entry_in);
+ }
+ return GNUNET_ATS_NetworkTypeCount;
+}
+
+
+static void
+bandwidth_changed_cb (void *cls, struct ATS_Address *address)
+{
+ struct GAS_Addresses_Handle *handle = cls;
+ struct GAS_Addresses_Suggestion_Requests *cur;
+
+ GNUNET_assert (handle != NULL);
+ GNUNET_assert (address != NULL);
- GNUNET_free (quota_wan_in_str);
- quota_wan_in_str = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Bandwidth assignment changed for peer %s \n", GNUNET_i2s(&address->peer));
+ struct GNUNET_ATS_Information *ats;
+ unsigned int ats_count;
+
+ cur = handle->r_head;
+ while (NULL != cur)
+ {
+ if (0 == memcmp (&address->peer, &cur->id, sizeof (cur->id)))
+ break; /* we have an address request pending*/
+ cur = cur->next;
}
- else
+ if (NULL == cur)
{
- wan_quota_in = (UINT32_MAX) /10;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Nobody is interested in peer `%s' :(\n",GNUNET_i2s (&address->peer));
+ return;
}
- if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_OUT", &quota_wan_out_str))
- {
- if (0 == strcmp(quota_wan_out_str, "unlimited") ||
- (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_wan_out_str, &wan_quota_out)))
- wan_quota_out = (UINT32_MAX) /10;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending bandwidth update for peer `%s'\n",GNUNET_i2s (&address->peer));
+
+ ats_count = assemble_ats_information (address, &ats);
+ GAS_scheduling_transmit_address_suggestion (&address->peer,
+ address->plugin,
+ address->addr, address->addr_len,
+ address->session_id,
+ ats, ats_count,
+ address->assigned_bw_out,
+ address->assigned_bw_in);
+ GNUNET_free (ats);
+}
- GNUNET_free (quota_wan_out_str);
- quota_wan_out_str = NULL;
- }
- else
+
+/**
+ * Initialize address subsystem.
+ *
+ * @param cfg configuration to use
+ * @param stats the statistics handle to use
+ */
+struct GAS_Addresses_Handle *
+GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_STATISTICS_Handle *stats)
+{
+ struct GAS_Addresses_Handle *ah;
+ int quotas[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
+ unsigned long long quotas_in[GNUNET_ATS_NetworkTypeCount];
+ unsigned long long quotas_out[GNUNET_ATS_NetworkTypeCount];
+ int quota_count;
+ char *mode_str;
+ int c;
+
+ ah = GNUNET_malloc (sizeof (struct GAS_Addresses_Handle));
+ ah->running = GNUNET_NO;
+
+ ah->stat = (struct GNUNET_STATISTICS_Handle *) stats;
+ /* Initialize the addresses database */
+ ah->addresses = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO);
+ GNUNET_assert (NULL != ah->addresses);
+
+ /* Figure out configured solution method */
+ if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", "MODE", &mode_str))
{
- wan_quota_out = (UINT32_MAX) /10;
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "No ressource assignment method configured, using simplistic approch\n");
+ ah->ats_mode = MODE_SIMPLISTIC;
}
-
- mode = GNUNET_CONFIGURATION_get_value_yesno (cfg, "ats", "MLP");
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MLP mode %u", mode);
- switch (mode)
+ else
{
- /* MLP = YES */
- case GNUNET_YES:
-#if HAVE_LIBGLPK
- ats_mode = MLP;
- /* Init the MLP solver with default values */
- mlp = GAS_mlp_init (cfg, stats, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
- if (NULL == mlp)
+ for (c = 0; c < strlen (mode_str); c++)
+ mode_str[c] = toupper (mode_str[c]);
+ if (0 == strcmp (mode_str, "SIMPLISTIC"))
+ {
+ ah->ats_mode = MODE_SIMPLISTIC;
+ }
+ else if (0 == strcmp (mode_str, "MLP"))
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode\n");
- GNUNET_STATISTICS_update (GSA_stats, "MLP mode enabled", 0, GNUNET_NO);
- break;
+ ah->ats_mode = MODE_MLP;
+#if !HAVE_LIBGLPK
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Assignment method `%s' configured, but GLPK is not availabe, please install \n", mode_str);
+ ah->ats_mode = MODE_SIMPLISTIC;
+#endif
}
else
{
- GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 1, GNUNET_NO);
- break;
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid ressource assignment method `%s' configured, using simplistic approch\n", mode_str);
+ ah->ats_mode = MODE_SIMPLISTIC;
}
+ GNUNET_free (mode_str);
+ }
+ /* Start configured solution method */
+ switch (ah->ats_mode)
+ {
+ case MODE_MLP:
+ /* Init the MLP solver with default values */
+#if HAVE_LIBGLPK
+ ah->ats_mode = MODE_MLP;
+ ah->s_init = &GAS_mlp_init;
+ ah->s_add = &GAS_mlp_address_add;
+ ah->s_update = &GAS_mlp_address_update;
+ ah->s_get = &GAS_mlp_get_preferred_address;
+ ah->s_pref = &GAS_mlp_address_change_preference;
+ ah->s_del = &GAS_mlp_address_delete;
+ ah->s_done = &GAS_mlp_done;
#else
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode");
- GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO);
- ats_mode = SIMPLE;
- break;
+ GNUNET_free (ah);
+ return NULL;
#endif
- /* MLP = NO */
- case GNUNET_NO:
- GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO);
- ats_mode = SIMPLE;
break;
- /* No configuration value */
- case GNUNET_SYSERR:
- GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO);
- ats_mode = SIMPLE;
+ case MODE_SIMPLISTIC:
+ /* Init the simplistic solver with default values */
+ ah->ats_mode = MODE_SIMPLISTIC;
+ ah->s_init = &GAS_simplistic_init;
+ ah->s_add = &GAS_simplistic_address_add;
+ ah->s_update = &GAS_simplistic_address_update;
+ ah->s_get = &GAS_simplistic_get_preferred_address;
+ ah->s_pref = &GAS_simplistic_address_change_preference;
+ ah->s_del = &GAS_simplistic_address_delete;
+ ah->s_done = &GAS_simplistic_done;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS started in %s mode\n", "SIMPLISTIC");
break;
default:
+ return NULL;
break;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS started with %s mode\n", (SIMPLE == ats_mode) ? "SIMPLE" : "MLP");
- running = GNUNET_YES;
+
+ GNUNET_assert (NULL != ah->s_init);
+ GNUNET_assert (NULL != ah->s_add);
+ GNUNET_assert (NULL != ah->s_update);
+ GNUNET_assert (NULL != ah->s_get);
+ GNUNET_assert (NULL != ah->s_pref);
+ GNUNET_assert (NULL != ah->s_del);
+ GNUNET_assert (NULL != ah->s_done);
+
+ quota_count = load_quotas(cfg, quotas_in, quotas_out, GNUNET_ATS_NetworkTypeCount);
+
+ ah->solver = ah->s_init (cfg, stats, quotas, quotas_in, quotas_out, quota_count, &bandwidth_changed_cb, ah);
+ if (NULL == ah->solver)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to initialize solver!\n");
+ GNUNET_free (ah);
+ return NULL;
+ }
+
+ /* up and running */
+ ah->running = GNUNET_YES;
+ return ah;
}
@@ -903,24 +1215,28 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
* @return GNUNET_OK (continue to iterate)
*/
static int
-free_address_it (void *cls, const GNUNET_HashCode * key, void *value)
+free_address_it (void *cls, const struct GNUNET_HashCode * key, void *value)
{
+ struct GAS_Addresses_Handle *handle = cls;
struct ATS_Address *aa = value;
-
- destroy_address (aa);
+ handle->s_del (handle->solver, handle->addresses, aa, GNUNET_NO);
+ destroy_address (handle, aa);
return GNUNET_OK;
}
void
-GAS_addresses_destroy_all ()
+GAS_addresses_destroy_all (struct GAS_Addresses_Handle *handle)
{
- if (GNUNET_NO == running)
+ if (GNUNET_NO == handle->running)
return;
- if (addresses != NULL)
- GNUNET_CONTAINER_multihashmap_iterate (addresses, &free_address_it, NULL);
- GNUNET_assert (active_addr_count == 0);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received `%s'\n",
+ "DESTROY ALL");
+
+ if (handle->addresses != NULL)
+ GNUNET_CONTAINER_multihashmap_iterate (handle->addresses, &free_address_it, handle);
}
@@ -928,18 +1244,147 @@ GAS_addresses_destroy_all ()
* Shutdown address subsystem.
*/
void
-GAS_addresses_done ()
+GAS_addresses_done (struct GAS_Addresses_Handle *handle)
{
- GAS_addresses_destroy_all ();
- running = GNUNET_NO;
- GNUNET_CONTAINER_multihashmap_destroy (addresses);
- addresses = NULL;
-#if HAVE_LIBGLPK
- if (ats_mode == MLP)
+ struct GAS_Addresses_Suggestion_Requests *cur;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Shutting down addresses\n");
+ GNUNET_assert (NULL != handle);
+ GAS_addresses_destroy_all (handle);
+ handle->running = GNUNET_NO;
+ GNUNET_CONTAINER_multihashmap_destroy (handle->addresses);
+ handle->addresses = NULL;
+ while (NULL != (cur = handle->r_head))
{
- GAS_mlp_done (mlp);
+ GNUNET_CONTAINER_DLL_remove (handle->r_head, handle->r_tail, cur);
+ GNUNET_free (cur);
}
-#endif
+ handle->s_done (handle->solver);
+ GNUNET_free (handle);
+ /* Stop configured solution method */
+
+}
+
+struct PeerIteratorContext
+{
+ GNUNET_ATS_Peer_Iterator it;
+ void *it_cls;
+ struct GNUNET_CONTAINER_MultiHashMap *peers_returned;
+};
+
+static int
+peer_it (void *cls,
+ const struct GNUNET_HashCode * key,
+ void *value)
+{
+ struct PeerIteratorContext *ip_ctx = cls;
+ struct GNUNET_PeerIdentity tmp;
+
+ if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(ip_ctx->peers_returned, key))
+ {
+ GNUNET_CONTAINER_multihashmap_put(ip_ctx->peers_returned, key, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
+ tmp.hashPubKey = (*key);
+ ip_ctx->it (ip_ctx->it_cls, &tmp);
+ }
+
+ return GNUNET_OK;
+}
+
+/**
+ * Return all peers currently known to ATS
+ *
+ * @param handle the address handle
+ * @param p_it the iterator to call for every peer, callbach with id == NULL
+ * when done
+ * @param p_it_cls the closure for the iterator
+ */
+void
+GAS_addresses_iterate_peers (struct GAS_Addresses_Handle *handle, GNUNET_ATS_Peer_Iterator p_it, void *p_it_cls)
+{
+ struct PeerIteratorContext ip_ctx;
+ unsigned int size;
+
+ if (NULL == p_it)
+ return;
+ GNUNET_assert (NULL != handle->addresses);
+
+ size = GNUNET_CONTAINER_multihashmap_size(handle->addresses);
+ if (0 != size)
+ {
+ ip_ctx.it = p_it;
+ ip_ctx.it_cls = p_it_cls;
+ ip_ctx.peers_returned = GNUNET_CONTAINER_multihashmap_create (size, GNUNET_NO);
+ GNUNET_CONTAINER_multihashmap_iterate (handle->addresses, &peer_it, &ip_ctx);
+ GNUNET_CONTAINER_multihashmap_destroy (ip_ctx.peers_returned);
+ }
+ p_it (p_it_cls, NULL);
+}
+
+struct PeerInfoIteratorContext
+{
+ GNUNET_ATS_PeerInfo_Iterator it;
+ void *it_cls;
+};
+
+
+static int
+peerinfo_it (void *cls,
+ const struct GNUNET_HashCode * key,
+ void *value)
+{
+ struct PeerInfoIteratorContext *pi_ctx = cls;
+ struct ATS_Address *addr = (struct ATS_Address *) value;
+ struct GNUNET_ATS_Information *ats;
+ uint32_t ats_count;
+
+ if (NULL != pi_ctx->it)
+ {
+ ats_count = assemble_ats_information (addr, &ats);
+
+ pi_ctx->it (pi_ctx->it_cls,
+ &addr->peer,
+ addr->plugin,
+ addr->addr, addr->addr_len,
+ addr->active,
+ ats, ats_count,
+ addr->assigned_bw_out,
+ addr->assigned_bw_in);
+ GNUNET_free (ats);
+ }
+ return GNUNET_YES;
+}
+
+
+/**
+ * Return all peers currently known to ATS
+ *
+ * @param handle the address handle
+ * @param peer the respective peer
+ * @param pi_it the iterator to call for every peer
+ * @param pi_it_cls the closure for the iterator
+ */
+void
+GAS_addresses_get_peer_info (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
+ GNUNET_ATS_PeerInfo_Iterator pi_it,
+ void *pi_it_cls)
+{
+ struct PeerInfoIteratorContext pi_ctx;
+ struct GNUNET_BANDWIDTH_Value32NBO zero_bw;
+ GNUNET_assert (NULL != peer);
+ GNUNET_assert (NULL != handle->addresses);
+ if (NULL == pi_it)
+ return; /* does not make sense without callback */
+
+ zero_bw = GNUNET_BANDWIDTH_value_init (0);
+ pi_ctx.it = pi_it;
+ pi_ctx.it_cls = pi_it_cls;
+
+ GNUNET_CONTAINER_multihashmap_get_multiple (handle->addresses, &peer->hashPubKey, &peerinfo_it, &pi_ctx);
+
+ if (NULL != pi_it)
+ pi_it (pi_it_cls, NULL, NULL, NULL, 0, GNUNET_NO, NULL, 0, zero_bw, zero_bw);
}
diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h
index fe07563..b774cff 100644
--- a/src/ats/gnunet-service-ats_addresses.h
+++ b/src/ats/gnunet-service-ats_addresses.h
@@ -32,46 +32,88 @@
#include "gnunet_statistics_service.h"
#include "ats.h"
+#define ATS_BLOCKING_DELTA GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 100)
+
+struct GAS_Addresses_Handle;
+
+/**
+ * Address with additional information
+ */
struct ATS_Address
{
+ /**
+ * Next element in DLL
+ */
struct ATS_Address *next;
+ /**
+ * Previous element in DLL
+ */
struct ATS_Address *prev;
+ /**
+ * Peer ID
+ */
struct GNUNET_PeerIdentity peer;
- size_t addr_len;
-
+ /**
+ * Session ID, 0 if no session is given
+ */
uint32_t session_id;
- uint32_t ats_count;
-
+ /**
+ * Address
+ */
const void *addr;
- char *plugin;
+ /**
+ * Address length
+ */
+ size_t addr_len;
- void *mlp_information;
+ /**
+ * Plugin name
+ */
+ char *plugin;
- struct GNUNET_ATS_Information *ats;
+ /**
+ * Solver specific information for this address
+ */
+ void *solver_information;
+ /* CHECK USAGE */
struct GNUNET_TIME_Relative atsp_latency;
+ /* CHECK USAGE */
struct GNUNET_BANDWIDTH_Value32NBO atsp_utilization_in;
+ /* CHECK USAGE */
struct GNUNET_BANDWIDTH_Value32NBO atsp_utilization_out;
+
+ /* CHECK USAGE */
uint32_t atsp_distance;
+ /* CHECK USAGE */
uint32_t atsp_cost_wan;
+ /* CHECK USAGE */
uint32_t atsp_cost_lan;
+ /* CHECK USAGE */
uint32_t atsp_cost_wlan;
+ /* CHECK USAGE */
uint32_t atsp_network_type;
+ /**
+ * Inbound bandwidth assigned by solver in NBO
+ */
struct GNUNET_BANDWIDTH_Value32NBO assigned_bw_in;
+ /**
+ * Outbound bandwidth assigned by solver in NBO
+ */
struct GNUNET_BANDWIDTH_Value32NBO assigned_bw_out;
/**
@@ -95,36 +137,128 @@ struct ATS_Address
int used;
};
+
+/**
+ * Callback to call from solver when bandwidth for address has changed
+ *
+ * @param address the with changed bandwidth assigned
+ */
+
+typedef void
+ (*GAS_bandwidth_changed_cb) (void *cls, struct ATS_Address *address);
+
+/**
+ * Init the simplistic problem solving component
+ *
+ * Quotas:
+ * network[i] contains the network type as type GNUNET_ATS_NetworkType[i]
+ * out_quota[i] contains outbound quota for network type i
+ * in_quota[i] contains inbound quota for network type i
+ *
+ * Example
+ * network = {GNUNET_ATS_NET_UNSPECIFIED, GNUNET_ATS_NET_LOOPBACK, GNUNET_ATS_NET_LAN, GNUNET_ATS_NET_WAN, GNUNET_ATS_NET_WLAN}
+ * network[2] == GNUNET_ATS_NET_LAN
+ * out_quota[2] == 65353
+ * in_quota[2] == 65353
+ *
+ * @param cfg configuration handle
+ * @param stats the GNUNET_STATISTICS handle
+ * @param network array of GNUNET_ATS_NetworkType with length dest_length
+ * @param out_quota array of outbound quotas
+ * @param in_quota array of outbound quota
+ * @param bw_changed_cb callback to call when assigned changes
+ * @return handle for the solver on success, NULL on fail
+ */
+typedef void *
+ (*GAS_solver_init) (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_STATISTICS_Handle *stats,
+ int *network,
+ unsigned long long *out_quota,
+ unsigned long long *in_quota,
+ int dest_length,
+ GAS_bandwidth_changed_cb bw_changed_cb,
+ void *bw_changed_cb_cls);
+
+
+typedef void
+(*GAS_solver_address_change_preference) (void *solver,
+ void *client,
+ const struct GNUNET_PeerIdentity *peer,
+ enum GNUNET_ATS_PreferenceKind kind,
+ float score);
+
+/**
+ * Add a single address to the solver
+ *
+ * @param solver the solver Handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the address to add
+ */
+typedef void
+(*GAS_solver_address_add) (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap * addresses,
+ struct ATS_Address *address);
+
+
+
+typedef void
+ (*GAS_solver_address_delete) (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap *addresses,
+ struct ATS_Address *address,
+ int session_only);
+
+typedef void
+(*GAS_solver_address_update) (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap *addresses,
+ struct ATS_Address *address,
+ uint32_t session,
+ int in_use,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count);
+
+
+typedef const struct ATS_Address *
+(*GAS_solver_get_preferred_address) (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap *addresses,
+ const struct GNUNET_PeerIdentity *peer);
+
+
+typedef void
+ (*GAS_solver_done) (void *solver);
+
+
/**
* Initialize address subsystem.
*
* @param cfg configuration to use
* @param stats the statistics handle to use
*/
-void
+struct GAS_Addresses_Handle *
GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
const struct GNUNET_STATISTICS_Handle *stats);
-
/**
* Shutdown address subsystem.
*/
void
-GAS_addresses_done (void);
+GAS_addresses_done (struct GAS_Addresses_Handle *handle);
void
-GAS_addresses_handle_backoff_reset (const struct GNUNET_PeerIdentity *peer);
+GAS_addresses_handle_backoff_reset (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer);
/**
* This address is now used or not used anymore
*/
int
-GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer,
+GAS_addresses_in_use (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
const char *plugin_name, const void *plugin_addr,
size_t plugin_addr_len, uint32_t session_id, int in_use);
void
-GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
+GAS_addresses_update (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
const char *plugin_name, const void *plugin_addr,
size_t plugin_addr_len, uint32_t session_id,
const struct GNUNET_ATS_Information *atsi,
@@ -132,32 +266,82 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
void
-GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
+GAS_addresses_destroy (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
const char *plugin_name, const void *plugin_addr,
size_t plugin_addr_len, uint32_t session_id);
void
-GAS_addresses_destroy_all (void);
+GAS_addresses_destroy_all (struct GAS_Addresses_Handle *handle);
-// FIXME: this function should likely end up in the LP-subsystem and
-// not with 'addresses' in the future...
-// Note: this call should trigger an address suggestion
-// (GAS_scheduling_transmit_address_suggestion)
+/**
+ * Cancel address suggestions for a peer
+ *
+ * @param peer the respective peer
+ */
void
-GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer);
+GAS_addresses_request_address_cancel (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer);
+void
+GAS_addresses_request_address (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer);
-// FIXME: this function should likely end up in the LP-subsystem and
-// not with 'addresses' in the future...
void
-GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer,
+GAS_addresses_change_preference (struct GAS_Addresses_Handle *handle,
+ void *client,
+ const struct GNUNET_PeerIdentity *peer,
enum GNUNET_ATS_PreferenceKind kind,
float score);
+void
+GAS_addresses_add (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
+ const char *plugin_name, const void *plugin_addr,
+ size_t plugin_addr_len, uint32_t session_id,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count);
+
+
+typedef void (*GNUNET_ATS_Peer_Iterator) (void *p_it_cls,
+ const struct GNUNET_PeerIdentity *id);
-/* FIXME: add performance request API */
+/**
+ * Return all peers currently known to ATS
+ *
+ * @param p_it the iterator to call for every peer
+ * @param p_it_cls the closure for the iterator
+ */
+void
+GAS_addresses_iterate_peers (struct GAS_Addresses_Handle *handle,
+ GNUNET_ATS_Peer_Iterator p_it,
+ void *p_it_cls);
+
+typedef void (*GNUNET_ATS_PeerInfo_Iterator) (void *p_it_cls,
+ const struct GNUNET_PeerIdentity *id,
+ const char *plugin_name,
+ const void *plugin_addr, size_t plugin_addr_len,
+ const int address_active,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count,
+ struct GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in);
+
+/**
+ * Return information all peers currently known to ATS
+ *
+ * @param peer the respective peer
+ * @param pi_it the iterator to call for every peer
+ * @param pi_it_cls the closure for the iterator
+ */
+void
+GAS_addresses_get_peer_info (struct GAS_Addresses_Handle *handle,
+ const struct GNUNET_PeerIdentity *peer,
+ GNUNET_ATS_PeerInfo_Iterator pi_it,
+ void *pi_it_cls);
#endif
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c
index 8bfa010..98a77ae 100644
--- a/src/ats/gnunet-service-ats_addresses_mlp.c
+++ b/src/ats/gnunet-service-ats_addresses_mlp.c
@@ -31,6 +31,8 @@
#include "gnunet_statistics_service.h"
#include "glpk.h"
+#define LOG(kind,...) GNUNET_log_from (kind, "ats-mlp",__VA_ARGS__)
+
#define WRITE_MLP GNUNET_NO
#define DEBUG_ATS GNUNET_NO
#define VERBOSE_GLPK GNUNET_NO
@@ -48,68 +50,46 @@ mlp_solve_to_string (int retcode)
switch (retcode) {
case 0:
return "ok";
- break;
case GLP_EBADB:
return "invalid basis";
- break;
case GLP_ESING:
return "singular matrix";
- break;
case GLP_ECOND:
return "ill-conditioned matrix";
- break;
case GLP_EBOUND:
return "invalid bounds";
- break;
case GLP_EFAIL:
return "solver failed";
- break;
case GLP_EOBJLL:
return "objective lower limit reached";
- break;
case GLP_EOBJUL:
return "objective upper limit reached";
- break;
case GLP_EITLIM:
return "iteration limit exceeded";
- break;
case GLP_ETMLIM:
return "time limit exceeded";
- break;
case GLP_ENOPFS:
return "no primal feasible solution";
- break;
case GLP_EROOT:
return "root LP optimum not provided";
- break;
case GLP_ESTOP:
return "search terminated by application";
- break;
case GLP_EMIPGAP:
return "relative mip gap tolerance reached";
- break;
case GLP_ENOFEAS:
return "no dual feasible solution";
- break;
case GLP_ENOCVG:
return "no convergence";
- break;
case GLP_EINSTAB:
return "numerical instability";
- break;
case GLP_EDATA:
return "invalid data";
- break;
case GLP_ERANGE:
return "result out of range";
- break;
default:
GNUNET_break (0);
return "unknown error";
- break;
}
- GNUNET_break (0);
- return "unknown error";
}
@@ -124,29 +104,20 @@ mlp_status_to_string (int retcode)
switch (retcode) {
case GLP_UNDEF:
return "solution is undefined";
- break;
case GLP_FEAS:
return "solution is feasible";
- break;
case GLP_INFEAS:
return "solution is infeasible";
- break;
case GLP_NOFEAS:
return "no feasible solution exists";
- break;
case GLP_OPT:
return "solution is optimal";
- break;
case GLP_UNBND:
return "solution is unbounded";
- break;
default:
GNUNET_break (0);
return "unknown error";
- break;
}
- GNUNET_break (0);
- return "unknown error";
}
/**
@@ -162,37 +133,26 @@ mlp_ats_to_string (int ats_index)
switch (ats_index) {
case GNUNET_ATS_ARRAY_TERMINATOR:
return "GNUNET_ATS_ARRAY_TERMINATOR";
- break;
case GNUNET_ATS_UTILIZATION_UP:
return "GNUNET_ATS_UTILIZATION_UP";
- break;
case GNUNET_ATS_UTILIZATION_DOWN:
return "GNUNET_ATS_UTILIZATION_DOWN";
- break;
case GNUNET_ATS_COST_LAN:
return "GNUNET_ATS_COST_LAN";
- break;
case GNUNET_ATS_COST_WAN:
return "GNUNET_ATS_COST_LAN";
- break;
case GNUNET_ATS_COST_WLAN:
return "GNUNET_ATS_COST_WLAN";
- break;
case GNUNET_ATS_NETWORK_TYPE:
return "GNUNET_ATS_NETWORK_TYPE";
- break;
case GNUNET_ATS_QUALITY_NET_DELAY:
return "GNUNET_ATS_QUALITY_NET_DELAY";
- break;
case GNUNET_ATS_QUALITY_NET_DISTANCE:
return "GNUNET_ATS_QUALITY_NET_DISTANCE";
- break;
default:
+ GNUNET_break (0);
return "unknown";
- break;
}
- GNUNET_break (0);
- return "unknown error";
}
/**
@@ -278,7 +238,7 @@ mlp_delete_problem (struct GAS_MLP_Handle *mlp)
* @return GNUNET_OK to continue
*/
static int
-create_constraint_it (void *cls, const GNUNET_HashCode * key, void *value)
+create_constraint_it (void *cls, const struct GNUNET_HashCode * key, void *value)
{
struct GAS_MLP_Handle *mlp = cls;
struct ATS_Address *address = value;
@@ -286,8 +246,8 @@ create_constraint_it (void *cls, const GNUNET_HashCode * key, void *value)
unsigned int row_index;
char *name;
- GNUNET_assert (address->mlp_information != NULL);
- mlpi = (struct MLP_information *) address->mlp_information;
+ GNUNET_assert (address->solver_information != NULL);
+ mlpi = (struct MLP_information *) address->solver_information;
/* c 1) bandwidth capping
* b_t + (-M) * n_t <= 0
@@ -379,6 +339,7 @@ create_constraint_it (void *cls, const GNUNET_HashCode * key, void *value)
return GNUNET_OK;
}
+#if 0
/**
* Find the required ATS information for an address
*
@@ -387,7 +348,6 @@ create_constraint_it (void *cls, const GNUNET_HashCode * key, void *value)
*
* @return the index on success, otherwise GNUNET_SYSERR
*/
-
static int
mlp_lookup_ats (struct ATS_Address *addr, int ats_index)
{
@@ -407,6 +367,7 @@ mlp_lookup_ats (struct ATS_Address *addr, int ats_index)
else
return GNUNET_SYSERR;
}
+#endif
/**
* Adds the problem constraints for all addresses
@@ -599,7 +560,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON
/* For all addresses of this peer */
while (addr != NULL)
{
- mlpi = (struct MLP_information *) addr->mlp_information;
+ mlpi = (struct MLP_information *) addr->solver_information;
/* coefficient for c 2) */
ia[mlp->ci] = peer->r_c2;
@@ -650,7 +611,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON
for (tp = mlp->peer_head; tp != NULL; tp = tp->next)
for (ta = tp->head; ta != NULL; ta = ta->next)
{
- mlpi = ta->mlp_information;
+ mlpi = ta->solver_information;
value = mlpi->q_averaged[c];
mlpi->r_q[c] = mlp->r_q[c];
@@ -674,7 +635,7 @@ mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CON
* @return GNUNET_OK to continue
*/
static int
-create_columns_it (void *cls, const GNUNET_HashCode * key, void *value)
+create_columns_it (void *cls, const struct GNUNET_HashCode * key, void *value)
{
struct GAS_MLP_Handle *mlp = cls;
struct ATS_Address *address = value;
@@ -682,8 +643,8 @@ create_columns_it (void *cls, const GNUNET_HashCode * key, void *value)
unsigned int col;
char *name;
- GNUNET_assert (address->mlp_information != NULL);
- mlpi = address->mlp_information;
+ GNUNET_assert (address->solver_information != NULL);
+ mlpi = address->solver_information;
/* Add bandwidth column */
col = glp_add_cols (mlp->prob, 2);
@@ -866,7 +827,7 @@ lp_solv:
end = GNUNET_TIME_absolute_get ();
duration = GNUNET_TIME_absolute_get_difference (start, end);
mlp->lp_solved++;
- mlp->lp_total_duration =+ duration.rel_value;
+ mlp->lp_total_duration += duration.rel_value;
s_ctx->lp_duration = duration;
GNUNET_STATISTICS_update (mlp->stats,"# LP problem solved", 1, GNUNET_NO);
@@ -943,7 +904,7 @@ mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContex
end = GNUNET_TIME_absolute_get ();
duration = GNUNET_TIME_absolute_get_difference (start, end);
mlp->mlp_solved++;
- mlp->mlp_total_duration =+ duration.rel_value;
+ mlp->mlp_total_duration += duration.rel_value;
s_ctx->mlp_duration = duration;
GNUNET_STATISTICS_update (mlp->stats,"# MLP problem solved", 1, GNUNET_NO);
@@ -972,7 +933,7 @@ mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContex
return GNUNET_OK;
}
-int GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx);
+int GAS_mlp_solve_problem (void *solver, struct GAS_MLP_SolutionContext *ctx);
static void
@@ -996,13 +957,14 @@ mlp_scheduler (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
/**
* Solves the MLP problem
*
- * @param mlp the MLP Handle
+ * @param solver the MLP Handle
* @param ctx solution context
* @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
*/
int
-GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx)
+GAS_mlp_solve_problem (void *solver, struct GAS_MLP_SolutionContext *ctx)
{
+ struct GAS_MLP_Handle *mlp = solver;
int res;
/* Check if solving is already running */
if (GNUNET_YES == mlp->semaphore)
@@ -1080,7 +1042,7 @@ GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContex
double b = 0.0;
double n = 0.0;
- mlpi = a->mlp_information;
+ mlpi = a->solver_information;
b = glp_mip_col_val(mlp->prob, mlpi->c_b);
mlpi->b = b;
@@ -1111,15 +1073,23 @@ GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContex
*
* @param cfg the GNUNET_CONFIGURATION_Handle handle
* @param stats the GNUNET_STATISTICS handle
- * @param max_duration maximum numbers of iterations for the LP/MLP Solver
- * @param max_iterations maximum time limit for the LP/MLP Solver
- * @return struct GAS_MLP_Handle * on success, NULL on fail
+ * @param network array of GNUNET_ATS_NetworkType with length dest_length
+ * @param out_dest array of outbound quotas
+ * @param in_dest array of outbound quota
+ * @param dest_length array length for quota arrays
+ * @param bw_changed_cb callback for changed bandwidth amounts
+ * @param bw_changed_cb_cls cls for callback
+ * @return struct GAS_MLP_Handle on success, NULL on fail
*/
-struct GAS_MLP_Handle *
+void *
GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
const struct GNUNET_STATISTICS_Handle *stats,
- struct GNUNET_TIME_Relative max_duration,
- unsigned int max_iterations)
+ int *network,
+ unsigned long long *out_dest,
+ unsigned long long *in_dest,
+ int dest_length,
+ GAS_bandwidth_changed_cb bw_changed_cb,
+ void *bw_changed_cb_cls)
{
struct GAS_MLP_Handle * mlp = GNUNET_malloc (sizeof (struct GAS_MLP_Handle));
@@ -1134,6 +1104,9 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
char * quota_out_str;
char * quota_in_str;
+ struct GNUNET_TIME_Relative max_duration;
+ long long unsigned int max_iterations;
+
/* Init GLPK environment */
int res = glp_init_env();
switch (res) {
@@ -1167,6 +1140,18 @@ GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
mlp->BIG_M = (double) BIG_M_VALUE;
+ /* Get timeout for iterations */
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time(cfg, "ats", "MAX_DURATION", &max_duration))
+ {
+ max_duration = MLP_MAX_EXEC_DURATION;
+ }
+
+ /* Get maximum number of iterations */
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_size(cfg, "ats", "MAX_ITERATIONS", &max_iterations))
+ {
+ max_iterations = MLP_MAX_ITERATIONS;
+ }
+
/* Get diversity coefficient from configuration */
if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
"COEFFICIENT_D",
@@ -1388,29 +1373,33 @@ update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address)
GNUNET_i2s (&address->peer));
GNUNET_assert (NULL != address);
- GNUNET_assert (NULL != address->mlp_information);
- GNUNET_assert (NULL != address->ats);
+ GNUNET_assert (NULL != address->solver_information);
+// GNUNET_assert (NULL != address->ats);
- struct MLP_information *mlpi = address->mlp_information;
- struct GNUNET_ATS_Information *ats = address->ats;
+ struct MLP_information *mlpi = address->solver_information;
+ //struct GNUNET_ATS_Information *ats = address->ats;
GNUNET_assert (mlpi != NULL);
int c;
for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
{
- int index = mlp_lookup_ats(address, mlp->q[c]);
+
+ /* FIXME int index = mlp_lookup_ats(address, mlp->q[c]); */
+ int index = GNUNET_SYSERR;
if (index == GNUNET_SYSERR)
continue;
-
+ /* FIXME
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value `%s': %f\n",
GNUNET_i2s (&address->peer),
mlp_ats_to_string(mlp->q[c]),
(double) ats[index].value);
- int i = mlpi->q_avg_i[c];
+ int i = mlpi->q_avg_i[c];*/
double * qp = mlpi->q[c];
+ /* FIXME
qp[i] = (double) ats[index].value;
+ */
int t;
for (t = 0; t < MLP_AVERAGING_QUEUE_LENGTH; t++)
@@ -1538,6 +1527,20 @@ update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address)
}
}
+
+/**
+ * Add a single address to the solve
+ *
+ * @param solver the solver Handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the address to add
+ */
+void
+GAS_mlp_address_add (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address)
+{
+
+}
+
/**
* Updates a single address in the MLP problem
*
@@ -1547,14 +1550,24 @@ update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address)
* Otherwise the addresses' values can be updated and the existing base can
* be reused
*
- * @param mlp the MLP Handle
- * @param addresses the address hashmap
- * the address has to be already removed from the hashmap
- * @param address the address to update
+ * @param solver the solver Handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the update address
+ * @param session the new session (if changed otherwise current)
+ * @param in_use the new address in use state (if changed otherwise current)
+ * @param atsi the latest ATS information
+ * @param atsi_count the atsi count
*/
void
-GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address)
+GAS_mlp_address_update (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap *addresses,
+ struct ATS_Address *address,
+ uint32_t session,
+ int in_use,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count)
{
+ struct GAS_MLP_Handle *mlp = solver;
int new;
struct MLP_information *mlpi;
struct GAS_MLP_SolutionContext ctx;
@@ -1562,7 +1575,7 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
GNUNET_STATISTICS_update (mlp->stats, "# MLP address updates", 1, GNUNET_NO);
/* We add a new address */
- if (address->mlp_information == NULL)
+ if (address->solver_information == NULL)
new = GNUNET_YES;
else
new = GNUNET_NO;
@@ -1583,7 +1596,7 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
mlpi->q_averaged[c] = 0.0;
}
- address->mlp_information = mlpi;
+ address->solver_information = mlpi;
mlp->addr_in_problem ++;
GNUNET_STATISTICS_update (mlp->stats, "# addresses in MLP", 1, GNUNET_NO);
@@ -1650,22 +1663,27 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
*
* The MLP problem has to be recreated and the problem has to be resolved
*
- * @param mlp the MLP Handle
+ * @param solver the MLP Handle
* @param addresses the address hashmap
* the address has to be already removed from the hashmap
* @param address the address to delete
+ * @param session_only delete only session not whole address
*/
void
-GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address)
+GAS_mlp_address_delete (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap * addresses,
+ struct ATS_Address *address,
+ int session_only)
{
+ struct GAS_MLP_Handle *mlp = solver;
GNUNET_STATISTICS_update (mlp->stats,"# LP address deletions", 1, GNUNET_NO);
struct GAS_MLP_SolutionContext ctx;
/* Free resources */
- if (address->mlp_information != NULL)
+ if (address->solver_information != NULL)
{
- GNUNET_free (address->mlp_information);
- address->mlp_information = NULL;
+ GNUNET_free (address->solver_information);
+ address->solver_information = NULL;
mlp->addr_in_problem --;
GNUNET_STATISTICS_update (mlp->stats, "# addresses in MLP", -1, GNUNET_NO);
@@ -1706,22 +1724,22 @@ GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
}
static int
-mlp_get_preferred_address_it (void *cls, const GNUNET_HashCode * key, void *value)
+mlp_get_preferred_address_it (void *cls, const struct GNUNET_HashCode * key, void *value)
{
- struct ATS_PreferedAddress *aa = (struct ATS_PreferedAddress *) cls;
+ struct ATS_Address *aa = (struct ATS_Address *) cls;
struct ATS_Address *addr = value;
- struct MLP_information *mlpi = addr->mlp_information;
+ struct MLP_information *mlpi = addr->solver_information;
if (mlpi == NULL)
return GNUNET_YES;
if (mlpi->n == GNUNET_YES)
{
- aa->address = addr;
+ aa = addr;
if (mlpi->b > (double) UINT32_MAX)
- aa->bandwidth_out = UINT32_MAX;
+ aa->assigned_bw_out.value__ = htonl (UINT32_MAX);
else
- aa->bandwidth_out = (uint32_t) mlpi->b;
- aa->bandwidth_in = 0;
+ aa->assigned_bw_out.value__ = htonl((uint32_t) mlpi->b);
+ aa->assigned_bw_in.value__ = htonl(0);
return GNUNET_NO;
}
return GNUNET_YES;
@@ -1731,20 +1749,17 @@ mlp_get_preferred_address_it (void *cls, const GNUNET_HashCode * key, void *valu
/**
* Get the preferred address for a specific peer
*
- * @param mlp the MLP Handle
+ * @param solver the MLP Handle
* @param addresses address hashmap
* @param peer the peer
* @return suggested address
*/
-struct ATS_PreferedAddress *
-GAS_mlp_get_preferred_address (struct GAS_MLP_Handle *mlp,
+const struct ATS_Address *
+GAS_mlp_get_preferred_address (void *solver,
struct GNUNET_CONTAINER_MultiHashMap * addresses,
const struct GNUNET_PeerIdentity *peer)
{
- struct ATS_PreferedAddress * aa = GNUNET_malloc (sizeof (struct ATS_PreferedAddress));
- aa->address = NULL;
- aa->bandwidth_in = 0;
- aa->bandwidth_out = 0;
+ struct ATS_Address * aa = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting preferred address for `%s'\n", GNUNET_i2s (peer));
GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey, mlp_get_preferred_address_it, aa);
return aa;
@@ -1754,31 +1769,37 @@ GAS_mlp_get_preferred_address (struct GAS_MLP_Handle *mlp,
/**
* Changes the preferences for a peer in the MLP problem
*
- * @param mlp the MLP Handle
+ * @param solver the MLP Handle
+ * @param client client
* @param peer the peer
* @param kind the kind to change the preference
* @param score the score
*/
void
-GAS_mlp_address_change_preference (struct GAS_MLP_Handle *mlp,
+GAS_mlp_address_change_preference (void *solver,
+ void *client,
const struct GNUNET_PeerIdentity *peer,
enum GNUNET_ATS_PreferenceKind kind,
float score)
{
+ struct GAS_MLP_Handle *mlp = solver;
GNUNET_STATISTICS_update (mlp->stats,"# LP address preference changes", 1, GNUNET_NO);
- struct ATS_Peer *p = mlp_find_peer (mlp, peer);
- p = p;
+ //struct ATS_Peer *p = mlp_find_peer (mlp, peer);
+ //FIXME to finish implementation
/* Here we have to do the matching */
+
}
/**
* Shutdown the MLP problem solving component
- * @param mlp the MLP handle
+ *
+ * @param solver the solver handle
*/
void
-GAS_mlp_done (struct GAS_MLP_Handle *mlp)
+GAS_mlp_done (void *solver)
{
+ struct GAS_MLP_Handle *mlp = solver;
struct ATS_Peer * peer;
struct ATS_Address *addr;
@@ -1799,8 +1820,8 @@ GAS_mlp_done (struct GAS_MLP_Handle *mlp)
for (addr = peer->head; NULL != addr; addr = peer->head)
{
GNUNET_CONTAINER_DLL_remove(peer->head, peer->tail, addr);
- GNUNET_free (addr->mlp_information);
- addr->mlp_information = NULL;
+ GNUNET_free (addr->solver_information);
+ addr->solver_information = NULL;
}
GNUNET_free (peer);
peer = mlp->peer_head;
diff --git a/src/ats/gnunet-service-ats_addresses_mlp.h b/src/ats/gnunet-service-ats_addresses_mlp.h
index d37eea7..a49f585 100644
--- a/src/ats/gnunet-service-ats_addresses_mlp.h
+++ b/src/ats/gnunet-service-ats_addresses_mlp.h
@@ -20,7 +20,7 @@
/**
* @file ats/gnunet-service-ats_addresses_mlp.h
- * @brief ats mlp problem solver
+ * @brief ats MLP problem solver
* @author Matthias Wachs
* @author Christian Grothoff
*/
@@ -34,8 +34,6 @@
#ifndef GNUNET_SERVICE_ATS_ADDRESSES_MLP_H
#define GNUNET_SERVICE_ATS_ADDRESSES_MLP_H
-#define DEBUG_MLP GNUNET_EXTRA_LOGGING
-
#define BIG_M_VALUE (UINT32_MAX) /10
#define BIG_M_STRING "unlimited"
@@ -66,13 +64,6 @@ struct ATS_Peer
struct ATS_Address *tail;
};
-struct ATS_PreferedAddress
-{
- uint32_t bandwidth_out;
- uint32_t bandwidth_in;
- struct ATS_Address *address;
-};
-
struct GAS_MLP_SolutionContext
{
int lp_result;
@@ -105,12 +96,20 @@ struct GAS_MLP_Handle
/**
* GLPK LP control parameter
*/
+#if HAVE_LIBGLPK
glp_smcp control_param_lp;
+#else
+ void *control_param_lp;
+#endif
/**
* GLPK LP control parameter
*/
+#if HAVE_LIBGLPK
glp_iocp control_param_mlp;
+#else
+ void *control_param_mlp;
+#endif
/**
* Solves the task in an regular interval
@@ -317,26 +316,34 @@ struct MLP_information
*
* @param cfg configuration handle
* @param stats the GNUNET_STATISTICS handle
- * @param max_duration maximum numbers of iterations for the LP/MLP Solver
- * @param max_iterations maximum time limit for the LP/MLP Solver
- * @return struct GAS_MLP_Handle * on success, NULL on fail
+ * @param network array of GNUNET_ATS_NetworkType with length dest_length
+ * @param out_dest array of outbound quotas
+ * @param in_dest array of outbound quota
+ * @param dest_length array length for quota arrays
+ * @param bw_changed_cb callback for changed bandwidth amounts
+ * @param bw_changed_cb_cls cls for callback
+ * @return struct GAS_MLP_Handle on success, NULL on fail
*/
-struct GAS_MLP_Handle *
+void *
GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
const struct GNUNET_STATISTICS_Handle *stats,
- struct GNUNET_TIME_Relative max_duration,
- unsigned int max_iterations);
+ int *network,
+ unsigned long long *out_dest,
+ unsigned long long *in_dest,
+ int dest_length,
+ GAS_bandwidth_changed_cb bw_changed_cb,
+ void *bw_changed_cb_cls);
+
/**
- * Solves the MLP problem on demand
+ * Add a single address to the solve
*
- * @param mlp the MLP Handle
- * @param ctx solution context
- * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
+ * @param solver the solver Handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the address to add
*/
-int
-GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx);
-
+void
+GAS_mlp_address_add (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address);
/**
* Updates a single address in the MLP problem
@@ -347,13 +354,22 @@ GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContex
* Otherwise the addresses' values can be updated and the existing base can
* be reused
*
- * @param mlp the MLP Handle
- * @param addresses the address hashmap
- * the address has to be already added from the hashmap
- * @param address the address to update
+ * @param solver the solver Handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the update address
+ * @param session the new session (if changed otherwise current)
+ * @param in_use the new address in use state (if changed otherwise current)
+ * @param atsi the latest ATS information
+ * @param atsi_count the atsi count
*/
void
-GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address);
+GAS_mlp_address_update (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap *addresses,
+ struct ATS_Address *address,
+ uint32_t session,
+ int in_use,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count);
/**
@@ -361,25 +377,31 @@ GAS_mlp_address_update (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_Mult
*
* The MLP problem has to be recreated and the problem has to be resolved
*
- * @param mlp the MLP Handle
+ * @param solver the MLP Handle
* @param addresses the address hashmap
* the address has to be already removed from the hashmap
* @param address the address to delete
+ * @param session_only delete only session not whole address
*/
void
-GAS_mlp_address_delete (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address);
+GAS_mlp_address_delete (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap *addresses,
+ struct ATS_Address *address,
+ int session_only);
/**
* Changes the preferences for a peer in the MLP problem
*
- * @param mlp the MLP Handle
+ * @param solver the MLP Handle
+ * @param client client
* @param peer the peer
* @param kind the kind to change the preference
* @param score the score
*/
void
-GAS_mlp_address_change_preference (struct GAS_MLP_Handle *mlp,
+GAS_mlp_address_change_preference (void *solver,
+ void *client,
const struct GNUNET_PeerIdentity *peer,
enum GNUNET_ATS_PreferenceKind kind,
float score);
@@ -388,21 +410,23 @@ GAS_mlp_address_change_preference (struct GAS_MLP_Handle *mlp,
/**
* Get the preferred address for a specific peer
*
- * @param mlp the MLP Handle
+ * @param solver the MLP Handle
* @param addresses address hashmap
* @param peer the peer
* @return suggested address
*/
-struct ATS_PreferedAddress *
-GAS_mlp_get_preferred_address (struct GAS_MLP_Handle *mlp,
+const struct ATS_Address *
+GAS_mlp_get_preferred_address (void *solver,
struct GNUNET_CONTAINER_MultiHashMap * addresses,
const struct GNUNET_PeerIdentity *peer);
/**
* Shutdown the MLP problem solving component
+ *
+ * @param solver the solver handle
*/
void
-GAS_mlp_done ();
+GAS_mlp_done (void *solver);
#endif
/* end of gnunet-service-ats_addresses_mlp.h */
diff --git a/src/ats/gnunet-service-ats_addresses_simplistic.c b/src/ats/gnunet-service-ats_addresses_simplistic.c
new file mode 100644
index 0000000..74a4b43
--- /dev/null
+++ b/src/ats/gnunet-service-ats_addresses_simplistic.c
@@ -0,0 +1,1377 @@
+/*
+ This file is part of GNUnet.
+ (C) 2011 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file ats/gnunet-service-ats_addresses_simplistic.h
+ * @brief ats simplistic ressource assignment
+ * @author Matthias Wachs
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet-service-ats_addresses.h"
+#include "gnunet_statistics_service.h"
+
+#define LOG(kind,...) GNUNET_log_from (kind, "ats-simplistic",__VA_ARGS__)
+
+/**
+ * ATS simplistic solver
+ *
+ * Assigns in and outbound bandwidth equally for all addresses in specific
+ * network type (WAN, LAN) based on configured in and outbound quota for this
+ * network.
+ *
+ * For each peer only a single is selected and marked as "active" in the address
+ * struct.
+ *
+ * E.g.:
+ *
+ * You have the networks WAN and LAN and quotas
+ * WAN_TOTAL_IN, WAN_TOTAL_OUT
+ * LAN_TOTAL_IN, LAN_TOTAL_OUT
+ *
+ * If you have x addresses in the network segment LAN, the quotas are
+ * QUOTA_PER_ADDRESS = LAN_TOTAL_OUT / x
+ *
+ * Quotas are automatically recalculated and reported back when addresses are
+ * - requested
+ *
+ */
+
+#define PREF_AGING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+#define PREF_AGING_FACTOR 0.95
+
+#define DEFAULT_PREFERENCE 1.0
+#define MIN_UPDATE_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+/**
+ * A handle for the simplistic solver
+ */
+struct GAS_SIMPLISTIC_Handle
+{
+ /**
+ * Statistics handle
+ */
+
+ struct GNUNET_STATISTICS_Handle *stats;
+
+ /**
+ * Total number of addresses for solver
+ */
+ unsigned int total_addresses;
+
+ /**
+ * Number of active addresses for solver
+ */
+ unsigned int active_addresses;
+
+ /**
+ * Networks array
+ */
+ struct Network *network_entries;
+
+ /**
+ * Number of networks
+ */
+ unsigned int networks;
+
+ /**
+ * Callback
+ */
+ GAS_bandwidth_changed_cb bw_changed;
+
+ /**
+ * Callback cls
+ */
+ void *bw_changed_cls;
+
+ struct GNUNET_CONTAINER_MultiHashMap *prefs;
+
+ struct PreferenceClient *pc_head;
+ struct PreferenceClient *pc_tail;
+};
+
+struct Network
+{
+ /**
+ * ATS network type
+ */
+ unsigned int type;
+
+ /**
+ * Network description
+ */
+ char *desc;
+
+ /**
+ * Total inbound quota
+ *
+ */
+ unsigned long long total_quota_in;
+
+ /**
+ * Total outbound quota
+ *
+ */
+ unsigned long long total_quota_out;
+
+ /**
+ * Number of active addresses for this network
+ */
+ unsigned int active_addresses;
+
+ /**
+ * Number of total addresses for this network
+ */
+ unsigned int total_addresses;
+
+ /**
+ * String for statistics total addresses
+ */
+ char *stat_total;
+
+ /**
+ * String for statistics active addresses
+ */
+ char *stat_active;
+
+ struct AddressWrapper *head;
+ struct AddressWrapper *tail;
+};
+
+struct AddressWrapper
+{
+ struct AddressWrapper *next;
+ struct AddressWrapper *prev;
+
+ struct ATS_Address *addr;
+};
+
+
+struct PreferenceClient
+{
+ struct PreferenceClient *prev;
+ struct PreferenceClient *next;
+ void *client;
+
+ double f_total[GNUNET_ATS_PreferenceCount];
+
+ struct PreferencePeer *p_head;
+ struct PreferencePeer *p_tail;
+};
+
+
+struct PreferencePeer
+{
+ struct PreferencePeer *next;
+ struct PreferencePeer *prev;
+ struct PreferenceClient *client;
+ struct GAS_SIMPLISTIC_Handle *s;
+ struct GNUNET_PeerIdentity id;
+
+ double f[GNUNET_ATS_PreferenceCount];
+ double f_rel[GNUNET_ATS_PreferenceCount];
+ double f_rel_total;
+
+ GNUNET_SCHEDULER_TaskIdentifier aging_task;
+};
+
+/**
+ * Get the prefered address for a specific peer
+ *
+ * @param solver the solver handle
+ * @param addresses the address hashmap containing all addresses
+ * @param peer the identity of the peer
+ */
+const struct ATS_Address *
+GAS_simplistic_get_preferred_address (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap * addresses,
+ const struct GNUNET_PeerIdentity *peer);
+
+/**
+ * Init the simplistic problem solving component
+ *
+ * Quotas:
+ * network[i] contains the network type as type GNUNET_ATS_NetworkType[i]
+ * out_quota[i] contains outbound quota for network type i
+ * in_quota[i] contains inbound quota for network type i
+ *
+ * Example
+ * network = {GNUNET_ATS_NET_UNSPECIFIED, GNUNET_ATS_NET_LOOPBACK, GNUNET_ATS_NET_LAN, GNUNET_ATS_NET_WAN, GNUNET_ATS_NET_WLAN}
+ * network[2] == GNUNET_ATS_NET_LAN
+ * out_quota[2] == 65353
+ * in_quota[2] == 65353
+ *
+ * @param cfg configuration handle
+ * @param stats the GNUNET_STATISTICS handle
+ * @param network array of GNUNET_ATS_NetworkType with length dest_length
+ * @param out_quota array of outbound quotas
+ * @param in_quota array of outbound quota
+ * @param dest_length array length for quota arrays
+ * @param bw_changed_cb callback for changed bandwidth amounts
+ * @param bw_changed_cb_cls cls for callback
+ * @return handle for the solver on success, NULL on fail
+ */
+void *
+GAS_simplistic_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_STATISTICS_Handle *stats,
+ int *network,
+ unsigned long long *out_quota,
+ unsigned long long *in_quota,
+ int dest_length,
+ GAS_bandwidth_changed_cb bw_changed_cb,
+ void *bw_changed_cb_cls)
+{
+ int c;
+ struct GAS_SIMPLISTIC_Handle *s = GNUNET_malloc (sizeof (struct GAS_SIMPLISTIC_Handle));
+ struct Network * cur;
+ char * net_str[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkTypeString;
+
+
+ s->stats = (struct GNUNET_STATISTICS_Handle *) stats;
+ s->bw_changed = bw_changed_cb;
+ s->bw_changed_cls = bw_changed_cb_cls;
+ s->networks = dest_length;
+ s->network_entries = GNUNET_malloc (dest_length * sizeof (struct Network));
+ s->active_addresses = 0;
+ s->total_addresses = 0;
+ s->prefs = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
+
+ for (c = 0; c < dest_length; c++)
+ {
+ cur = &s->network_entries[c];
+ cur->total_addresses = 0;
+ cur->active_addresses = 0;
+ cur->type = network[c];
+ cur->total_quota_in = in_quota[c];
+ cur->total_quota_out = out_quota[c];
+ cur->desc = net_str[c];
+ GNUNET_asprintf (&cur->stat_total, "# ATS addresses %s total", cur->desc);
+ GNUNET_asprintf (&cur->stat_active, "# ATS active addresses %s total", cur->desc);
+ }
+ return s;
+}
+
+static int
+free_pref (void *cls,
+ const struct GNUNET_HashCode * key,
+ void *value)
+{
+ float *v = value;
+ GNUNET_free (v);
+ return GNUNET_OK;
+}
+
+/**
+ * Shutdown the simplistic problem solving component
+ *
+ * @param solver the respective handle to shutdown
+ */
+void
+GAS_simplistic_done (void *solver)
+{
+ struct GAS_SIMPLISTIC_Handle *s = solver;
+ struct PreferenceClient *pc;
+ struct PreferenceClient *next_pc;
+ struct PreferencePeer *p;
+ struct PreferencePeer *next_p;
+ struct AddressWrapper *cur;
+ struct AddressWrapper *next;
+ int c;
+ GNUNET_assert (s != NULL);
+
+ for (c = 0; c < s->networks; c++)
+ {
+ if (s->network_entries[c].total_addresses > 0)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Had %u addresses for network `%s' not deleted during shutdown\n",
+ s->network_entries[c].total_addresses,
+ s->network_entries[c].desc);
+ GNUNET_break (0);
+ }
+
+ if (s->network_entries[c].active_addresses > 0)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Had %u active addresses for network `%s' not deleted during shutdown\n",
+ s->network_entries[c].active_addresses,
+ s->network_entries[c].desc);
+ GNUNET_break (0);
+ }
+
+ next = s->network_entries[c].head;
+ while (NULL != (cur = next))
+ {
+ next = cur->next;
+ GNUNET_CONTAINER_DLL_remove (s->network_entries[c].head,
+ s->network_entries[c].tail,
+ cur);
+ GNUNET_free (cur);
+ }
+ GNUNET_free (s->network_entries[c].stat_total);
+ GNUNET_free (s->network_entries[c].stat_active);
+ }
+ if (s->total_addresses > 0)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Had %u addresses not deleted during shutdown\n",
+ s->total_addresses);
+ GNUNET_break (0);
+ }
+ if (s->active_addresses > 0)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Had %u active addresses not deleted during shutdown\n",
+ s->active_addresses);
+ GNUNET_break (0);
+ }
+ GNUNET_free (s->network_entries);
+
+ next_pc = s->pc_head;
+ while (NULL != (pc = next_pc))
+ {
+ next_pc = pc->next;
+ GNUNET_CONTAINER_DLL_remove (s->pc_head, s->pc_tail, pc);
+ next_p = pc->p_head;
+ while (NULL != (p = next_p))
+ {
+ next_p = p->next;
+ if (GNUNET_SCHEDULER_NO_TASK != p->aging_task)
+ {
+ GNUNET_SCHEDULER_cancel(p->aging_task);
+ p->aging_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_CONTAINER_DLL_remove (pc->p_head, pc->p_tail, p);
+ GNUNET_free (p);
+ }
+ GNUNET_free (pc);
+ }
+
+ GNUNET_CONTAINER_multihashmap_iterate (s->prefs, &free_pref, NULL);
+ GNUNET_CONTAINER_multihashmap_destroy (s->prefs);
+ GNUNET_free (s);
+}
+
+
+/**
+ * Test if bandwidth is available in this network
+ *
+ * @param s the solver handle
+ * @param net the network type to update
+ * @return GNUNET_YES or GNUNET_NO
+ */
+
+static int
+bw_available_in_network (struct Network *net)
+{
+ unsigned int na = net->active_addresses + 1;
+ uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
+ if (((net->total_quota_in / na) > min_bw) &&
+ ((net->total_quota_out / na) > min_bw))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Enough bandwidth available for %u active addresses in network `%s'\n",
+ na,
+ net->desc);
+
+ return GNUNET_YES;
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Not enough bandwidth available for %u active addresses in network `%s'\n",
+ na,
+ net->desc);
+ return GNUNET_NO;
+}
+
+
+/**
+ * Update the quotas for a network type
+ *
+ * @param s the solver handle
+ * @param net the network type to update
+ * @param address_except address excluded from notifcation, since we suggest
+ * this address
+ */
+static void
+update_quota_per_network (struct GAS_SIMPLISTIC_Handle *s,
+ struct Network *net,
+ struct ATS_Address *address_except)
+{
+ unsigned long long remaining_quota_in = 0;
+ unsigned long long quota_out_used = 0;
+
+ unsigned long long remaining_quota_out = 0;
+ unsigned long long quota_in_used = 0;
+ uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
+ double total_prefs; /* Important: has to be double not float due to precision */
+ double cur_pref; /* Important: has to be double not float due to precision */
+ double *t = NULL; /* Important: has to be double not float due to precision */
+
+ unsigned long long assigned_quota_in = 0;
+ unsigned long long assigned_quota_out = 0;
+ struct AddressWrapper *cur;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n",
+ net->desc, net->active_addresses, net->total_quota_in, net->total_quota_in);
+
+ if (net->active_addresses == 0)
+ return; /* no addresses to update */
+
+ /* Idea TODO
+ *
+ * Assign every peer in network minimum Bandwidth
+ * Distribute bandwidth left according to preference
+ */
+
+ if ((net->active_addresses * min_bw) > net->total_quota_in)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ if ((net->active_addresses * min_bw) > net->total_quota_out)
+ {
+ GNUNET_break (0);
+ return;
+ }
+
+ remaining_quota_in = net->total_quota_in - (net->active_addresses * min_bw);
+ remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Remaining bandwidth : (in/out): %llu/%llu \n",
+ remaining_quota_in, remaining_quota_out);
+ total_prefs = 0.0;
+ for (cur = net->head; NULL != cur; cur = cur->next)
+ {
+ if (GNUNET_YES == cur->addr->active)
+ {
+ t = GNUNET_CONTAINER_multihashmap_get (s->prefs, &cur->addr->peer.hashPubKey);
+ if (NULL == t)
+ total_prefs += DEFAULT_PREFERENCE;
+ else
+ {
+ total_prefs += (*t);
+ }
+ }
+ }
+ for (cur = net->head; NULL != cur; cur = cur->next)
+ {
+ if (GNUNET_YES == cur->addr->active)
+ {
+ cur_pref = 0.0;
+ t = GNUNET_CONTAINER_multihashmap_get (s->prefs, &cur->addr->peer.hashPubKey);
+ if (NULL == t)
+ cur_pref = DEFAULT_PREFERENCE;
+ else
+ cur_pref = (*t);
+ assigned_quota_in = min_bw + ((cur_pref / total_prefs) * remaining_quota_in);
+ assigned_quota_out = min_bw + ((cur_pref / total_prefs) * remaining_quota_out);
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "New quota for peer `%s' with preference (cur/total) %.3f/%.3f (in/out): %llu / %llu\n",
+ GNUNET_i2s (&cur->addr->peer),
+ cur_pref, total_prefs,
+ assigned_quota_in, assigned_quota_out);
+ }
+ else
+ {
+ assigned_quota_in = 0;
+ assigned_quota_out = 0;
+ }
+
+ quota_in_used += assigned_quota_in;
+ quota_out_used += assigned_quota_out;
+ /* Prevent overflow due to rounding errors */
+ if (assigned_quota_in > UINT32_MAX)
+ assigned_quota_in = UINT32_MAX;
+ if (assigned_quota_out > UINT32_MAX)
+ assigned_quota_out = UINT32_MAX;
+
+ /* Compare to current bandwidth assigned */
+ if ((assigned_quota_in != ntohl(cur->addr->assigned_bw_in.value__)) ||
+ (assigned_quota_out != ntohl(cur->addr->assigned_bw_out.value__)))
+ {
+ cur->addr->assigned_bw_in.value__ = htonl (assigned_quota_in);
+ cur->addr->assigned_bw_out.value__ = htonl (assigned_quota_out);
+ /* Notify on change */
+ if ((GNUNET_YES == cur->addr->active) && (cur->addr != address_except))
+ s->bw_changed (s->bw_changed_cls, cur->addr);
+ }
+
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Total bandwidth assigned is (in/out): %llu /%llu\n",
+ quota_in_used,
+ quota_out_used);
+ if (quota_out_used > net->total_quota_out + 1) /* +1 is required due to rounding errors */
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Total outbound bandwidth assigned is larger than allowed (used/allowed) for %u active addresses: %llu / %llu\n",
+ net->active_addresses,
+ quota_out_used,
+ net->total_quota_out);
+ }
+ if (quota_in_used > net->total_quota_in + 1) /* +1 is required due to rounding errors */
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR,
+ "Total inbound bandwidth assigned is larger than allowed (used/allowed) for %u active addresses: %llu / %llu\n",
+ net->active_addresses,
+ quota_in_used,
+ net->total_quota_in);
+ }
+}
+
+static void
+update_all_networks (struct GAS_SIMPLISTIC_Handle *s)
+{
+ int i;
+ for (i = 0; i < s->networks; i++)
+ update_quota_per_network (s, &s->network_entries[i], NULL);
+
+}
+
+static void
+addresse_increment (struct GAS_SIMPLISTIC_Handle *s,
+ struct Network *net,
+ int total,
+ int active)
+{
+ if (GNUNET_YES == total)
+ {
+ s->total_addresses ++;
+ net->total_addresses ++;
+ GNUNET_STATISTICS_update (s->stats, "# ATS addresses total", 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (s->stats, net->stat_total, 1, GNUNET_NO);
+ }
+ if (GNUNET_YES == active)
+ {
+ net->active_addresses ++;
+ s->active_addresses ++;
+ GNUNET_STATISTICS_update (s->stats, "# ATS active addresses total", 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (s->stats, net->stat_active, 1, GNUNET_NO);
+ }
+
+}
+
+static int
+addresse_decrement (struct GAS_SIMPLISTIC_Handle *s,
+ struct Network *net,
+ int total,
+ int active)
+{
+ int res = GNUNET_OK;
+ if (GNUNET_YES == total)
+ {
+ if (s->total_addresses < 1)
+ {
+ GNUNET_break (0);
+ res = GNUNET_SYSERR;
+ }
+ else
+ {
+ s->total_addresses --;
+ GNUNET_STATISTICS_update (s->stats, "# ATS addresses total", -1, GNUNET_NO);
+ }
+ if (net->total_addresses < 1)
+ {
+ GNUNET_break (0);
+ res = GNUNET_SYSERR;
+ }
+ else
+ {
+ net->total_addresses --;
+ GNUNET_STATISTICS_update (s->stats, net->stat_total, -1, GNUNET_NO);
+ }
+ }
+
+ if (GNUNET_YES == active)
+ {
+ if (net->active_addresses < 1)
+ {
+ GNUNET_break (0);
+ res = GNUNET_SYSERR;
+ }
+ else
+ {
+ net->active_addresses --;
+ GNUNET_STATISTICS_update (s->stats, net->stat_active, -1, GNUNET_NO);
+ }
+ if (s->active_addresses < 1)
+ {
+ GNUNET_break (0);
+ res = GNUNET_SYSERR;
+ }
+ else
+ {
+ s->active_addresses --;
+ GNUNET_STATISTICS_update (s->stats, "# ATS addresses total", -1, GNUNET_NO);
+ }
+ }
+ return res;
+}
+
+
+/**
+ * Add a single address to the solve
+ *
+ * @param solver the solver Handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the address to add
+ */
+void
+GAS_simplistic_address_add (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address)
+{
+ struct GAS_SIMPLISTIC_Handle *s = solver;
+ struct Network *net = NULL;
+ struct AddressWrapper *aw = NULL;
+
+ GNUNET_assert (NULL != s);
+ int c;
+ for (c = 0; c < s->networks; c++)
+ {
+ net = &s->network_entries[c];
+ if (address->atsp_network_type == net->type)
+ break;
+ }
+ if (NULL == net)
+ {
+ GNUNET_break (0);
+ return;
+ }
+
+ aw = GNUNET_malloc (sizeof (struct AddressWrapper));
+ aw->addr = address;
+ GNUNET_CONTAINER_DLL_insert (net->head, net->tail, aw);
+ addresse_increment (s, net, GNUNET_YES, GNUNET_NO);
+ aw->addr->solver_information = net;
+
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "After adding address now total %u and active %u addresses in network `%s'\n",
+ net->total_addresses,
+ net->active_addresses,
+ net->desc);
+}
+
+/**
+ * Remove an address from the solver
+ *
+ * @param solver the solver handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the address to remove
+ * @param session_only delete only session not whole address
+ */
+void
+GAS_simplistic_address_delete (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap * addresses,
+ struct ATS_Address *address, int session_only)
+{
+ struct GAS_SIMPLISTIC_Handle *s = solver;
+ struct Network *net;
+ struct AddressWrapper *aw;
+
+ /* Remove an adress completely, we have to:
+ * - Remove from specific network
+ * - Decrease number of total addresses
+ * - If active:
+ * - decrease number of active addreses
+ * - update quotas
+ */
+
+ net = (struct Network *) address->solver_information;
+
+ if (GNUNET_NO == session_only)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Deleting %s address %p for peer `%s' from network `%s' (total: %u/ active: %u)\n",
+ (GNUNET_NO == address->active) ? "inactive" : "active",
+ address, GNUNET_i2s (&address->peer),
+ net->desc, net->total_addresses, net->active_addresses);
+
+ /* Remove address */
+ addresse_decrement (s, net, GNUNET_YES, GNUNET_NO);
+ for (aw = net->head; NULL != aw; aw = aw->next)
+ {
+ if (aw->addr == address)
+ break;
+ }
+ if (NULL == aw )
+ {
+ GNUNET_break (0);
+ return;
+ }
+ GNUNET_CONTAINER_DLL_remove (net->head, net->tail, aw);
+ GNUNET_free (aw);
+ }
+ else
+ {
+ /* Remove session only: remove if active and update */
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Deleting %s session %p for peer `%s' from network `%s' (total: %u/ active: %u)\n",
+ (GNUNET_NO == address->active) ? "inactive" : "active",
+ address, GNUNET_i2s (&address->peer),
+ net->desc, net->total_addresses, net->active_addresses);
+ }
+
+ if (GNUNET_YES == address->active)
+ {
+ /* Address was active, remove from network and update quotas*/
+ address->active = GNUNET_NO;
+ if (GNUNET_SYSERR == addresse_decrement (s, net, GNUNET_NO, GNUNET_YES))
+ GNUNET_break (0);
+ update_quota_per_network (s, net, NULL);
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "After deleting address now total %u and active %u addresses in network `%s'\n",
+ net->total_addresses,
+ net->active_addresses,
+ net->desc);
+
+}
+
+static struct Network *
+find_network (struct GAS_SIMPLISTIC_Handle *s, uint32_t type)
+{
+ int c;
+ for (c = 0 ; c < s->networks; c++)
+ {
+ if (s->network_entries[c].type == type)
+ return &s->network_entries[c];
+ }
+ return NULL;
+}
+
+/**
+ * Updates a single address in the solve
+ *
+ * @param solver the solver Handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the update address
+ * @param session the new session (if changed otherwise current)
+ * @param in_use the new address in use state (if changed otherwise current)
+ * @param atsi the latest ATS information
+ * @param atsi_count the atsi count
+ */
+void
+GAS_simplistic_address_update (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap *addresses,
+ struct ATS_Address *address,
+ uint32_t session,
+ int in_use,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count)
+{
+ struct ATS_Address *new;
+ struct GAS_SIMPLISTIC_Handle *s = (struct GAS_SIMPLISTIC_Handle *) solver;
+ int i;
+ uint32_t value;
+ uint32_t type;
+ int save_active = GNUNET_NO;
+ struct Network *new_net = NULL;
+ for (i = 0; i < atsi_count; i++)
+ {
+ type = ntohl (atsi[i].type);
+ value = ntohl (atsi[i].value);
+ switch (type)
+ {
+ case GNUNET_ATS_UTILIZATION_UP:
+ //if (address->atsp_utilization_out.value__ != atsi[i].value)
+
+ break;
+ case GNUNET_ATS_UTILIZATION_DOWN:
+ //if (address->atsp_utilization_in.value__ != atsi[i].value)
+
+ break;
+ case GNUNET_ATS_QUALITY_NET_DELAY:
+ //if (address->atsp_latency.rel_value != value)
+
+ break;
+ case GNUNET_ATS_QUALITY_NET_DISTANCE:
+ //if (address->atsp_distance != value)
+
+ break;
+ case GNUNET_ATS_COST_WAN:
+ //if (address->atsp_cost_wan != value)
+
+ break;
+ case GNUNET_ATS_COST_LAN:
+ //if (address->atsp_cost_lan != value)
+
+ break;
+ case GNUNET_ATS_COST_WLAN:
+ //if (address->atsp_cost_wlan != value)
+
+ break;
+ case GNUNET_ATS_NETWORK_TYPE:
+ if (address->atsp_network_type != value)
+ {
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Network type changed, moving %s address from `%s' to `%s'\n",
+ (GNUNET_YES == address->active) ? "active" : "inactive",
+ GNUNET_ATS_print_network_type(address->atsp_network_type),
+ GNUNET_ATS_print_network_type(value));
+
+ save_active = address->active;
+ /* remove from old network */
+ GAS_simplistic_address_delete (solver, addresses, address, GNUNET_NO);
+
+ /* set new network type */
+ address->atsp_network_type = value;
+ new_net = find_network (solver, value);
+ address->solver_information = new_net;
+ if (address->solver_information == NULL)
+ {
+ GNUNET_break (0);
+ address->atsp_network_type = GNUNET_ATS_NET_UNSPECIFIED;
+ return;
+ }
+
+ /* Add to new network and update*/
+ GAS_simplistic_address_add (solver, addresses, address);
+ if (GNUNET_YES == save_active)
+ {
+ /* check if bandwidth available in new network */
+ if (GNUNET_YES == (bw_available_in_network (new_net)))
+ {
+ /* Suggest updated address */
+ address->active = GNUNET_YES;
+ addresse_increment (s, new_net, GNUNET_NO, GNUNET_YES);
+ update_quota_per_network (solver, new_net, NULL);
+ }
+ else
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Not enough bandwidth in new network, suggesting alternative address ..\n");
+
+ /* Set old address to zero bw */
+ address->assigned_bw_in = GNUNET_BANDWIDTH_value_init (0);
+ address->assigned_bw_out = GNUNET_BANDWIDTH_value_init (0);
+ s->bw_changed (s->bw_changed_cls, address);
+
+ /* Find new address to suggest since no bandwidth in network*/
+ new = (struct ATS_Address *) GAS_simplistic_get_preferred_address (s, addresses, &address->peer);
+ if (NULL != new)
+ {
+ /* Have an alternative address to suggest */
+ s->bw_changed (s->bw_changed_cls, new);
+ }
+
+ }
+ }
+ }
+ break;
+ case GNUNET_ATS_ARRAY_TERMINATOR:
+ break;
+ default:
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Received unsupported ATS type %u\n", type);
+ GNUNET_break (0);
+ break;
+
+ }
+
+ }
+ if (address->session_id != session)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Session changed from %u to %u\n", address->session_id, session);
+ address->session_id = session;
+ }
+ if (address->used != in_use)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Usage changed from %u to %u\n", address->used, in_use);
+ address->used = in_use;
+ }
+
+}
+
+
+
+/**
+ * Find a "good" address to use for a peer. If we already have an existing
+ * address, we stick to it. Otherwise, we pick by lowest distance and then
+ * by lowest latency.
+ *
+ * @param cls the 'struct ATS_Address**' where we store the result
+ * @param key unused
+ * @param value another 'struct ATS_Address*' to consider using
+ * @return GNUNET_OK (continue to iterate)
+ */
+static int
+find_address_it (void *cls, const struct GNUNET_HashCode * key, void *value)
+{
+ struct ATS_Address **previous_p = cls;
+ struct ATS_Address *current = (struct ATS_Address *) value;
+ struct ATS_Address *previous = *previous_p;
+ struct GNUNET_TIME_Absolute now;
+ struct Network *net = (struct Network *) current->solver_information;
+
+ now = GNUNET_TIME_absolute_get();
+
+ if (current->blocked_until.abs_value == GNUNET_TIME_absolute_max (now, current->blocked_until).abs_value)
+ {
+ /* This address is blocked for suggestion */
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Address %p blocked for suggestion for %llu ms \n",
+ current,
+ GNUNET_TIME_absolute_get_difference(now, current->blocked_until).rel_value);
+ return GNUNET_OK;
+ }
+
+ if (GNUNET_NO == bw_available_in_network (net))
+ return GNUNET_OK; /* There's no bandwidth available in this network */
+
+ if (NULL != previous)
+ {
+ if ((0 == strcmp (previous->plugin, "tcp")) &&
+ (0 == strcmp (current->plugin, "tcp")))
+ {
+ if ((0 != previous->addr_len) &&
+ (0 == current->addr_len))
+ {
+ /* saved address was an outbound address, but we have an inbound address */
+ *previous_p = current;
+ return GNUNET_OK;
+ }
+ if (0 == previous->addr_len)
+ {
+ /* saved address was an inbound address, so do not overwrite */
+ return GNUNET_OK;
+ }
+ }
+ }
+
+ if (NULL == previous)
+ {
+ *previous_p = current;
+ return GNUNET_OK;
+ }
+ if ((ntohl (previous->assigned_bw_in.value__) == 0) &&
+ (ntohl (current->assigned_bw_in.value__) > 0))
+ {
+ /* stick to existing connection */
+ *previous_p = current;
+ return GNUNET_OK;
+ }
+ if (previous->atsp_distance > current->atsp_distance)
+ {
+ /* user shorter distance */
+ *previous_p = current;
+ return GNUNET_OK;
+ }
+ if (previous->atsp_latency.rel_value > current->atsp_latency.rel_value)
+ {
+ /* user lower latency */
+ *previous_p = current;
+ return GNUNET_OK;
+ }
+ /* don't care */
+ return GNUNET_OK;
+}
+
+static int
+find_active_address_it (void *cls, const struct GNUNET_HashCode * key, void *value)
+{
+ struct ATS_Address * dest = (struct ATS_Address *) (*(struct ATS_Address **)cls);
+ struct ATS_Address * aa = (struct ATS_Address *) value;
+
+ if (GNUNET_YES == aa->active)
+ {
+ if (dest != NULL)
+ {
+ /* should never happen */
+ LOG (GNUNET_ERROR_TYPE_ERROR, "Multiple active addresses for peer `%s'\n", GNUNET_i2s (&aa->peer));
+ GNUNET_break (0);
+ return GNUNET_NO;
+ }
+ dest = aa;
+ }
+ return GNUNET_OK;
+}
+
+static struct ATS_Address *
+find_active_address (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap * addresses,
+ const struct GNUNET_PeerIdentity *peer)
+{
+ struct ATS_Address * dest = NULL;
+
+ GNUNET_CONTAINER_multihashmap_get_multiple(addresses,
+ &peer->hashPubKey,
+ &find_active_address_it, &dest);
+ return dest;
+}
+
+/**
+ * Get the prefered address for a specific peer
+ *
+ * @param solver the solver handle
+ * @param addresses the address hashmap containing all addresses
+ * @param peer the identity of the peer
+ */
+const struct ATS_Address *
+GAS_simplistic_get_preferred_address (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap * addresses,
+ const struct GNUNET_PeerIdentity *peer)
+{
+ struct GAS_SIMPLISTIC_Handle *s = solver;
+ struct Network *net_prev;
+ struct Network *net_cur;
+ struct ATS_Address *cur;
+ struct ATS_Address *prev;
+
+ GNUNET_assert (s != NULL);
+ cur = NULL;
+ /* Get address with: stick to current address, lower distance, lower latency */
+ GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
+ &find_address_it, &cur);
+ if (NULL == cur)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Cannot suggest address for peer `%s'\n", GNUNET_i2s (peer));
+ return NULL;
+ }
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Suggesting %s address %p for peer `%s'\n",
+ (GNUNET_NO == cur->active) ? "inactive" : "active",
+ cur, GNUNET_i2s (peer));
+ net_cur = (struct Network *) cur->solver_information;
+ if (GNUNET_YES == cur->active)
+ {
+ /* This address was selected previously, so no need to update quotas */
+ return cur;
+ }
+
+ /* This address was not active, so we have to:
+ *
+ * - mark previous active address as not active
+ * - update quota for previous address network
+ * - update quota for this address network
+ */
+
+ prev = find_active_address (s, addresses, peer);
+ if (NULL != prev)
+ {
+ net_prev = (struct Network *) prev->solver_information;
+ prev->active = GNUNET_NO; /* No active any longer */
+ prev->assigned_bw_in = GNUNET_BANDWIDTH_value_init (0); /* no bw assigned */
+ prev->assigned_bw_out = GNUNET_BANDWIDTH_value_init (0); /* no bw assigned */
+ s->bw_changed (s->bw_changed_cls, prev); /* notify about bw change, REQUIRED? */
+ if (GNUNET_SYSERR == addresse_decrement (s, net_prev, GNUNET_NO, GNUNET_YES))
+ GNUNET_break (0);
+ update_quota_per_network (s, net_prev, NULL);
+ }
+
+ if (GNUNET_NO == (bw_available_in_network (cur->solver_information)))
+ {
+ GNUNET_break (0); /* This should never happen*/
+ return NULL;
+ }
+
+ cur->active = GNUNET_YES;
+ addresse_increment(s, net_cur, GNUNET_NO, GNUNET_YES);
+ update_quota_per_network (s, net_cur, cur);
+
+ return cur;
+}
+
+static void
+recalculate_preferences (struct PreferencePeer *p)
+{
+ struct GAS_SIMPLISTIC_Handle *s = p->s;
+ struct PreferencePeer *p_cur;
+ struct PreferenceClient *c_cur = p->client;
+ double p_rel_global;
+ double *dest;
+ int kind;
+ int rkind;
+ int clients;
+
+ /**
+ * Idea:
+ *
+ * We have:
+ * Set of clients c
+ * Set of peers p_i in P
+ * Set of preference kinds k
+ * A preference value f_k_p_i with an unknown range
+ *
+ * We get:
+ * A client specific relative preference f_p_i_rel [1..2] for all peers
+ *
+ * For every client c
+ * {
+ * For every preference kind k:
+ * {
+ * We remember for the preference f_p_i for each peer p_i.
+ * We have a default preference value f_p_i = 0
+ * We have a sum of all preferences f_t = sum (f_p_i)
+ * So we can calculate a relative preference value fr_p_i:
+ *
+ * f_k_p_i_rel = (f_t + f_p_i) / f_t
+ * f_k_p_i_rel = [1..2], default 1.0
+ * }
+ * f_p_i_rel = sum (f_k_p_i_rel) / #k
+ * }
+ *
+ **/
+
+ /* For this client: for all preferences, except TERMINATOR */
+ for (kind = GNUNET_ATS_PREFERENCE_END + 1 ; kind < GNUNET_ATS_PreferenceCount; kind ++)
+ {
+ /* Recalcalculate total preference for this quality kind over all peers*/
+ c_cur->f_total[kind] = 0;
+ for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
+ c_cur->f_total[kind] += p_cur->f[kind];
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Client %p has total preference for %s of %.3f\n",
+ c_cur->client,
+ GNUNET_ATS_print_preference_type (kind),
+ c_cur->f_total[kind]);
+
+ /* Recalcalculate relative preference for all peers */
+ for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
+ {
+ /* Calculate relative preference for specific kind */
+ if (0.0 == c_cur->f_total[kind])
+ {
+ /* No one has preference, so set default preference */
+ p_cur->f_rel[kind] = DEFAULT_PREFERENCE;
+ }
+ else
+ {
+ p_cur->f_rel[kind] = (c_cur->f_total[kind] + p_cur->f[kind]) / c_cur->f_total[kind];
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Client %p: peer `%s' has relative preference for %s of %.3f\n",
+ c_cur->client,
+ GNUNET_i2s (&p_cur->id),
+ GNUNET_ATS_print_preference_type (kind),
+ p_cur->f_rel[kind]);
+
+ /* Calculate peer relative preference */
+ /* Start with kind = 1 to exclude terminator */
+ p_cur->f_rel_total = 0;
+ for (rkind = GNUNET_ATS_PREFERENCE_END + 1; rkind < GNUNET_ATS_PreferenceCount; rkind ++)
+ {
+ p_cur->f_rel_total += p_cur->f_rel[rkind];
+ }
+ p_cur->f_rel_total /= (GNUNET_ATS_PreferenceCount - 1.0); /* -1 due to terminator */
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Client %p: peer `%s' has total relative preference of %.3f\n",
+ c_cur->client,
+ GNUNET_i2s (&p_cur->id),
+ p_cur->f_rel_total);
+ }
+ }
+
+ /* Calculcate global total relative peer preference over all clients */
+ p_rel_global = 0.0;
+ clients = 0;
+ for (c_cur = s->pc_head; NULL != c_cur; c_cur = c_cur->next)
+ {
+ for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
+ if (0 == memcmp (&p_cur->id, &p->id, sizeof (p_cur->id)))
+ break;
+ if (NULL != p_cur)
+ {
+ clients++;
+ p_rel_global += p_cur->f_rel_total;
+ }
+ }
+ p_rel_global /= clients;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Global preference value for peer `%s': %.3f\n",
+ GNUNET_i2s (&p->id), p_rel_global);
+
+ /* Update global map */
+ if (NULL != (dest = GNUNET_CONTAINER_multihashmap_get(s->prefs, &p->id.hashPubKey)))
+ (*dest) = p_rel_global;
+ else
+ {
+ dest = GNUNET_malloc (sizeof (double));
+ (*dest) = p_rel_global;
+ GNUNET_CONTAINER_multihashmap_put(s->prefs,
+ &p->id.hashPubKey,
+ dest,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ }
+}
+
+static void
+update_preference (struct PreferencePeer *p,
+ enum GNUNET_ATS_PreferenceKind kind,
+ float score_f)
+{
+ double score = score_f;
+
+ /* Update preference value according to type */
+ switch (kind) {
+ case GNUNET_ATS_PREFERENCE_BANDWIDTH:
+ case GNUNET_ATS_PREFERENCE_LATENCY:
+ p->f[kind] = (p->f[kind] + score) / 2;
+ break;
+ case GNUNET_ATS_PREFERENCE_END:
+ break;
+ default:
+ break;
+ }
+ recalculate_preferences(p);
+ update_all_networks (p->s);
+}
+
+
+static void
+preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ int i;
+ double *t = NULL;
+ double backup;
+ struct PreferencePeer *p = cls;
+ GNUNET_assert (NULL != p);
+
+
+ p->aging_task = GNUNET_SCHEDULER_NO_TASK;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Aging preferences for peer `%s'\n",
+ GNUNET_i2s (&p->id));
+
+ /* Issue for aging :
+ *
+ * Not for every peer preference values are set by default, so reducing the
+ * absolute preference value does not help for aging because it does not have
+ * influence on the relative values.
+ *
+ * So we have to reduce the relative value to have an immediate impact on
+ * quota calculation. In addition we cannot call recalculate_preferences here
+ * but instead reduce the absolute value to have an aging impact on future
+ * calls to change_preference where recalculate_preferences is called
+ *
+ */
+ /* Aging absolute values: */
+ for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
+ {
+ if (p->f[i] > 1.0)
+ {
+ backup = p->f[i];
+ p->f[i] *= PREF_AGING_FACTOR;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Aged preference for peer `%s' from %.3f to %.3f\n",
+ GNUNET_i2s (&p->id), backup, p->f[i]);
+ }
+ }
+ /* Updating relative value */
+ t = GNUNET_CONTAINER_multihashmap_get (p->s->prefs, &p->id.hashPubKey);
+ if (NULL == t)
+ {
+ GNUNET_break (0);
+ }
+ else
+ {
+ if ((*t) > 1.0)
+ (*t) = (*t) * PREF_AGING_FACTOR;
+ else
+ (*t) = 1.0;
+ update_all_networks (p->s);
+ }
+ p->aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL,
+ &preference_aging, p);
+}
+
+
+/**
+ * Changes the preferences for a peer in the problem
+ *
+ * @param solver the solver handle
+ * @param client the client with this preference
+ * @param peer the peer to change the preference for
+ * @param kind the kind to change the preference
+ * @param score the score
+ */
+void
+GAS_simplistic_address_change_preference (void *solver,
+ void *client,
+ const struct GNUNET_PeerIdentity *peer,
+ enum GNUNET_ATS_PreferenceKind kind,
+ float score_f)
+{
+ static struct GNUNET_TIME_Absolute next_update;
+ struct GAS_SIMPLISTIC_Handle *s = solver;
+ struct PreferenceClient *c_cur;
+ struct PreferencePeer *p_cur;
+ int i;
+
+ GNUNET_assert (NULL != solver);
+ GNUNET_assert (NULL != client);
+ GNUNET_assert (NULL != peer);
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Client %p changes preference for peer `%s' %s %f\n",
+ client,
+ GNUNET_i2s (peer),
+ GNUNET_ATS_print_preference_type (kind),
+ score_f);
+
+ if (kind >= GNUNET_ATS_PreferenceCount)
+ {
+ GNUNET_break (0);
+ return;
+ }
+
+ /* Find preference client */
+ for (c_cur = s->pc_head; NULL != c_cur; c_cur = c_cur->next)
+ {
+ if (client == c_cur->client)
+ break;
+ }
+ /* Not found: create new preference client */
+ if (NULL == c_cur)
+ {
+ c_cur = GNUNET_malloc (sizeof (struct PreferenceClient));
+ c_cur->client = client;
+ GNUNET_CONTAINER_DLL_insert (s->pc_head, s->pc_tail, c_cur);
+ }
+
+ /* Find entry for peer */
+ for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
+ if (0 == memcmp (&p_cur->id, peer, sizeof (p_cur->id)))
+ break;
+
+ /* Not found: create new peer entry */
+ if (NULL == p_cur)
+ {
+ p_cur = GNUNET_malloc (sizeof (struct PreferencePeer));
+ p_cur->s = s;
+ p_cur->client = c_cur;
+ p_cur->id = (*peer);
+ for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
+ {
+ /* Default value per peer absolut preference for a quality:
+ * No value set, so absolute preference 0 */
+ p_cur->f[i] = 0.0;
+ /* Default value per peer relative preference for a quality: 1.0 */
+ p_cur->f_rel[i] = DEFAULT_PREFERENCE;
+ }
+ p_cur->aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL, &preference_aging, p_cur);
+ GNUNET_CONTAINER_DLL_insert (c_cur->p_head, c_cur->p_tail, p_cur);
+ }
+
+ update_preference (p_cur, kind, score_f);
+
+ /* FIXME: We should update quotas if UPDATE_INTERVAL is reached */
+ if (GNUNET_TIME_absolute_get().abs_value > next_update.abs_value)
+ {
+ /* update quotas*/
+ next_update = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(),
+ MIN_UPDATE_INTERVAL);
+ }
+}
+
+/* end of gnunet-service-ats_addresses_simplistic.c */
diff --git a/src/ats/gnunet-service-ats_addresses_simplistic.h b/src/ats/gnunet-service-ats_addresses_simplistic.h
new file mode 100644
index 0000000..eab221c
--- /dev/null
+++ b/src/ats/gnunet-service-ats_addresses_simplistic.h
@@ -0,0 +1,151 @@
+/*
+ This file is part of GNUnet.
+ (C) 2011 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file ats/gnunet-service-ats_addresses_simplistic.h
+ * @brief ats simplistic ressource assignment
+ * @author Matthias Wachs
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet-service-ats_addresses.h"
+
+#define BIG_M_STRING "unlimited"
+
+/**
+ * Init the simplistic problem solving component
+ *
+ * Quotas:
+ * network[i] contains the network type as type GNUNET_ATS_NetworkType[i]
+ * out_quota[i] contains outbound quota for network type i
+ * in_quota[i] contains inbound quota for network type i
+ *
+ * Example
+ * network = {GNUNET_ATS_NET_UNSPECIFIED, GNUNET_ATS_NET_LOOPBACK, GNUNET_ATS_NET_LAN, GNUNET_ATS_NET_WAN, GNUNET_ATS_NET_WLAN}
+ * network[2] == GNUNET_ATS_NET_LAN
+ * out_quota[2] == 65353
+ * in_quota[2] == 65353
+ *
+ * @param cfg configuration handle
+ * @param stats the GNUNET_STATISTICS handle
+ * @param network array of GNUNET_ATS_NetworkType with length dest_length
+ * @param out_quota array of outbound quotas
+ * @param in_quota array of outbound quota
+ * @param dest_length array length for quota arrays
+ * @param bw_changed_cb callback for changed bandwidth amounts
+ * @param bw_changed_cb_cls cls for callback
+ * @return handle for the solver on success, NULL on fail
+ */
+void *
+GAS_simplistic_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const struct GNUNET_STATISTICS_Handle *stats,
+ int *network,
+ unsigned long long *out_quota,
+ unsigned long long *in_quota,
+ int dest_length,
+ GAS_bandwidth_changed_cb bw_changed_cb,
+ void *bw_changed_cb_cls);
+
+/**
+ * Shutdown the simplistic problem solving component
+ *
+ * @param solver the respective handle to shutdown
+ */
+void
+GAS_simplistic_done (void * solver);
+
+/**
+ * Add a single address to the solve
+ *
+ * @param solver the solver Handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the address to add
+ */
+void
+GAS_simplistic_address_add (void *solver, struct GNUNET_CONTAINER_MultiHashMap * addresses, struct ATS_Address *address);
+
+
+/**
+ * Updates a single address in the solve
+ *
+ * @param solver the solver Handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the update address
+ * @param session the new session (if changed otherwise current)
+ * @param in_use the new address in use state (if changed otherwise current)
+ * @param atsi the latest ATS information
+ * @param atsi_count the atsi count
+ */
+void
+GAS_simplistic_address_update (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap *addresses,
+ struct ATS_Address *address,
+ uint32_t session,
+ int in_use,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count);
+
+
+/**
+ * Remove an address from the solver
+ *
+ * @param solver the solver handle
+ * @param addresses the address hashmap containing all addresses
+ * @param address the address to remove
+ * @param session_only delete only session not whole address
+ */
+void
+GAS_simplistic_address_delete (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap * addresses,
+ struct ATS_Address *address, int session_only);
+
+
+/**
+ * Get the prefered address for a specific peer
+ *
+ * @param solver the solver handle
+ * @param addresses the address hashmap containing all addresses
+ * @param peer the identity of the peer
+ */
+const struct ATS_Address *
+GAS_simplistic_get_preferred_address (void *solver,
+ struct GNUNET_CONTAINER_MultiHashMap * addresses,
+ const struct GNUNET_PeerIdentity *peer);
+
+
+/**
+ * Changes the preferences for a peer in the problem
+ *
+ * @param solver the solver handle
+ * @param client the client with this preference
+ * @param peer the peer to change the preference for
+ * @param kind the kind to change the preference
+ * @param score the score
+ */
+void
+GAS_simplistic_address_change_preference (void *solver,
+ void *client,
+ const struct GNUNET_PeerIdentity *peer,
+ enum GNUNET_ATS_PreferenceKind kind,
+ float score);
+
+
+/* end of gnunet-service-ats_addresses_simplistic.h */
diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c
index 7ab8e9a..35f0223 100644
--- a/src/ats/gnunet-service-ats_performance.c
+++ b/src/ats/gnunet-service-ats_performance.c
@@ -61,6 +61,28 @@ struct PerformanceClient
/**
+ * We keep clients that are interested in performance in a linked list.
+ */
+struct AddressIteration
+{
+ /**
+ * Actual handle to the client.
+ */
+ struct PerformanceClient *pc;
+
+ int all;
+
+ uint32_t id;
+
+ unsigned int msg_type;
+};
+
+/**
+ * Address handle
+ */
+static struct GAS_Addresses_Handle *GSA_addresses;
+
+/**
* Head of linked list of all clients to this service.
*/
static struct PerformanceClient *pc_head;
@@ -93,29 +115,6 @@ find_client (struct GNUNET_SERVER_Client *client)
return NULL;
}
-
-/**
- * Register a new performance client.
- *
- * @param client handle of the new client
- * @param flag flag specifying the type of the client
- */
-void
-GAS_performance_add_client (struct GNUNET_SERVER_Client *client,
- enum StartFlag flag)
-{
- struct PerformanceClient *pc;
-
- GNUNET_break (NULL == find_client (client));
- pc = GNUNET_malloc (sizeof (struct PerformanceClient));
- pc->client = client;
- pc->flag = flag;
- GNUNET_SERVER_notification_context_add (nc, client);
- GNUNET_SERVER_client_keep (client);
- GNUNET_CONTAINER_DLL_insert (pc_head, pc_tail, pc);
-}
-
-
/**
* Unregister a client (which may have been a performance client,
* but this is not assured).
@@ -126,7 +125,6 @@ void
GAS_performance_remove_client (struct GNUNET_SERVER_Client *client)
{
struct PerformanceClient *pc;
-
pc = find_client (client);
if (NULL == pc)
return;
@@ -135,31 +133,34 @@ GAS_performance_remove_client (struct GNUNET_SERVER_Client *client)
GNUNET_free (pc);
}
-
/**
* Transmit the given performance information to all performance
* clients.
*
+ * @param pc performance client to send to
* @param peer peer for which this is an address suggestion
* @param plugin_name 0-termintated string specifying the transport plugin
* @param plugin_addr binary address for the plugin to use
* @param plugin_addr_len number of bytes in plugin_addr
+ * @param active is this address active
* @param atsi performance data for the address
* @param atsi_count number of performance records in 'ats'
* @param bandwidth_out assigned outbound bandwidth
* @param bandwidth_in assigned inbound bandwidth
*/
void
-GAS_performance_notify_clients (const struct GNUNET_PeerIdentity *peer,
- const char *plugin_name,
- const void *plugin_addr, size_t plugin_addr_len,
- const struct GNUNET_ATS_Information *atsi,
- uint32_t atsi_count,
- struct GNUNET_BANDWIDTH_Value32NBO
- bandwidth_out,
- struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
+GAS_performance_notify_client (struct PerformanceClient *pc,
+ const struct GNUNET_PeerIdentity *peer,
+ const char *plugin_name,
+ const void *plugin_addr, size_t plugin_addr_len,
+ const int active,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count,
+ struct GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
{
- struct PerformanceClient *pc;
+
struct PeerInformationMessage *msg;
size_t plugin_name_length = strlen (plugin_name) + 1;
size_t msize =
@@ -170,6 +171,10 @@ GAS_performance_notify_clients (const struct GNUNET_PeerIdentity *peer,
struct GNUNET_ATS_Information *atsp;
char *addrp;
+ GNUNET_assert (NULL != pc);
+ if (NULL == find_client (pc->client))
+ return; /* Client disconnected */
+
GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
GNUNET_assert (atsi_count <
GNUNET_SERVER_MAX_MESSAGE_SIZE /
@@ -177,9 +182,11 @@ GAS_performance_notify_clients (const struct GNUNET_PeerIdentity *peer,
msg = (struct PeerInformationMessage *) buf;
msg->header.size = htons (msize);
msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_PEER_INFORMATION);
+ msg->id = htonl (0);
msg->ats_count = htonl (atsi_count);
msg->peer = *peer;
msg->address_length = htons (plugin_addr_len);
+ msg->address_active = ntohl (active);
msg->plugin_name_length = htons (plugin_name_length);
msg->bandwidth_out = bandwidth_out;
msg->bandwidth_in = bandwidth_in;
@@ -188,18 +195,314 @@ GAS_performance_notify_clients (const struct GNUNET_PeerIdentity *peer,
addrp = (char *) &atsp[atsi_count];
memcpy (addrp, plugin_addr, plugin_addr_len);
strcpy (&addrp[plugin_addr_len], plugin_name);
+ GNUNET_SERVER_notification_context_unicast (nc, pc->client, &msg->header,
+ GNUNET_YES);
+}
+
+
+/**
+ * Transmit the given performance information to all performance
+ * clients.
+ *
+ * @param peer peer for which this is an address suggestion
+ * @param plugin_name 0-termintated string specifying the transport plugin
+ * @param plugin_addr binary address for the plugin to use
+ * @param plugin_addr_len number of bytes in plugin_addr
+ * @param active is this address active
+ * @param atsi performance data for the address
+ * @param atsi_count number of performance records in 'ats'
+ * @param bandwidth_out assigned outbound bandwidth
+ * @param bandwidth_in assigned inbound bandwidth
+ */
+void
+GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer,
+ const char *plugin_name,
+ const void *plugin_addr, size_t plugin_addr_len,
+ const int active,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count,
+ struct GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
+{
+ struct PerformanceClient *pc;
+
for (pc = pc_head; pc != NULL; pc = pc->next)
if (pc->flag == START_FLAG_PERFORMANCE_WITH_PIC)
{
- GNUNET_SERVER_notification_context_unicast (nc, pc->client, &msg->header,
- GNUNET_YES);
- GNUNET_STATISTICS_update (GSA_stats,
- "# performance updates given to clients", 1,
- GNUNET_NO);
+ GAS_performance_notify_client (pc,
+ peer,
+ plugin_name, plugin_addr, plugin_addr_len,
+ active,
+ atsi, atsi_count,
+ bandwidth_out, bandwidth_in);
}
+ GNUNET_STATISTICS_update (GSA_stats,
+ "# performance updates given to clients", 1,
+ GNUNET_NO);
}
+static void
+peerinfo_it (void *cls,
+ const struct GNUNET_PeerIdentity *id,
+ const char *plugin_name,
+ const void *plugin_addr, size_t plugin_addr_len,
+ const int active,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count,
+ struct GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
+{
+ struct PerformanceClient *pc = cls;
+ GNUNET_assert (NULL != pc);
+ if (NULL == id)
+ return;
+
+ if (GNUNET_NO == active)
+ return;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Callback for peer `%s' plugin `%s' BW out %llu, BW in %llu \n",
+ GNUNET_i2s (id),
+ plugin_name,
+ ntohl (bandwidth_out.value__),
+ ntohl (bandwidth_in.value__));
+ GAS_performance_notify_client(pc,
+ id,
+ plugin_name, plugin_addr, plugin_addr_len,
+ active,
+ atsi, atsi_count,
+ bandwidth_out, bandwidth_in);
+}
+
+
+/**
+ * Iterator for GAS_performance_add_client
+ *
+ * @param cls the client requesting information
+ * @param id result
+ */
+static void
+peer_it (void *cls,
+ const struct GNUNET_PeerIdentity *id)
+{
+ struct PerformanceClient *pc = cls;
+ if (NULL != id)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for peer `%s'\n", GNUNET_i2s (id));
+ GAS_addresses_get_peer_info (GSA_addresses, id, &peerinfo_it, pc);
+ }
+}
+
+/**
+ * Register a new performance client.
+ *
+ * @param client handle of the new client
+ * @param flag flag specifying the type of the client
+ */
+void
+GAS_performance_add_client (struct GNUNET_SERVER_Client *client,
+ enum StartFlag flag)
+{
+ struct PerformanceClient *pc;
+ GNUNET_break (NULL == find_client (client));
+
+ pc = GNUNET_malloc (sizeof (struct PerformanceClient));
+ pc->client = client;
+ pc->flag = flag;
+ GNUNET_SERVER_notification_context_add (nc, client);
+ GNUNET_SERVER_client_keep (client);
+ GNUNET_CONTAINER_DLL_insert (pc_head, pc_tail, pc);
+
+ /* Send information about clients */
+ GAS_addresses_iterate_peers (GSA_addresses, &peer_it, pc);
+}
+
+static void transmit_req_addr (struct AddressIteration *ai,
+ const struct GNUNET_PeerIdentity *id,
+ const char *plugin_name,
+ const void *plugin_addr, size_t plugin_addr_len,
+ const int active,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count,
+ struct GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
+
+{
+
+ struct GNUNET_ATS_Information *atsp;
+ struct PeerInformationMessage *msg;
+ char *addrp;
+ size_t plugin_name_length;
+ size_t msize;
+
+ if (NULL != plugin_name)
+ plugin_name_length = strlen (plugin_name) + 1;
+ else
+ plugin_name_length = 0;
+ msize = sizeof (struct PeerInformationMessage) +
+ atsi_count * sizeof (struct GNUNET_ATS_Information) +
+ plugin_addr_len + plugin_name_length;
+ char buf[msize] GNUNET_ALIGN;
+
+ GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE);
+ GNUNET_assert (atsi_count <
+ GNUNET_SERVER_MAX_MESSAGE_SIZE /
+ sizeof (struct GNUNET_ATS_Information));
+ msg = (struct PeerInformationMessage *) buf;
+ msg->header.size = htons (msize);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_RESPONSE);
+ msg->ats_count = htonl (atsi_count);
+ msg->id = htonl (ai->id);
+ if (NULL != id)
+ msg->peer = *id;
+ else
+ memset (&msg->peer, '\0', sizeof (struct GNUNET_PeerIdentity));
+ msg->address_length = htons (plugin_addr_len);
+ msg->address_active = ntohl (active);
+ msg->plugin_name_length = htons (plugin_name_length);
+ msg->bandwidth_out = bandwidth_out;
+ msg->bandwidth_in = bandwidth_in;
+ atsp = (struct GNUNET_ATS_Information *) &msg[1];
+ memcpy (atsp, atsi, sizeof (struct GNUNET_ATS_Information) * atsi_count);
+ addrp = (char *) &atsp[atsi_count];
+ if (NULL != plugin_addr)
+ memcpy (addrp, plugin_addr, plugin_addr_len);
+ if (NULL != plugin_name)
+ strcpy (&addrp[plugin_addr_len], plugin_name);
+ GNUNET_SERVER_notification_context_unicast (nc, ai->pc->client, &msg->header,
+ GNUNET_NO);
+}
+
+static void
+req_addr_peerinfo_it (void *cls,
+ const struct GNUNET_PeerIdentity *id,
+ const char *plugin_name,
+ const void *plugin_addr, size_t plugin_addr_len,
+ const int active,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t atsi_count,
+ struct GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
+{
+ struct AddressIteration *ai = cls;
+
+ GNUNET_assert (NULL != ai);
+ GNUNET_assert (NULL != ai->pc);
+ if (NULL == find_client (ai->pc->client))
+ return; /* Client disconnected */
+
+ if ((NULL == id) && (NULL == plugin_name) && (NULL == plugin_addr))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Address iteration done\n");
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Callback for %s peer `%s' plugin `%s' BW out %u, BW in %u \n",
+ (active == GNUNET_YES) ? "ACTIVE" : "INACTIVE",
+ GNUNET_i2s (id),
+ plugin_name,
+ (unsigned int) ntohl (bandwidth_out.value__),
+ (unsigned int) ntohl (bandwidth_in.value__));
+
+ /* Transmit result */
+ if ((GNUNET_YES == ai->all) || (GNUNET_YES == active))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending result for %s peer `%s' plugin `%s' BW out %u, BW in %u \n",
+ (active == GNUNET_YES) ? "ACTIVE" : "INACTIVE",
+ GNUNET_i2s (id),
+ plugin_name,
+ (unsigned int) ntohl (bandwidth_out.value__),
+ (unsigned int) ntohl (bandwidth_in.value__));
+ transmit_req_addr (cls,
+ id,
+ plugin_name,
+ plugin_addr, plugin_addr_len,
+ active,
+ atsi,
+ atsi_count,
+ bandwidth_out, bandwidth_in);
+ }
+}
+
+
+/**
+ * Iterator for GAS_handle_request_address_list
+ *
+ * @param cls the client requesting information
+ * @param id result
+ */
+static void
+req_addr_peer_it (void *cls,
+ const struct GNUNET_PeerIdentity *id)
+{
+ struct AddressIteration *ai = cls;
+ if (NULL != id)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for peer `%s'\n", GNUNET_i2s (id));
+ GAS_addresses_get_peer_info (GSA_addresses, id, &req_addr_peerinfo_it, ai);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer iteration done\n");
+ }
+}
+
+/**
+ * Handle 'address list request' messages from clients.
+ *
+ * @param cls unused, NULL
+ * @param client client that sent the request
+ * @param message the request message
+ */
+void
+GAS_handle_request_address_list (void *cls, struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ struct PerformanceClient *pc;
+ struct AddressIteration ai;
+ struct AddressListRequestMessage * alrm = (struct AddressListRequestMessage *) message;
+ struct GNUNET_PeerIdentity allzeros;
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_zero;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n",
+ "ADDRESSLIST_REQUEST");
+
+ if (NULL == (pc = find_client(client)))
+ {
+ GNUNET_break (0);
+ return;
+ }
+
+ ai.all = ntohl (alrm->all);
+ ai.id = ntohl (alrm->id);
+ ai.pc = pc;
+
+ memset (&allzeros, '\0', sizeof (struct GNUNET_PeerIdentity));
+ bandwidth_zero.value__ = htonl (0);
+ if (0 == memcmp (&alrm->peer, &allzeros, sizeof (struct GNUNET_PeerIdentity)))
+ {
+ /* Return addresses for all peers */
+ GAS_addresses_iterate_peers (GSA_addresses, &req_addr_peer_it, &ai);
+ transmit_req_addr (&ai, NULL, NULL, NULL, 0, GNUNET_NO, NULL, 0, bandwidth_zero, bandwidth_zero);
+ }
+ else
+ {
+ /* Return addresses for a specific peer */
+ GAS_addresses_get_peer_info (GSA_addresses, &alrm->peer, &req_addr_peerinfo_it, &ai);
+ transmit_req_addr (&ai, NULL, NULL, NULL, 0, GNUNET_NO, NULL, 0, bandwidth_zero, bandwidth_zero);
+ }
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+
+
/**
* Handle 'reservation request' messages from clients.
*
@@ -251,7 +554,8 @@ GAS_handle_reservation_request (void *cls, struct GNUNET_SERVER_Client *client,
* @param message the request message
*/
void
-GAS_handle_preference_change (void *cls, struct GNUNET_SERVER_Client *client,
+GAS_handle_preference_change (void *cls,
+ struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
const struct ChangePreferenceMessage *msg;
@@ -283,7 +587,9 @@ GAS_handle_preference_change (void *cls, struct GNUNET_SERVER_Client *client,
1, GNUNET_NO);
pi = (const struct PreferenceInformation *) &msg[1];
for (i = 0; i < nump; i++)
- GAS_addresses_change_preference (&msg->peer,
+ GAS_addresses_change_preference (GSA_addresses,
+ client,
+ &msg->peer,
(enum GNUNET_ATS_PreferenceKind)
ntohl (pi[i].preference_kind),
pi[i].preference_value);
@@ -295,10 +601,13 @@ GAS_handle_preference_change (void *cls, struct GNUNET_SERVER_Client *client,
* Initialize performance subsystem.
*
* @param server handle to our server
+ * @param addresses the address handle to use
*/
void
-GAS_performance_init (struct GNUNET_SERVER_Handle *server)
+GAS_performance_init (struct GNUNET_SERVER_Handle *server,
+ struct GAS_Addresses_Handle *addresses)
{
+ GSA_addresses = addresses;
nc = GNUNET_SERVER_notification_context_create (server, 128);
}
diff --git a/src/ats/gnunet-service-ats_performance.h b/src/ats/gnunet-service-ats_performance.h
index 75d555a..6d527ae 100644
--- a/src/ats/gnunet-service-ats_performance.h
+++ b/src/ats/gnunet-service-ats_performance.h
@@ -60,15 +60,17 @@ GAS_performance_remove_client (struct GNUNET_SERVER_Client *client);
* @param plugin_name 0-termintated string specifying the transport plugin
* @param plugin_addr binary address for the plugin to use
* @param plugin_addr_len number of bytes in plugin_addr
+ * @param active is this address active
* @param atsi performance data for the address
* @param atsi_count number of performance records in 'ats'
* @param bandwidth_out assigned outbound bandwidth
* @param bandwidth_in assigned inbound bandwidth
*/
void
-GAS_performance_notify_clients (const struct GNUNET_PeerIdentity *peer,
+GAS_performance_notify_all_clients (const struct GNUNET_PeerIdentity *peer,
const char *plugin_name,
const void *plugin_addr, size_t plugin_addr_len,
+ const int active,
const struct GNUNET_ATS_Information *atsi,
uint32_t atsi_count,
struct GNUNET_BANDWIDTH_Value32NBO
@@ -78,6 +80,18 @@ GAS_performance_notify_clients (const struct GNUNET_PeerIdentity *peer,
/**
+ * Handle 'address list request' messages from clients.
+ *
+ * @param cls unused, NULL
+ * @param client client that sent the request
+ * @param message the request message
+ */
+void
+GAS_handle_request_address_list (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message);
+
+/**
* Handle 'reservation request' messages from clients.
*
* @param cls unused, NULL
@@ -85,7 +99,8 @@ GAS_performance_notify_clients (const struct GNUNET_PeerIdentity *peer,
* @param message the request message
*/
void
-GAS_handle_reservation_request (void *cls, struct GNUNET_SERVER_Client *client,
+GAS_handle_reservation_request (void *cls,
+ struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message);
@@ -97,7 +112,8 @@ GAS_handle_reservation_request (void *cls, struct GNUNET_SERVER_Client *client,
* @param message the request message
*/
void
-GAS_handle_preference_change (void *cls, struct GNUNET_SERVER_Client *client,
+GAS_handle_preference_change (void *cls,
+ struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message);
@@ -105,9 +121,11 @@ GAS_handle_preference_change (void *cls, struct GNUNET_SERVER_Client *client,
* Initialize performance subsystem.
*
* @param server handle to our server
+ * @param addresses the address handle to use
*/
void
-GAS_performance_init (struct GNUNET_SERVER_Handle *server);
+GAS_performance_init (struct GNUNET_SERVER_Handle *server,
+ struct GAS_Addresses_Handle *GSA_addresses);
/**
diff --git a/src/ats/gnunet-service-ats_reservations.c b/src/ats/gnunet-service-ats_reservations.c
index d1212dd..3354c4e 100644
--- a/src/ats/gnunet-service-ats_reservations.c
+++ b/src/ats/gnunet-service-ats_reservations.c
@@ -122,7 +122,7 @@ GAS_reservations_set_bandwidth (const struct GNUNET_PeerIdentity *peer,
void
GAS_reservations_init ()
{
- trackers = GNUNET_CONTAINER_multihashmap_create (128);
+ trackers = GNUNET_CONTAINER_multihashmap_create (128, GNUNET_NO);
}
@@ -135,7 +135,7 @@ GAS_reservations_init ()
* @return GNUNET_OK (continue to iterate)
*/
static int
-free_tracker (void *cls, const GNUNET_HashCode * key, void *value)
+free_tracker (void *cls, const struct GNUNET_HashCode * key, void *value)
{
struct GNUNET_BANDWIDTH_Tracker *tracker = value;
diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c
index 0b66ac5..4a20f90 100644
--- a/src/ats/gnunet-service-ats_scheduling.c
+++ b/src/ats/gnunet-service-ats_scheduling.c
@@ -43,6 +43,11 @@ static struct GNUNET_SERVER_Client *my_client;
/**
+ * Handle to address subsystem
+ */
+static struct GAS_Addresses_Handle *address_handle;
+
+/**
* Register a new scheduling client.
*
* @param client handle of the new client
@@ -74,7 +79,7 @@ GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client)
{
if (my_client != client)
return;
- GAS_addresses_destroy_all ();
+ GAS_addresses_destroy_all (address_handle);
my_client = NULL;
}
@@ -166,10 +171,8 @@ GAS_handle_request_address (void *cls, struct GNUNET_SERVER_Client *client,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n",
"REQUEST_ADDRESS");
- GNUNET_STATISTICS_update (GSA_stats, "# address requests received", 1,
- GNUNET_NO);
GNUNET_break (0 == ntohl (msg->reserved));
- GAS_addresses_request_address (&msg->peer);
+ GAS_addresses_request_address (address_handle, &msg->peer);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -193,7 +196,7 @@ GAS_handle_request_address_cancel (void *cls,
"REQUEST_ADDRESS_CANCEL");
GNUNET_break (0 == ntohl (msg->reserved));
- /* TODO */
+ GAS_addresses_request_address_cancel (address_handle, &msg->peer);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -215,10 +218,66 @@ GAS_handle_reset_backoff (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n",
"RESET_BACKOFF");
- GNUNET_STATISTICS_update (GSA_stats, "# backoff reset requests received", 1,
- GNUNET_NO);
GNUNET_break (0 == ntohl (msg->reserved));
- GAS_addresses_handle_backoff_reset (&msg->peer);
+ GAS_addresses_handle_backoff_reset (address_handle, &msg->peer);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+/**
+ * Handle 'address add' messages from clients.
+ *
+ * @param cls unused, NULL
+ * @param client client that sent the request
+ * @param message the request message
+ */
+void
+GAS_handle_address_add (void *cls, struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct AddressUpdateMessage *m;
+ const struct GNUNET_ATS_Information *atsi;
+ const char *address;
+ const char *plugin_name;
+ uint16_t address_length;
+ uint16_t plugin_name_length;
+ uint32_t ats_count;
+ uint16_t size;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n",
+ "ADDRESS_ADD");
+ size = ntohs (message->size);
+ if (size < sizeof (struct AddressUpdateMessage))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ m = (const struct AddressUpdateMessage *) message;
+ ats_count = ntohl (m->ats_count);
+ address_length = ntohs (m->address_length);
+ plugin_name_length = ntohs (m->plugin_name_length);
+ atsi = (const struct GNUNET_ATS_Information *) &m[1];
+ address = (const char *) &atsi[ats_count];
+ if (plugin_name_length != 0)
+ plugin_name = &address[address_length];
+ else
+ plugin_name = "";
+
+ if ((address_length + plugin_name_length +
+ ats_count * sizeof (struct GNUNET_ATS_Information) +
+ sizeof (struct AddressUpdateMessage) != ntohs (message->size)) ||
+ (ats_count >
+ GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)) ||
+ ((plugin_name_length > 0) && (plugin_name[plugin_name_length - 1] != '\0')))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ GNUNET_STATISTICS_update (GSA_stats, "# address updates received", 1,
+ GNUNET_NO);
+ GAS_addresses_add (address_handle, &m->peer, plugin_name, address, address_length,
+ ntohl (m->session_id), atsi, ats_count);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -276,7 +335,7 @@ GAS_handle_address_update (void *cls, struct GNUNET_SERVER_Client *client,
}
GNUNET_STATISTICS_update (GSA_stats, "# address updates received", 1,
GNUNET_NO);
- GAS_addresses_update (&m->peer, plugin_name, address, address_length,
+ GAS_addresses_update (address_handle, &m->peer, plugin_name, address, address_length,
ntohl (m->session_id), atsi, ats_count);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
@@ -332,12 +391,13 @@ GAS_handle_address_in_use (void *cls, struct GNUNET_SERVER_Client *client,
}
in_use = ntohs (m->in_use);
- res = GAS_addresses_in_use (&m->peer,
- plugin_name,
- address,
- address_length,
- ntohl (m->session_id),
- in_use);
+ res = GAS_addresses_in_use (address_handle,
+ &m->peer,
+ plugin_name,
+ address,
+ address_length,
+ ntohl (m->session_id),
+ in_use);
if (res == GNUNET_OK)
GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -402,7 +462,8 @@ GAS_handle_address_destroyed (void *cls, struct GNUNET_SERVER_Client *client,
return;
}
GNUNET_STATISTICS_update (GSA_stats, "# addresses destroyed", 1, GNUNET_NO);
- GAS_addresses_destroy (&m->peer, plugin_name, address, address_length,
+ GAS_addresses_destroy (address_handle, &m->peer, plugin_name,
+ address, address_length,
ntohl (m->session_id));
if (0 != ntohl (m->session_id))
{
@@ -421,10 +482,12 @@ GAS_handle_address_destroyed (void *cls, struct GNUNET_SERVER_Client *client,
* Initialize scheduling subsystem.
*
* @param server handle to our server
+ * @param ah the address handle to use
*/
void
-GAS_scheduling_init (struct GNUNET_SERVER_Handle *server)
+GAS_scheduling_init (struct GNUNET_SERVER_Handle *server, struct GAS_Addresses_Handle *ah)
{
+ address_handle = ah;
nc = GNUNET_SERVER_notification_context_create (server, 128);
}
diff --git a/src/ats/gnunet-service-ats_scheduling.h b/src/ats/gnunet-service-ats_scheduling.h
index 08a7f1b..d7b5e9c 100644
--- a/src/ats/gnunet-service-ats_scheduling.h
+++ b/src/ats/gnunet-service-ats_scheduling.h
@@ -115,6 +115,18 @@ GAS_handle_request_address_cancel (void *cls,
struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message);
+
+/**
+ * Handle 'address add' messages from clients.
+ *
+ * @param cls unused, NULL
+ * @param client client that sent the request
+ * @param message the request message
+ */
+void
+GAS_handle_address_add (void *cls, struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message);
+
/**
* Handle 'address update' messages from clients.
*
@@ -147,7 +159,8 @@ GAS_handle_address_in_use (void *cls, struct GNUNET_SERVER_Client *client,
* @param message the request message
*/
void
-GAS_handle_address_destroyed (void *cls, struct GNUNET_SERVER_Client *client,
+GAS_handle_address_destroyed (void *cls,
+ struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message);
@@ -155,9 +168,10 @@ GAS_handle_address_destroyed (void *cls, struct GNUNET_SERVER_Client *client,
* Initialize scheduling subsystem.
*
* @param server handle to our server
+ * @param ah the address handle to use
*/
void
-GAS_scheduling_init (struct GNUNET_SERVER_Handle *server);
+GAS_scheduling_init (struct GNUNET_SERVER_Handle *server, struct GAS_Addresses_Handle *ah);
/**
diff --git a/src/ats/perf_ats_mlp.c b/src/ats/perf_ats_mlp.c
deleted file mode 100644
index b9ee5e4..0000000
--- a/src/ats/perf_ats_mlp.c
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 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 ats/perf_ats_mlp
- * @brief performance test for the MLP solver
- * @author Christian Grothoff
- * @author Matthias Wachs
-
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_statistics_service.h"
-#include "gnunet-service-ats_addresses_mlp.h"
-
-#define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3)
-#define MLP_MAX_ITERATIONS INT_MAX
-
-#define DEF_PEERS 10
-#define DEF_ADDRESSES_PER_PEER 5
-#define DEF_ATS_VALUES 2
-#define DEF_ATS_MAX_DELAY 30
-#define DEF_ATS_MAX_DISTANCE 3
-
-static unsigned int peers;
-static unsigned int addresses;
-static unsigned int numeric;
-static unsigned int update_percentage;
-
-static int start;
-static int end;
-
-struct ATS_Peer *p;
-struct ATS_Address *a;
-
-static int ret;
-
-static struct GNUNET_CONTAINER_MultiHashMap * amap;
-
-static struct GAS_MLP_Handle *mlp;
-
-
-
-
-GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
-
-struct PeerContext
-{
- struct GNUNET_PeerIdentity id;
-
- struct Address *addr;
-};
-
-struct Address
-{
- char *plugin;
- size_t plugin_len;
-
- void *addr;
- size_t addr_len;
-
- struct GNUNET_ATS_Information *ats;
- int ats_count;
-
- void *session;
-};
-
-void
-do_shutdown (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- unsigned int ca;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown\n");
-
- if (NULL != mlp)
- {
- GAS_mlp_done (mlp);
- mlp = NULL;
- }
-
- if (NULL != a)
- {
- for (ca=0; ca < (peers * addresses); ca++)
- {
- GNUNET_free (a[ca].plugin);
- GNUNET_free (a[ca].ats);
- }
- }
-
- if (NULL != amap)
- GNUNET_CONTAINER_multihashmap_destroy(amap);
- GNUNET_free_non_null (a);
- GNUNET_free_non_null (p);
-
-}
-
-static void
-update_addresses (struct ATS_Address * a, unsigned int addrs, unsigned int percentage)
-{
- if (percentage == 0)
- return;
-
- unsigned int ua = (addrs) * ((float) percentage / 100);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updating %u of %u addresses per peer\n", ua, addrs);
-
- unsigned int updated[addrs];
- unsigned int u_types[DEF_ATS_VALUES];
- unsigned int updates = 0;
- unsigned int u_type = 0;
- unsigned int u_val = 0;
- unsigned int cur = 0;
-
- u_types[0] = 0;
- u_types[1] = 0;
-
- for (cur = 0; cur < addrs; cur ++)
- {
- updated[cur] = 0;
- }
- cur = 0;
-
- while (updates < ua)
- {
- cur = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, addrs);
- if (0 == updated[cur])
- {
- u_type = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_VALUES);
- switch (u_type) {
- case 0:
- do
- {
- u_val = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DELAY);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating DELAY from %u to %u\n",a[cur].ats[u_type].value, u_val);
- }
- while (a[cur].ats[u_type].value == u_val);
- break;
- case 1:
- do
- {
- u_val = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DISTANCE);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating DISTANCE from %u to %u\n",a[cur].ats[u_type].value, u_val);
- }
- while (a[cur].ats[u_type].value == u_val);
- break;
- default:
- GNUNET_break (0);
- break;
- }
- u_types[u_type]++;
-
- a[cur].ats[u_type].value = u_val;
- updated[cur] = 1;
- GAS_mlp_address_update(mlp, amap, &a[cur]);
- updates++;
- }
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updated %u delay and %u distance values\n", u_types[0], u_types[1]);
-
-}
-
-
-static void
-check (void *cls, char *const *args, const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- unsigned int c = 0;
- unsigned int c2 = 0;
- unsigned int ca = 0;
- int update = GNUNET_NO;
- int range = GNUNET_NO;
- int res;
-
-#if !HAVE_LIBGLPK
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!");
- ret = 1;
- return;
-#endif
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up %u peers with %u addresses per peer\n", peers, addresses);
-
- mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
- if (NULL == mlp)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to init MLP\n");
- ret = 1;
- if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
- GNUNET_SCHEDULER_cancel(shutdown_task);
- shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
- }
-
- if (peers == 0)
- peers = DEF_PEERS;
- if (addresses == 0)
- addresses = DEF_ADDRESSES_PER_PEER;
-
- p = GNUNET_malloc (peers * sizeof (struct ATS_Peer));
- a = GNUNET_malloc (peers * addresses * sizeof (struct ATS_Address));
-
- amap = GNUNET_CONTAINER_multihashmap_create(addresses * peers);
-
- mlp->auto_solve = GNUNET_NO;
- if (start == 0)
- start = 0;
- if (end == 0)
- end = -1;
- if ((start != -1) && (end != -1))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Solving problem starting from %u to %u\n", start , end);
- range = GNUNET_YES;
- }
- else
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Solving problem for %u peers\n", peers);
-
- if ((update_percentage >= 0) && (update_percentage <= 100))
- {
- update = GNUNET_YES;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Benchmarking with existing presolution and %u%% updated addresses\n", update_percentage);
- }
- else if ((update_percentage > 100) && (update_percentage != UINT_MAX))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Invalid percentage: %u\n", update_percentage);
- ret = 1;
- return;
- }
-
- for (c=0; c < peers; c++)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up peer %u\n", c);
- GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_NONCE, &p[c].id.hashPubKey);
-
- for (c2=0; c2 < addresses; c2++)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up address %u for peer %u\n", c2, c);
- /* Setting required information */
- a[ca].mlp_information = NULL;
- a[ca].prev = NULL;
- a[ca].next = NULL;
-
- /* Setting address */
- a[ca].peer = p[c].id;
- a[ca].plugin = GNUNET_strdup("test");
- a[ca].atsp_network_type = GNUNET_ATS_NET_LOOPBACK;
-
- a[ca].ats = GNUNET_malloc (DEF_ATS_VALUES * sizeof (struct GNUNET_ATS_Information));
- a[ca].ats[0].type = GNUNET_ATS_QUALITY_NET_DELAY;
- a[ca].ats[0].value = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DELAY);
- a[ca].ats[1].type = GNUNET_ATS_QUALITY_NET_DISTANCE;
- a[ca].ats[1].value = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DISTANCE);
- a[ca].ats_count = 2;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up address %u\n", ca);
- GNUNET_CONTAINER_multihashmap_put (amap, &a[ca].peer.hashPubKey, &a[ca], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- GAS_mlp_address_update(mlp, amap, &a[ca]);
- ca++;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Problem contains %u peers and %u adresses\n", mlp->c_p, mlp->addr_in_problem);
-
- if (((GNUNET_YES == range) && (((start >= 0) && ((c+1) >= start)) && (c <= end))) || ((c+1) == peers))
- {
- GNUNET_assert ((c+1) == mlp->c_p);
- GNUNET_assert ((c+1) * addresses == mlp->addr_in_problem);
-
- /* Solving the problem */
- struct GAS_MLP_SolutionContext ctx;
-
- res = GAS_mlp_solve_problem(mlp, &ctx);
-
- if (GNUNET_NO == update)
- {
- if (GNUNET_OK == res)
- {
- GNUNET_assert (GNUNET_OK == ctx.lp_result);
- GNUNET_assert (GNUNET_OK == ctx.mlp_result);
- if (GNUNET_YES == numeric)
- printf ("%u;%u;%llu;%llu\n",mlp->c_p, mlp->addr_in_problem, (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value);
- else
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Problem solved for %u peers with %u address successfully (LP: %llu ms / MLP: %llu ms)\n",
- mlp->c_p, mlp->addr_in_problem, ctx.lp_duration.rel_value, ctx.mlp_duration.rel_value);
- }
- else
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Solving problem with %u peers and %u addresses failed\n", c, c2);
- }
- else
- {
- struct GAS_MLP_SolutionContext uctx;
- /* Update addresses */
- update_addresses (a, (c+1) * c2, update_percentage);
-
- /* Solve again */
- res = GAS_mlp_solve_problem(mlp, &uctx);
-
- if (GNUNET_OK == res)
- {
- GNUNET_assert (GNUNET_OK == uctx.lp_result);
- GNUNET_assert (GNUNET_OK == uctx.mlp_result);
- if (GNUNET_YES == numeric)
- printf ("%u;%u;%llu;%llu;%llu;%llu\n",mlp->c_p, mlp->addr_in_problem,
- (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value,
- (unsigned long long) uctx.lp_duration.rel_value, (unsigned long long) uctx.mlp_duration.rel_value);
- else
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updated problem solved for %u peers with %u address successfully (Initial: LP/MLP: %llu/%llu ms, Update: %llu/%llu ms)\n",
- mlp->c_p, mlp->addr_in_problem,
- (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value,
- (unsigned long long) uctx.lp_duration.rel_value, (unsigned long long) uctx.mlp_duration.rel_value);
- }
- else
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Solving updated problem with %u peers and %u addresses failed\n", c, c2);
- }
- }
- }
-
- if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
- GNUNET_SCHEDULER_cancel(shutdown_task);
- shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
-
-}
-
-
-int
-main (int argc, char *argv[])
-{
- /* Init invalid */
- update_percentage = UINT_MAX;
- static struct GNUNET_GETOPT_CommandLineOption options[] = {
- {'a', "addresses", NULL,
- gettext_noop ("addresses per peer"), 1,
- &GNUNET_GETOPT_set_uint, &addresses},
- {'p', "peers", NULL,
- gettext_noop ("peers"), 1,
- &GNUNET_GETOPT_set_uint, &peers},
- {'n', "numeric", NULL,
- gettext_noop ("numeric output only"), 0,
- &GNUNET_GETOPT_set_one, &numeric},
- {'e', "end", NULL,
- gettext_noop ("end solving problem"), 1,
- &GNUNET_GETOPT_set_uint, &end},
- {'s', "start", NULL,
- gettext_noop ("start solving problem"), 1,
- &GNUNET_GETOPT_set_uint, &start},
- {'u', "update", NULL,
- gettext_noop ("benchmark with existing solution (address updates)"), 1,
- &GNUNET_GETOPT_set_uint, &update_percentage},
- GNUNET_GETOPT_OPTION_END
- };
-
-
- GNUNET_PROGRAM_run (argc, argv,
- "perf_ats_mlp", "nohelp", options,
- &check, NULL);
-
-
- return ret;
-}
-
-/* end of file perf_ats_mlp.c */
diff --git a/src/ats/test_ats_api.conf b/src/ats/test_ats_api.conf
index efd7fc9..9e00a15 100644
--- a/src/ats/test_ats_api.conf
+++ b/src/ats/test_ats_api.conf
@@ -7,13 +7,11 @@ DEFAULTSERVICES = ats
UNIXPATH = /tmp/test-ats-scheduling-arm.sock
[ats]
-#DEBUG = YES
-#PREFIX = valgrind --leak-check=full
+#PREFIX = valgrind --leak-check=full --track-origins=yes --num-callers=25
AUTOSTART = YES
PORT = 12002
HOSTNAME = localhost
HOME = $SERVICEHOME
-CONFIG = $DEFAULTCONFIG
BINARY = gnunet-service-ats
ACCEPT_FROM = 127.0.0.1;
ACCEPT_FROM6 = ::1;
@@ -22,8 +20,11 @@ UNIX_MATCH_UID = YES
UNIX_MATCH_GID = YES
# Enable MLP mode (default: NO)
-MLP = NO
+MODE = SIMPLISTIC
# Network specific inbound/outbound quotas
+# UNSPECIFIED
+UNSPECIFIED_QUOTA_IN = 64 KiB
+UNSPECIFIED_QUOTA_OUT = 64 KiB
# LOOPBACK
LOOPBACK_QUOTA_IN = unlimited
LOOPBACK_QUOTA_OUT = unlimited
@@ -34,8 +35,8 @@ LAN_QUOTA_OUT = unlimited
WAN_QUOTA_IN = 64 KiB
WAN_QUOTA_OUT = 64 KiB
# WLAN
-WLAN_QUOTA_IN = 1 MiB
-WLAN_QUOTA_OUT = 1 MiB
+WLAN_QUOTA_IN = 512
+WLAN_QUOTA_OUT = 512
# ATS extended options
DUMP_MLP = NO
diff --git a/src/ats/test_ats_api_common.c b/src/ats/test_ats_api_common.c
new file mode 100644
index 0000000..f1002f8
--- /dev/null
+++ b/src/ats/test_ats_api_common.c
@@ -0,0 +1,139 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_common.c
+ * @brief shared functions for ats test
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+
+#include "test_ats_api_common.h"
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
+
+#define PEERID0 "2AK99KD8RM9UA9LC3QKA0IQ5UBFC0FBB50EBGCFQT8448DGGACNAC4CJQDD1CPFS494O41U88DJD1FLIG8VA5CQR9IN4L96GP104MVO"
+#define PEERID1 "5ED7I0AR3MSTAL7FQN04S22E0EQ3CR9RLASCDLVMM1BNFPUPTCT46DLKNJ4DACASJ6U0DR5J8S3R2UJL49682JS7MOVRAB8P8A4PJH0"
+
+void
+create_test_address (struct Test_Address *dest, char * plugin, void *session, void *addr, size_t addrlen)
+{
+
+ dest->plugin = GNUNET_strdup (plugin);
+ dest->session = session;
+ if (addrlen > 0)
+ {
+ dest->addr = GNUNET_malloc (addrlen);
+ memcpy (dest->addr, addr, addrlen);
+ }
+ else
+ dest->addr = NULL;
+ dest->addr_len = addrlen;
+}
+
+void
+free_test_address (struct Test_Address *dest)
+{
+ GNUNET_free (dest->plugin);
+ if (NULL != dest->addr)
+ GNUNET_free (dest->addr);
+}
+
+int
+compare_addresses (const struct GNUNET_HELLO_Address *address1, void *session1,
+ const struct GNUNET_HELLO_Address *address2, void *session2)
+{
+ if (0 != memcmp (&address1->peer, &address2->peer, sizeof (struct GNUNET_PeerIdentity)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggestion with invalid peer id'\n");
+ return GNUNET_SYSERR;
+ }
+ if (0 != strcmp (address1->transport_name, address2->transport_name))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggestion with invalid plugin'\n");
+ return GNUNET_SYSERR;
+ }
+ if (address1->address_length != address2->address_length)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggestion with invalid address length'\n");
+ return GNUNET_SYSERR;
+
+ }
+ else if (0 != memcmp (address1->address, address2->address, address2->address_length))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggestion with invalid address'\n");
+ return GNUNET_SYSERR;
+ }
+ if (session1 != session2)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggestion with invalid session1 %p vs session2 %p'\n",
+ session1, session2);
+ return GNUNET_SYSERR;
+
+ }
+ return GNUNET_OK;
+}
+
+
+int
+compare_ats (const struct GNUNET_ATS_Information *ats_is, uint32_t ats_count_is,
+ const struct GNUNET_ATS_Information *ats_should, uint32_t ats_count_should)
+{
+ unsigned int c_o;
+ unsigned int c_i;
+ char *prop[] = GNUNET_ATS_PropertyStrings;
+ uint32_t type1;
+ uint32_t type2;
+ uint32_t val1;
+ uint32_t val2;
+ int res = GNUNET_OK;
+
+ for (c_o = 0; c_o < ats_count_is; c_o++)
+ {
+ for (c_i = 0; c_i < ats_count_should; c_i++)
+ {
+ type1 = ntohl(ats_is[c_o].type);
+ type2 = ntohl(ats_should[c_i].type);
+ if (type1 == type2)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS type `%s'\n",
+ prop[type1]);
+ val1 = ntohl(ats_is[c_o].value);
+ val2 = ntohl(ats_should[c_i].value);
+ if (val1 != val2)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ATS value `%s' not equal: %u != %u\n",
+ prop[type1],
+ val1, val2);
+ res = GNUNET_SYSERR;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS value `%s' equal: %u == %u\n",
+ prop[type1],
+ val1, val2);
+ }
+ }
+ }
+ }
+ return res;
+}
+
+
+/* end of file test_ats_api_common.c */
diff --git a/src/ats/test_ats_api_common.h b/src/ats/test_ats_api_common.h
new file mode 100644
index 0000000..04dd11b
--- /dev/null
+++ b/src/ats/test_ats_api_common.h
@@ -0,0 +1,75 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_common.h
+ * @brief shared definitions for ats testcases
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_ats_service.h"
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
+
+#define PEERID0 "2AK99KD8RM9UA9LC3QKA0IQ5UBFC0FBB50EBGCFQT8448DGGACNAC4CJQDD1CPFS494O41U88DJD1FLIG8VA5CQR9IN4L96GP104MVO"
+#define PEERID1 "5ED7I0AR3MSTAL7FQN04S22E0EQ3CR9RLASCDLVMM1BNFPUPTCT46DLKNJ4DACASJ6U0DR5J8S3R2UJL49682JS7MOVRAB8P8A4PJH0"
+
+struct Test_Address
+{
+ char *plugin;
+ size_t plugin_len;
+
+ void *addr;
+ size_t addr_len;
+
+ struct GNUNET_ATS_Information *ats;
+ int ats_count;
+
+ void *session;
+};
+
+struct PeerContext
+{
+ struct GNUNET_PeerIdentity id;
+
+ struct Test_Address *addr;
+
+ unsigned long long bw_out_assigned;
+
+ unsigned long long bw_in_assigned;
+};
+
+void
+free_test_address (struct Test_Address *dest);
+
+void
+create_test_address (struct Test_Address *dest, char * plugin, void *session, void *addr, size_t addrlen);
+
+int
+compare_addresses (const struct GNUNET_HELLO_Address *address1, void *session1,
+ const struct GNUNET_HELLO_Address *address2, void *session2);
+
+int
+compare_ats (const struct GNUNET_ATS_Information *ats_is, uint32_t ats_count_is,
+ const struct GNUNET_ATS_Information *ats_should, uint32_t ats_count_should);
+
+/* end of file test_ats_api_common.h */
diff --git a/src/ats/test_ats_api_performance.c b/src/ats/test_ats_api_performance.c
new file mode 100644
index 0000000..64737d8
--- /dev/null
+++ b/src/ats/test_ats_api_performance.c
@@ -0,0 +1,596 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_performance.c
+ * @brief test adding addresses in automatic transport selection performance API
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+struct GNUNET_CONFIGURATION_Handle *cfg;
+
+static struct GNUNET_ATS_SchedulingHandle *atsh;
+static struct GNUNET_ATS_PerformanceHandle *ph;
+struct GNUNET_ATS_AddressListHandle* phal;
+
+static int ret;
+
+struct Address
+{
+ char *plugin;
+ size_t plugin_len;
+
+ void *addr;
+ size_t addr_len;
+
+ struct GNUNET_ATS_Information *ats;
+ int ats_count;
+
+ void *session;
+};
+
+struct PeerContext
+{
+ struct GNUNET_PeerIdentity id;
+
+ struct Address *addr;
+};
+
+
+
+static struct PeerContext p[2];
+
+static struct Address p0_addresses[2];
+static struct Address p1_addresses[2];
+
+struct GNUNET_HELLO_Address p0_ha[2];
+struct GNUNET_HELLO_Address p1_ha[2];
+struct GNUNET_HELLO_Address *s_ha[2];
+
+static unsigned int stage = 0;
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Timeout in stage %u\n", stage);
+
+ if (NULL != atsh)
+ GNUNET_ATS_scheduling_done (atsh);
+ if (phal != NULL)
+ GNUNET_ATS_performance_list_addresses_cancel (phal);
+ phal = NULL;
+ if (ph != NULL)
+ GNUNET_ATS_performance_done (ph);
+ ph = NULL;
+
+ GNUNET_free_non_null (p0_addresses[0].addr);
+ GNUNET_free_non_null (p0_addresses[1].addr);
+ GNUNET_free_non_null (p1_addresses[0].addr);
+ GNUNET_free_non_null (p1_addresses[1].addr);
+
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (NULL != atsh)
+ GNUNET_ATS_scheduling_done (atsh);
+ if (phal != NULL)
+ GNUNET_ATS_performance_list_addresses_cancel (phal);
+ phal = NULL;
+ if (ph != NULL)
+ GNUNET_ATS_performance_done (ph);
+ ph = NULL;
+
+ GNUNET_free_non_null (p0_addresses[0].addr);
+ GNUNET_free_non_null (p0_addresses[1].addr);
+ GNUNET_free_non_null (p1_addresses[0].addr);
+ GNUNET_free_non_null (p1_addresses[1].addr);
+
+ ret = 0;
+}
+
+static void
+test_performance_api (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+void all_active_addresses_peer_cb (void *cls,
+ const struct
+ GNUNET_HELLO_Address *
+ address,
+ struct
+ GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct
+ GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_in,
+ const struct
+ GNUNET_ATS_Information *
+ ats, uint32_t ats_count)
+{
+ static int cb = 0;
+ int fail = GNUNET_NO;
+
+ if (address != NULL)
+ {
+ if (0 == memcmp (&address->peer, &p[0].id,
+ sizeof (struct GNUNET_PeerIdentity)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Did not expected callback for peer 0 address `%s', got address `%s'!\n",
+ s_ha[0]->address, address->address);
+ GNUNET_ATS_performance_list_addresses_cancel (phal);
+ fail = GNUNET_YES;
+ }
+
+ if (0 == memcmp (&address->peer, &p[1].id,
+ sizeof (struct GNUNET_PeerIdentity)))
+ {
+ if (0 == strcmp(address->address, s_ha[1]->address))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Callback for peer 1 suggested address %s\n",
+ s_ha[1]->address);
+ cb ++;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Expected callback for peer 1 address `%s', got address `%s'!\n",
+ s_ha[1]->address, address->address);
+ GNUNET_ATS_performance_list_addresses_cancel (phal);
+ fail = GNUNET_YES;
+ }
+ }
+ }
+ if ((address == NULL) || (GNUNET_YES == fail))
+ {
+ phal = NULL;
+ if ((1 == cb) && (GNUNET_NO == fail))
+ {
+ /* Received all addresses + terminator cb, next stage */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %i: SUCCESS\n", stage);
+ GNUNET_SCHEDULER_add_now (&test_performance_api, NULL);
+ return;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %i: FAIL\n", stage);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 5;
+ return;
+ }
+ }
+}
+
+void all_active_addresses_cb (void *cls,
+ const struct
+ GNUNET_HELLO_Address *
+ address,
+ struct
+ GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct
+ GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_in,
+ const struct
+ GNUNET_ATS_Information *
+ ats, uint32_t ats_count)
+{
+ static int cb = 0;
+ int fail = GNUNET_NO;
+
+ if (address != NULL)
+ {
+ if (0 == memcmp (&address->peer, &p[0].id,
+ sizeof (struct GNUNET_PeerIdentity)))
+ {
+ if (0 == strcmp(address->address, s_ha[0]->address))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Callback for peer 0 suggested address %s\n",
+ s_ha[0]->address);
+ cb ++;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Expected callback for peer 0 address `%s', got address `%s'!\n",
+ s_ha[0]->address, address->address);
+ GNUNET_ATS_performance_list_addresses_cancel (phal);
+ fail = GNUNET_YES;
+ }
+ }
+
+ if (0 == memcmp (&address->peer, &p[1].id,
+ sizeof (struct GNUNET_PeerIdentity)))
+ {
+ if (0 == strcmp(address->address, s_ha[1]->address))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Callback for peer 1 suggested address %s\n",
+ s_ha[1]->address);
+ cb ++;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Expected callback for peer 1 address `%s', got address `%s'!\n",
+ s_ha[1]->address, address->address);
+ GNUNET_ATS_performance_list_addresses_cancel (phal);
+ fail = GNUNET_YES;
+ }
+ }
+ }
+ if ((address == NULL) || (GNUNET_YES == fail))
+ {
+ phal = NULL;
+ if ((2 == cb) && (GNUNET_NO == fail))
+ {
+ /* Received all addresses + terminator cb, next stage */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %i: SUCCESS\n", stage);
+ GNUNET_SCHEDULER_add_now (&test_performance_api, NULL);
+ return;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %i: FAIL\n", stage);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 5;
+ return;
+ }
+ }
+}
+
+
+
+void all_addresses_peer_cb (void *cls,
+ const struct
+ GNUNET_HELLO_Address *
+ address,
+ struct
+ GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct
+ GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_in,
+ const struct
+ GNUNET_ATS_Information *
+ ats, uint32_t ats_count)
+{
+ static int cb = 0;
+ int fail = GNUNET_NO;
+
+ if (address != NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Callback for peer `%s' address `%s'\n",
+ GNUNET_i2s (&address->peer), address->address);
+
+ if (0 != memcmp (&address->peer, &p[1].id,
+ sizeof (struct GNUNET_PeerIdentity)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Stage %i: Received address for wrong peer\n", stage);
+ GNUNET_ATS_performance_list_addresses_cancel (phal);
+ fail = GNUNET_YES;
+ ret = 4;
+ }
+ cb ++;
+ }
+
+ if ((NULL == address) || (fail))
+ {
+ phal = NULL;
+ if ((2 == cb) && (GNUNET_NO == fail))
+ {
+ /* Received all addresses + terminator cb, next stage */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %i: SUCCESS\n", stage);
+ GNUNET_SCHEDULER_add_now (&test_performance_api, NULL);
+ return;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %i: FAIL\n", stage);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 5;
+ return;
+ }
+ }
+}
+
+void all_addresses_cb (void *cls,
+ const struct
+ GNUNET_HELLO_Address *
+ address,
+ struct
+ GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_out,
+ struct
+ GNUNET_BANDWIDTH_Value32NBO
+ bandwidth_in,
+ const struct
+ GNUNET_ATS_Information *
+ ats, uint32_t ats_count)
+{
+ static int cb = 0;
+
+ if (address != NULL)
+ {
+ if (0 == memcmp (&address->peer, &p[0].id,
+ sizeof (struct GNUNET_PeerIdentity)))
+ {
+ if (0 == strcmp(address->address, p0_addresses[0].addr))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for peer 0 address 0\n");
+ cb |= 1;
+ }
+ if (0 == strcmp(address->address, p0_addresses[1].addr))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for peer 0 address 1\n");
+ cb |= 2;
+ }
+ }
+ if (0 == memcmp (&address->peer, &p[1].id,
+ sizeof (struct GNUNET_PeerIdentity)))
+ {
+ if (0 == strcmp(address->address, p1_addresses[0].addr))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for peer 1 address 0\n");
+ cb |= 4;
+ }
+ if (0 == strcmp(address->address, p1_addresses[1].addr))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback for peer 1 address 1\n");
+ cb |= 8;
+ }
+ }
+ }
+ else
+ {
+ phal = NULL;
+ if (((1 << 4) - 1) == cb)
+ {
+ /* Received all addresses + terminator cb, next stage */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %i: SUCCESS\n", stage);
+ GNUNET_SCHEDULER_add_now (&test_performance_api, NULL);
+ return;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %i: FAIL\n", stage);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 3;
+ return;
+ }
+ }
+}
+
+static void
+test_performance_api (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (NULL == ph)
+ ph = GNUNET_ATS_performance_init (cfg, NULL, NULL);
+ if (NULL == ph)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to initialize performance handle\n");
+ ret = 2;
+ }
+ stage++;
+ switch (stage) {
+ case 1: /* Get all peers, all addresses */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Run stage 1: \n");
+ phal = GNUNET_ATS_performance_list_addresses (ph,
+ NULL,
+ GNUNET_YES,
+ &all_addresses_cb, NULL);
+ GNUNET_assert (NULL != phal);
+ break;
+ case 2: /* Get specific peer, all addresses */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Run stage 2: \n");
+ phal = GNUNET_ATS_performance_list_addresses (ph,
+ &p[1].id,
+ GNUNET_YES,
+ &all_addresses_peer_cb, NULL);
+ GNUNET_assert (NULL != phal);
+ break;
+ case 3: /* Get all peers, active addresses */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Run stage 3: \n");
+ phal = GNUNET_ATS_performance_list_addresses (ph,
+ NULL,
+ GNUNET_NO,
+ &all_active_addresses_cb, NULL);
+ GNUNET_assert (NULL != phal);
+ break;
+ case 4: /* Get specific peers, active addresses */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Run stage 4: \n");
+ phal = GNUNET_ATS_performance_list_addresses (ph,
+ &p[1].id,
+ GNUNET_NO,
+ &all_active_addresses_peer_cb, NULL);
+ GNUNET_assert (NULL != phal);
+ break;
+ default:
+ /* done */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "All tests successful, shutdown... \n");
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+}
+
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *ats,
+ uint32_t ats_count)
+{
+ static int suggest_p0 = GNUNET_NO;
+ static int suggest_p1 = GNUNET_NO;
+ static int running = GNUNET_NO;
+
+ if ((GNUNET_NO == suggest_p0) && (0 == memcmp (&address->peer, &p[0].id,
+ sizeof (struct GNUNET_PeerIdentity))))
+ {
+ suggest_p0 = GNUNET_YES;;
+
+ if (s_ha[0] != NULL)
+ GNUNET_free (s_ha[0]);
+ s_ha[0] = GNUNET_HELLO_address_copy (address);
+ GNUNET_ATS_suggest_address_cancel (atsh, &p[0].id);
+ }
+ if ((GNUNET_NO == suggest_p1) && (0 == memcmp (&address->peer, &p[1].id,
+ sizeof (struct GNUNET_PeerIdentity))))
+ {
+ suggest_p1 = GNUNET_YES;
+
+ if (s_ha[1] != NULL)
+ GNUNET_free (s_ha[1]);
+ s_ha[1] = GNUNET_HELLO_address_copy (address);
+ GNUNET_ATS_suggest_address_cancel (atsh, &p[1].id);
+ }
+
+
+ if ((GNUNET_NO == running) && (GNUNET_YES == suggest_p0) && (GNUNET_YES == suggest_p1))
+ {
+ running = GNUNET_YES;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have address suggestion for both peers\n");
+ GNUNET_SCHEDULER_add_now (&test_performance_api, NULL);
+ }
+
+}
+
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *mycfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ ret = 1;
+ cfg = (struct GNUNET_CONFIGURATION_Handle *) mycfg;
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+
+ /* set up peer 0 */
+ GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
+ &p[0].id.hashPubKey);
+
+ p0_addresses[0].plugin = "test";
+ p0_addresses[0].session = NULL;
+ p0_addresses[0].addr = GNUNET_strdup ("test_p0_a0");
+ p0_addresses[0].addr_len = strlen (p0_addresses[0].addr) + 1;
+
+ p0_ha[0].address = p0_addresses[0].addr;
+ p0_ha[0].address_length = p0_addresses[0].addr_len;
+ p0_ha[0].peer = p[0].id;
+ p0_ha[0].transport_name = p0_addresses[0].plugin;
+
+ p0_addresses[1].plugin = "test";
+ p0_addresses[1].session = NULL;
+ p0_addresses[1].addr = GNUNET_strdup ("test_p0_a1");
+ p0_addresses[1].addr_len = strlen(p0_addresses[1].addr) + 1;
+
+ p0_ha[1].address = p0_addresses[1].addr;
+ p0_ha[1].address_length = p0_addresses[1].addr_len;
+ p0_ha[1].peer = p[0].id;
+ p0_ha[1].transport_name = p0_addresses[1].plugin;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer 0: `%s'\n",
+ GNUNET_i2s (&p[0].id));
+
+ GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
+ &p[1].id.hashPubKey);
+
+ p1_addresses[0].plugin = "test";
+ p1_addresses[0].session = NULL;
+ p1_addresses[0].addr = GNUNET_strdup ("test_p1_a0");
+ p1_addresses[0].addr_len = strlen(p1_addresses[0].addr) + 1;
+
+ p1_ha[0].address = p1_addresses[0].addr;
+ p1_ha[0].address_length = p1_addresses[0].addr_len;
+ p1_ha[0].peer = p[1].id;
+ p1_ha[0].transport_name = p1_addresses[0].plugin;
+
+ p1_addresses[1].plugin = "test";
+ p1_addresses[1].session = NULL;
+ p1_addresses[1].addr = GNUNET_strdup ("test_p1_a1");
+ p1_addresses[1].addr_len = strlen(p1_addresses[1].addr) + 1;
+
+ p1_ha[1].address = p1_addresses[1].addr;
+ p1_ha[1].address_length = p1_addresses[1].addr_len;
+ p1_ha[1].peer = p[1].id;
+ p1_ha[1].transport_name = p1_addresses[1].plugin;
+
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer 1: `%s'\n",
+ GNUNET_i2s (&p[1].id));
+
+
+ /* Add addresses */
+ atsh = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (atsh == NULL)
+ {
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_ATS_address_add (atsh, &p0_ha[0], NULL, NULL, 0);
+ GNUNET_ATS_address_add (atsh, &p0_ha[1], NULL, NULL, 0);
+
+ GNUNET_ATS_address_add (atsh, &p1_ha[0], NULL, NULL, 0);
+ GNUNET_ATS_address_add (atsh, &p1_ha[1], NULL, NULL, 0);
+
+
+ GNUNET_ATS_suggest_address (atsh, &p[0].id);
+ GNUNET_ATS_suggest_address (atsh, &p[1].id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_performance",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+/* end of file test_ats_api_performance.c */
diff --git a/src/ats/test_ats_api_reset_backoff.c b/src/ats/test_ats_api_reset_backoff.c
deleted file mode 100644
index 38c18e1..0000000
--- a/src/ats/test_ats_api_reset_backoff.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 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 ats/test_ats_api_reset_backoff.c
- * @brief test case for block reset api
- * @author Christian Grothoff
- * @author Matthias Wachs
- */
-#include "platform.h"
-#include "gnunet_ats_service.h"
-#include "ats.h"
-
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
-#define ATS_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 90)
-
-static GNUNET_SCHEDULER_TaskIdentifier die_task;
-
-static GNUNET_SCHEDULER_TaskIdentifier suggest_timeout_task;
-
-static struct GNUNET_ATS_SchedulingHandle *ats;
-
-struct GNUNET_OS_Process *arm_proc;
-
-static int ret;
-
-struct Address
-{
- char *plugin;
- size_t plugin_len;
-
- void *addr;
- size_t addr_len;
-
- struct GNUNET_ATS_Information *ats;
- int ats_count;
-
- void *session;
-};
-
-struct PeerContext
-{
- struct GNUNET_PeerIdentity id;
-
- struct Address *addr;
-};
-
-struct GNUNET_HELLO_Address hello_addr;
-struct Address address;
-struct PeerContext peer;
-struct GNUNET_ATS_Information atsi[2];
-
-static void
-stop_arm ()
-{
- if (0 != GNUNET_OS_process_kill (arm_proc, SIGTERM))
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
- GNUNET_OS_process_wait (arm_proc);
- GNUNET_OS_process_destroy (arm_proc);
- arm_proc = NULL;
-}
-
-
-static void
-end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- die_task = GNUNET_SCHEDULER_NO_TASK;
-
- if (suggest_timeout_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (suggest_timeout_task);
- suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK;
- }
-
- if (ats != NULL)
- {
- GNUNET_ATS_scheduling_done (ats);
- ats = NULL;
- }
-
- ret = GNUNET_SYSERR;
-
- stop_arm ();
-}
-
-
-static void
-end ()
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
- if (die_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_NO_TASK;
- }
-
- if (suggest_timeout_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (suggest_timeout_task);
- suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK;
- }
-
- GNUNET_ATS_scheduling_done (ats);
-
- ret = 0;
-
- stop_arm ();
-}
-
-
-static void
-suggest_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting address for peer timed out\n");
-
- if (die_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_NO_TASK;
- }
-
- die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
-}
-
-static void
-address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *a,
- struct Session *session,
- struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
- struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
- const struct GNUNET_ATS_Information *atsi,
- uint32_t ats_count)
-{
- static int suggestions;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS suggests address `%s'\n",
- GNUNET_i2s (&a->peer));
-
- if (0 != memcmp (&a->peer, &peer.id,
- sizeof (struct GNUNET_PeerIdentity)))
- {
- GNUNET_break (0);
- if (die_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_NO_TASK;
- }
- GNUNET_SCHEDULER_add_now (&end_badly, NULL);
- return;
- }
-
- if (0 != strcmp (a->transport_name, address.plugin))
- {
- GNUNET_break (0);
- if (die_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_NO_TASK;
- }
- GNUNET_SCHEDULER_add_now (&end_badly, NULL);
- return;
- }
-
- if (a->address_length != address.addr_len)
- {
- GNUNET_break (0);
- if (die_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_NO_TASK;
- }
- GNUNET_SCHEDULER_add_now (&end_badly, NULL);
- return;
- }
-
- if (0 != memcmp (a->address, address.addr,
- a->address_length))
- {
- GNUNET_break (0);
- if (die_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_NO_TASK;
- }
- GNUNET_SCHEDULER_add_now (&end_badly, NULL);
- return;
- }
-
- if (session != address.session)
- {
- GNUNET_break (0);
- if (die_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_NO_TASK;
- }
- GNUNET_SCHEDULER_add_now (&end_badly, NULL);
- return;
- }
-
- suggestions ++;
-
- if (2 == suggestions)
- {
- GNUNET_SCHEDULER_add_now(&end, NULL);
- return;
- }
-
- if (suggest_timeout_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (suggest_timeout_task);
- suggest_timeout_task = GNUNET_SCHEDULER_NO_TASK;
- }
- suggest_timeout_task = GNUNET_SCHEDULER_add_delayed(ATS_TIMEOUT, &suggest_timeout, NULL);
-}
-
-void
-start_arm (const char *cfgname)
-{
- arm_proc =
- GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
- "gnunet-service-arm",
- "-c", cfgname, NULL);
-}
-
-static void
-check (void *cls, char *const *args, const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- ret = GNUNET_SYSERR;
-
- die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
- start_arm (cfgfile);
-
- ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
-
- if (ats == NULL)
- {
- ret = GNUNET_SYSERR;
- end ();
- return;
- }
-
- /* set up peer */
- GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
- &peer.id.hashPubKey);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n", GNUNET_i2s (&peer.id));
-
- address.plugin = "test";
- address.session = NULL;
- address.addr = GNUNET_strdup ("test");
- address.addr_len = 4;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding address\n");
-
- hello_addr.peer = peer.id;
- hello_addr.transport_name = address.plugin;
- hello_addr.address = address.addr;
- hello_addr.address_length = address.addr_len;
- GNUNET_ATS_address_update (ats, &hello_addr, address.session, NULL, 0);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting address for peer `%s'\n",
- GNUNET_i2s (&peer.id));
- /* Increase block timout far beyond ATS_TIMEOUT */
- GNUNET_ATS_suggest_address (ats, &peer.id);
-
- GNUNET_ATS_reset_backoff(ats, &peer.id);
- GNUNET_ATS_suggest_address (ats, &peer.id);
-}
-
-int
-main (int argc, char *argv[])
-{
- static char *const argv2[] = { "test_ats_api_scheduling",
- "-c",
- "test_ats_api.conf",
- "-L", "WARNING",
- NULL
- };
-
- static struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
-
- GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
- "test_ats_api_scheduling", "nohelp", options, &check,
- NULL);
-
-
- return ret;
-}
-/* end of file test_ats_api_reset_backoff.c */
diff --git a/src/ats/test_ats_api_scheduling.c b/src/ats/test_ats_api_scheduling.c
deleted file mode 100644
index c9d2206..0000000
--- a/src/ats/test_ats_api_scheduling.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 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 ats/test_ats_api_scheduling.c
- * @brief test automatic transport selection scheduling API
- * @author Christian Grothoff
- * @author Matthias Wachs
- *
- * TODO:
- * - write test case
- * - extend API to get performance data
- * - implement simplistic strategy based on say 'lowest latency' or strict ordering
- * - extend API to get peer preferences, implement proportional bandwidth assignment
- * - re-implement API against a real ATS service (!)
- */
-#include "platform.h"
-#include "gnunet_ats_service.h"
-#include "ats.h"
-
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
-
-static GNUNET_SCHEDULER_TaskIdentifier die_task;
-
-static struct GNUNET_ATS_SchedulingHandle *ats;
-
-struct GNUNET_OS_Process *arm_proc;
-
-
-
-static int ret;
-
-struct Address
-{
- char *plugin;
- size_t plugin_len;
-
- void *addr;
- size_t addr_len;
-
- struct GNUNET_ATS_Information *ats;
- int ats_count;
-
- void *session;
-};
-
-struct PeerContext
-{
- struct GNUNET_PeerIdentity id;
-
- struct Address *addr;
-};
-
-struct Address addr[2];
-struct PeerContext p[2];
-struct GNUNET_ATS_Information atsi[2];
-
-static void
-stop_arm ()
-{
- if (0 != GNUNET_OS_process_kill (arm_proc, SIGTERM))
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
- GNUNET_OS_process_wait (arm_proc);
- GNUNET_OS_process_destroy (arm_proc);
- arm_proc = NULL;
-}
-
-
-static void
-end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- die_task = GNUNET_SCHEDULER_NO_TASK;
- if (ats != NULL)
- GNUNET_ATS_scheduling_done (ats);
-
- ret = GNUNET_SYSERR;
-
- stop_arm ();
-}
-
-
-static void
-end ()
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
- if (die_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (die_task);
- die_task = GNUNET_SCHEDULER_NO_TASK;
- }
-
- GNUNET_ATS_scheduling_done (ats);
-
- ret = 0;
-
- stop_arm ();
-}
-
-
-static void
-address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
- struct Session *session,
- struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
- struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
- const struct GNUNET_ATS_Information *ats,
- uint32_t ats_count)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS suggests address `%s'\n",
- GNUNET_i2s (&address->peer));
-
- GNUNET_assert (0 ==
- memcmp (&address->peer, &p[0].id,
- sizeof (struct GNUNET_PeerIdentity)));
- GNUNET_assert (0 == strcmp (address->transport_name, addr[0].plugin));
- GNUNET_assert (address->address_length == addr[0].addr_len);
- GNUNET_assert (0 ==
- memcmp (address->address, addr[0].plugin,
- address->address_length));
- GNUNET_assert (addr[0].session == session);
-
-
- /* TODO ats merge
- * GNUNET_assert (ats_count == 2);
- * GNUNET_assert (atsi[0].type == htons (1));
- * GNUNET_assert (atsi[0].type == htons (2));
- * GNUNET_assert (atsi[1].type == htons (2));
- * GNUNET_assert (atsi[1].type == htons (2));
- */
-
- ret = 0;
-
- GNUNET_SCHEDULER_add_now (&end, NULL);
-}
-
-void
-start_arm (const char *cfgname)
-{
- arm_proc =
- GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
- "gnunet-service-arm",
- "-c", cfgname, NULL);
-}
-
-static void
-check (void *cls, char *const *args, const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- struct GNUNET_HELLO_Address address0;
-
- ret = GNUNET_SYSERR;
-
- die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
- start_arm (cfgfile);
-
- ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
-
- if (ats == NULL)
- {
- ret = GNUNET_SYSERR;
- end ();
- return;
- }
-
- /* set up peer */
- GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
- &p[0].id.hashPubKey);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
- GNUNET_i2s (&p[0].id));
-
- GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
- &p[1].id.hashPubKey);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
- GNUNET_i2s (&p[1].id));
-
- addr[0].plugin = "test";
- addr[0].session = NULL;
- addr[0].addr = GNUNET_strdup ("test");
- addr[0].addr_len = 4;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing address creation\n");
-
- address0.peer = p[0].id;
- address0.transport_name = addr[0].plugin;
- address0.address = addr[0].addr;
- address0.address_length = addr[0].addr_len;
- GNUNET_ATS_address_update (ats, &address0, addr[0].session, NULL, 0);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing ATS info creation\n");
-
- atsi[0].type = htonl (GNUNET_ATS_UTILIZATION_UP);
- atsi[0].value = htonl (1024);
-
- GNUNET_ATS_address_update (ats, &address0, addr[0].session, atsi, 1);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing ATS info update\n");
-
- atsi[0].type = htonl (GNUNET_ATS_UTILIZATION_UP);
- atsi[0].value = htonl (2048);
-
- atsi[1].type = htonl (GNUNET_ATS_UTILIZATION_DOWN);
- atsi[1].value = htonl (1024);
-
- GNUNET_ATS_address_update (ats, &address0, addr[0].session, atsi, 2);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing manual address deletion \n");
- address0.peer = p[1].id; // FIXME: why? typo in old code?
- GNUNET_ATS_address_update (ats, &address0, addr[0].session, NULL, 0);
- GNUNET_ATS_address_destroyed (ats, &address0, addr[0].session);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting peer `%s'\n",
- GNUNET_i2s (&p[0].id));
- GNUNET_ATS_suggest_address (ats, &p[0].id);
-}
-
-int
-main (int argc, char *argv[])
-{
- static char *const argv2[] = { "test_ats_api_scheduling",
- "-c",
- "test_ats_api.conf",
- "-L", "WARNING",
- NULL
- };
-
- static struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
-
- GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
- "test_ats_api_scheduling", "nohelp", options, &check,
- NULL);
-
-
- return ret;
-}
-
-/* end of file test_ats_api_scheduling.c */
diff --git a/src/ats/test_ats_api_scheduling_add_address.c b/src/ats/test_ats_api_scheduling_add_address.c
new file mode 100644
index 0000000..f7ee195
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_add_address.c
@@ -0,0 +1,199 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_scheduling_add_address.c
+ * @brief test adding addresses in automatic transport selection scheduling API
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr;
+
+/**
+ * Test peer
+ */
+static struct PeerContext p;
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address;
+
+/**
+ * Session
+ */
+static void *test_session;
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[2];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (NULL != sched_ats)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+ free_test_address (&test_addr);
+}
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+ if (0 == stage)
+ {
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with invalid address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 0: Callback with incorrect ats info \n");
+ ret = 1;
+ }
+ stage ++;
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+}
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p.id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p.id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s_full(&p.id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address without session */
+ test_session = NULL;
+ create_test_address (&test_addr, "test", test_session, "test", strlen ("test") + 1);
+ test_hello_address.peer = p.id;
+ test_hello_address.transport_name = test_addr.plugin;
+ test_hello_address.address = test_addr.addr;
+ test_hello_address.address_length = test_addr.addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);
+
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_add_address",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+/* end of file test_ats_api_scheduling_add_address.c */
diff --git a/src/ats/test_ats_api_scheduling_add_session.c b/src/ats/test_ats_api_scheduling_add_session.c
new file mode 100644
index 0000000..9394484
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_add_session.c
@@ -0,0 +1,237 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_scheduling_add_session.c
+ * @brief test adding a session to an existing addresses
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr;
+
+/**
+ * Test peer
+ */
+static struct PeerContext p;
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address;
+
+/**
+ * Session
+ */
+static void *test_session;
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[2];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (NULL != sched_ats)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+ free_test_address (&test_addr);
+}
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+ if (0 == stage)
+ {
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with invalid address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 0: Callback with incorrect ats info \n");
+ ret = 1;
+ }
+ stage ++;
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+
+ /* Adding address with session */
+ test_session = &test_hello_address;
+ create_test_address (&test_addr, "test", test_session, "test", strlen ("test") + 1);
+ test_hello_address.peer = p.id;
+ test_hello_address.transport_name = test_addr.plugin;
+ test_hello_address.address = test_addr.addr;
+ test_hello_address.address_length = test_addr.addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);
+
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+ return;
+ }
+ if (1 == stage)
+ {
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 1: Callback with correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 1: Callback with invalid address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 1: Callback with incorrect ats info \n");
+ ret = 1;
+ }
+ stage ++;
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+}
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p.id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p.id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s_full(&p.id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address without session */
+ test_session = NULL;
+ create_test_address (&test_addr, "test", test_session, "test", strlen ("test") + 1);
+ test_hello_address.peer = p.id;
+ test_hello_address.transport_name = test_addr.plugin;
+ test_hello_address.address = test_addr.addr;
+ test_hello_address.address_length = test_addr.addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);
+
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_add_address",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+/* end of file test_ats_api_scheduling_add_session.c */
diff --git a/src/ats/test_ats_api_scheduling_block_and_reset.c b/src/ats/test_ats_api_scheduling_block_and_reset.c
new file mode 100644
index 0000000..b799a5d
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_block_and_reset.c
@@ -0,0 +1,364 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_scheduling_reset_backoff.c
+ * @brief test case for blocking suggests and blocking reset API
+ * measure duration of initial suggest, measure blocking duration,
+ * reset block, measure suggest, compare time
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+#define WAIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 10)
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+static GNUNET_SCHEDULER_TaskIdentifier wait_task;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr;
+
+/**
+ * Test peer
+ */
+static struct PeerContext p;
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address;
+
+/**
+ * Session
+ */
+static void *test_session;
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[2];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+
+struct GNUNET_TIME_Absolute initial_start;
+
+struct GNUNET_TIME_Relative initial_duration;
+
+/**
+ * Blocking start
+ */
+struct GNUNET_TIME_Absolute block_start;
+
+struct GNUNET_TIME_Relative block_duration;
+
+struct GNUNET_TIME_Absolute reset_block_start;
+
+struct GNUNET_TIME_Relative reset_block_duration;
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ if (wait_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (wait_task);
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (wait_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (wait_task);
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+ free_test_address (&test_addr);
+}
+
+static void
+request_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+ wait_task = GNUNET_SCHEDULER_add_delayed (WAIT, &request_task, NULL);
+}
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %u\n", stage);
+ if (3 == stage)
+ {
+ /* Suggestion after resetting block interval */
+ reset_block_duration = GNUNET_TIME_absolute_get_difference(reset_block_start, GNUNET_TIME_absolute_get());
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Address suggestion after resetting blocking took about %llu ms!\n",
+ (long long unsigned int) reset_block_duration.rel_value);
+ if ((block_duration.rel_value <= (initial_duration.rel_value * 3)) ||
+ (initial_duration.rel_value <= (block_duration.rel_value * 3)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Address suggestion after resetting blocking (%llu ms) took about the same as initial suggestion (%llu ms)\n",
+ (long long unsigned int) reset_block_duration.rel_value,
+ (long long unsigned int) initial_duration.rel_value);
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Address suggestion after resetting blocking (%llu ms) has too big difference to initial suggestion (%llu ms)\n",
+ (long long unsigned int) reset_block_duration.rel_value,
+ (long long unsigned int) initial_duration.rel_value);
+ ret = 1;
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ if (((initial_duration.rel_value * 3) <= block_duration.rel_value ) &&
+ ((reset_block_duration.rel_value * 3) <= block_duration.rel_value))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Address suggestion after resetting blocking (%llu ms) and initial suggestion (%llu ms) much faster than with blocking (%llu ms)\n",
+ (long long unsigned int) reset_block_duration.rel_value,
+ (long long unsigned int) initial_duration.rel_value,
+ (long long unsigned int) block_duration.rel_value);
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Address suggestion after resetting blocking (%llu ms) and initial suggestion (%llu ms) not faster than with blocking (%llu ms)\n",
+ (long long unsigned int) reset_block_duration.rel_value,
+ (long long unsigned int) initial_duration.rel_value,
+ (long long unsigned int) block_duration.rel_value);
+ ret = 1;
+ }
+
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+
+ }
+ if (2 == stage)
+ {
+ /* Suggestion after block*/
+ block_duration = GNUNET_TIME_absolute_get_difference(block_start, GNUNET_TIME_absolute_get());
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Address suggestion was blocked for about %llu ms!\n",
+ (long long unsigned int) block_duration.rel_value);
+
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n", stage,
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with invalid address `%s'\n", stage,
+ GNUNET_i2s (&address->peer));
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n");
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+ }
+ stage ++;
+
+ /* Reset block interval */
+ GNUNET_ATS_reset_backoff (sched_ats, &address->peer);
+ reset_block_start = GNUNET_TIME_absolute_get();
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+ }
+ if (1 == stage)
+ {
+ /* Initial suggestion */
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n", stage,
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with invalid address `%s'\n", stage,
+ GNUNET_i2s (&address->peer));
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n");
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+ }
+ stage ++;
+ initial_duration = GNUNET_TIME_absolute_get_difference(initial_start, GNUNET_TIME_absolute_get());
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %u: Initial suggestion took about %llu ms\n", stage,
+ (long long unsigned int) block_duration.rel_value);
+
+ block_start = GNUNET_TIME_absolute_get();
+ wait_task = GNUNET_SCHEDULER_add_delayed (WAIT, &request_task, NULL);
+ }
+ if (0 == stage)
+ {
+ /* Startup suggestion */
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n", stage,
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with invalid address `%s'\n", stage,
+ GNUNET_i2s (&address->peer));
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n");
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+ }
+ stage ++;
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+
+ initial_start = GNUNET_TIME_absolute_get();
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+ }
+}
+
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p.id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+ GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p.id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s_full(&p.id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address without session */
+ test_session = &test_addr;
+ create_test_address (&test_addr, "test", test_session, "test", strlen ("test") + 1);
+ test_hello_address.peer = p.id;
+ test_hello_address.transport_name = test_addr.plugin;
+ test_hello_address.address = test_addr.addr;
+ test_hello_address.address_length = test_addr.addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);
+
+ initial_start = GNUNET_TIME_absolute_get();
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_add_address",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+/* end of file test_ats_api_scheduling_reset_backoff.c */
diff --git a/src/ats/test_ats_api_scheduling_check_min_bw_alt.c b/src/ats/test_ats_api_scheduling_check_min_bw_alt.c
new file mode 100644
index 0000000..bf23ad2
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_check_min_bw_alt.c
@@ -0,0 +1,417 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_mlp.c
+ * @brief test for the MLP solver
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+
+ */
+/**
+ * @file ats/test_ats_api_scheduling_check_min_bw_alt.c
+ * @brief alternative suggestion on network change if no bw is available
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+#define DEBUG_ATS_INFO GNUNET_NO
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr[2];
+
+/**
+ * Test peer
+ */
+static struct PeerContext p[2];
+
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address[2];
+
+/**
+ * Session
+ */
+static void *test_session[2];
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[2][2];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+/**
+ * Configured WAN out quota
+ */
+unsigned long long wan_quota_out;
+
+/**
+ * Configured WAN in quota
+ */
+unsigned long long wan_quota_in;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr[0]);
+ free_test_address (&test_addr[1]);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+ free_test_address (&test_addr[0]);
+ free_test_address (&test_addr[1]);
+}
+
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+ unsigned int bw_in = ntohl(bandwidth_in.value__);
+ unsigned int bw_out = ntohl(bandwidth_out.value__);
+
+ if (0 == stage)
+ {
+ /* Initial suggestion for 1st address */
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address[0], test_session[0]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n",
+ stage, GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with invalid address `%s'\n",
+ stage, GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info[0], test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n");
+ ret = 1;
+ }
+
+ if (bw_in > wan_quota_in)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Suggested WAN inbound quota %u bigger than allowed quota %llu \n",
+ stage, bw_in, wan_quota_in);
+ ret = 1;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Suggested WAN inbound quota %u, allowed quota %llu \n",
+ stage, bw_in, wan_quota_in);
+
+ if (bw_out > wan_quota_out)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Suggested WAN outbound quota %u bigger than allowed quota %llu \n",
+ stage, bw_out, wan_quota_out);
+ ret = 1;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Suggested WAN outbound quota %u, allowed quota %llu \n",
+ stage, bw_out, wan_quota_out);
+
+ if (1 == ret)
+ {
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ p[0].bw_out_assigned = bw_out;
+ p[0].bw_in_assigned = bw_in;
+ stage ++;
+
+ /* Add a 2nd address to give ATS an suggestion alternative */
+ /* Prepare ATS Information */
+ test_ats_info[1][0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[1][0].value = htonl(GNUNET_ATS_NET_LAN);
+ test_ats_info[1][1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1][1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address with session */
+ test_session[1] = &test_addr[1];
+ create_test_address (&test_addr[1], "test1", test_session[1], "test1", strlen ("test1") + 1);
+ test_hello_address[1].peer = p[0].id;
+ test_hello_address[1].transport_name = test_addr[1].plugin;
+ test_hello_address[1].address = test_addr[1].addr;
+ test_hello_address[1].address_length = test_addr[1].addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address[1], test_session[1],
+ test_ats_info[1], test_ats_count);
+
+
+ /* Changing 1st address to network with now bw available (WLAN) */
+ test_ats_info[0][0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0][0].value = htonl(GNUNET_ATS_NET_WLAN);
+ test_ats_info[0][1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[0][1].value = htonl(1);
+ test_ats_count = 2;
+
+ GNUNET_ATS_address_update (sched_ats, &test_hello_address[0], test_session[0],
+ test_ats_info[0], test_ats_count);
+ return;
+ }
+ if (1 == stage)
+ {
+ /* Bandwidth update to (in/out) 0/0 for 1st address */
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address[0], test_session[0]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n",
+ stage, GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with invalid address `%s'\n",
+ stage, GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info[0], test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n");
+ ret = 1;
+ }
+
+ if ((bw_in != 0) || (bw_out != 0))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: ATS did not set bandwidth to 0 but instead to %u/%u \n",
+ stage, bw_in, wan_quota_in);
+ ret = 1;
+ }
+
+ if (1 == ret)
+ {
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+ p[0].bw_out_assigned = bw_out;
+ p[0].bw_in_assigned = bw_in;
+ stage ++;
+ return;
+ }
+ if (2 == stage)
+ {
+ /* Expecting suggestion of alternative 2nd address*/
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address[1], test_session[1]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n",
+ stage, GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with invalid address `%s'\n",
+ stage, GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info[1], test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n",
+ stage);
+ ret = 1;
+ }
+
+ if ((bw_in == 0) || (bw_out == 0))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: ATS did not set bandwidth correctly \n",
+ stage);
+ ret = 1;
+ }
+
+ if (1 == ret)
+ {
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 0;
+ return;
+ }
+}
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ char *quota_str;
+
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_OUT", &quota_str))
+ {
+ fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n");
+ ret = 1;
+ return;
+ }
+ if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_out))
+ {
+ fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n");
+ ret = 1;
+ GNUNET_free (quota_str);
+ return;
+ }
+ GNUNET_free (quota_str);
+ quota_str = NULL;
+
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_IN", &quota_str))
+ {
+ fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n");
+ ret = 1;
+ return;
+ }
+ if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_in))
+ {
+ fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n");
+ GNUNET_free (quota_str);
+ ret = 1;
+ return;
+ }
+ GNUNET_free (quota_str);
+ quota_str = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN inbound quota: %llu\n", wan_quota_in);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN outbound quota: %llu\n", wan_quota_out);
+
+
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer 0 */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p[0].id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p[0].id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s(&p[0].id));
+
+ /* Set up peer 1*/
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID1, &p[1].id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID1, GNUNET_i2s_full (&p[1].id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s(&p[1].id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0][0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0][0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[0][1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[0][1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address with session */
+ test_session[0] = &test_addr[0];
+ create_test_address (&test_addr[0], "test0", test_session[0], "test0", strlen ("test0") + 1);
+ test_hello_address[0].peer = p[0].id;
+ test_hello_address[0].transport_name = test_addr[0].plugin;
+ test_hello_address[0].address = test_addr[0].addr;
+ test_hello_address[0].address_length = test_addr[0].addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address[0], test_session[0],
+ test_ats_info[0], test_ats_count);
+
+ GNUNET_ATS_suggest_address (sched_ats, &p[0].id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_check_min_bw_alt",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+
+/* end of file test_ats_api_scheduling_check_min_bw_alt.c */
diff --git a/src/ats/test_ats_api_scheduling_destroy_address.c b/src/ats/test_ats_api_scheduling_destroy_address.c
new file mode 100644
index 0000000..93b90da
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_destroy_address.c
@@ -0,0 +1,218 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_scheduling_destroy_address.c
+ * @brief test destroying addresses in automatic transport selection scheduling API
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ *
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+static GNUNET_SCHEDULER_TaskIdentifier wait_task;
+
+#define WAIT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr;
+
+/**
+ * Test peer
+ */
+static struct PeerContext p;
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address;
+
+/**
+ * Session
+ */
+static void *test_session;
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[2];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ if (GNUNET_SCHEDULER_NO_TASK != wait_task)
+ {
+ GNUNET_SCHEDULER_cancel (wait_task);
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ free_test_address (&test_addr);
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+}
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+
+ if (0 ==stage)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Received suggestion for peer `%s'\n",
+ GNUNET_i2s(&address->peer));
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback with correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Callback with invalid address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+ return;
+ }
+ stage ++;
+ ret = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying address for `%s'\n",
+ GNUNET_i2s (&address->peer));
+ /* Destroying address */
+ GNUNET_ATS_address_destroyed (sched_ats, &test_hello_address, test_addr.session);
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+ /* Wait for timeout */
+ wait_task = GNUNET_SCHEDULER_add_delayed (WAIT_TIMEOUT, &end, NULL);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 1: Unexpected address suggestion\n");
+ ret = 1;
+
+}
+
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p.id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s_full(&p.id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address without session */
+ test_session = NULL;
+ create_test_address (&test_addr, "test", test_session, "test", strlen ("test") + 1);
+ test_hello_address.peer = p.id;
+ test_hello_address.transport_name = test_addr.plugin;
+ test_hello_address.address = test_addr.addr;
+ test_hello_address.address_length = test_addr.addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, test_ats_info, 2);
+
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_add_address",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+/* end of file test_ats_api_scheduling_destroy_address.c */
diff --git a/src/ats/test_ats_api_scheduling_destroy_inbound_connection.c b/src/ats/test_ats_api_scheduling_destroy_inbound_connection.c
new file mode 100644
index 0000000..fe98859
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_destroy_inbound_connection.c
@@ -0,0 +1,223 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_scheduling_destroy_inbound_connection.c
+ * @brief test destroying sessions for inbound connections: first add an address with a session,
+ * request the address and compare, delete the session, request and
+ * compare again, delete whole address, request and wait for timeout,
+ * shutdown
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ *
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+static GNUNET_SCHEDULER_TaskIdentifier wait_task;
+
+#define WAIT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr;
+
+/**
+ * Test peer
+ */
+static struct PeerContext p;
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address;
+
+/**
+ * Session
+ */
+static void *test_session;
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[2];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ if (wait_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (wait_task);
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ free_test_address (&test_addr);
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+}
+
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+
+ if (0 == stage)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Received suggestion for peer `%s'\n",
+ GNUNET_i2s(&address->peer));
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with invalid address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+ return;
+ }
+ stage ++;
+ ret = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying address for `%s'\n",
+ GNUNET_i2s (&address->peer));
+ /* Destroying session for address */
+ test_session = NULL;
+ GNUNET_ATS_address_destroyed (sched_ats, &test_hello_address, test_addr.session);
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+
+ /* Wait for timeout */
+ wait_task = GNUNET_SCHEDULER_add_delayed (WAIT_TIMEOUT, &end, NULL);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Unexpected address suggestion\n", stage);
+ ret = 1;
+}
+
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p.id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s_full(&p.id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address with session */
+ create_test_address (&test_addr, "test", &test_addr, NULL, 0);
+ test_session = &test_addr;
+ test_hello_address.peer = p.id;
+ test_hello_address.transport_name = test_addr.plugin;
+ test_hello_address.address = test_addr.addr;
+ test_hello_address.address_length = test_addr.addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_addr.session, test_ats_info, test_ats_count);
+
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_add_address",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+/* end of file test_ats_api_scheduling_destroy_inbound_connection.c */
diff --git a/src/ats/test_ats_api_scheduling_destroy_session.c b/src/ats/test_ats_api_scheduling_destroy_session.c
new file mode 100644
index 0000000..9467bdc
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_destroy_session.c
@@ -0,0 +1,235 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_scheduling_destroy_session.c
+ * @brief test destroying sessions: first add an address with a session,
+ * request the address and compare, delete the session, request and
+ * compare again, delete whole address, request and wait for timeout,
+ * shutdown
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ *
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+static GNUNET_SCHEDULER_TaskIdentifier wait_task;
+
+#define WAIT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr;
+
+/**
+ * Test peer
+ */
+static struct PeerContext p;
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address;
+
+/**
+ * Session
+ */
+static void *test_session;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ if (wait_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (wait_task);
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ free_test_address (&test_addr);
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+}
+
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+
+ if (0 == stage)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Received suggestion for peer `%s'\n",
+ GNUNET_i2s(&address->peer));
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with invalid address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+ return;
+ }
+ stage ++;
+ ret = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying address for `%s'\n",
+ GNUNET_i2s (&address->peer));
+ /* Destroying session for address */
+ test_session = NULL;
+ GNUNET_ATS_address_destroyed (sched_ats, &test_hello_address, test_addr.session);
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+ return;
+ }
+ else if (1 == stage)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 1: Received suggestion for peer `%s'\n",
+ GNUNET_i2s(&address->peer));
+
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 1: Callback with correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 1: Callback with invalid address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+ return;
+ }
+ stage ++;
+ ret = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying address for `%s'\n",
+ GNUNET_i2s (&address->peer));
+ /* Destroying complete address */
+ GNUNET_ATS_address_destroyed (sched_ats, &test_hello_address, session);
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+ wait_task = GNUNET_SCHEDULER_add_delayed (WAIT_TIMEOUT, &end, NULL);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 1: Unexpected address suggestion\n");
+ ret = 1;
+
+}
+
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p.id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s_full(&p.id));
+
+ /* Adding address with session */
+ create_test_address (&test_addr, "test", &test_addr, "test", strlen ("test") + 1);
+ test_session = &test_addr;
+ test_hello_address.peer = p.id;
+ test_hello_address.transport_name = test_addr.plugin;
+ test_hello_address.address = test_addr.addr;
+ test_hello_address.address_length = test_addr.addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_addr.session, NULL, 0);
+
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_add_address",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+/* end of file test_ats_api_scheduling_destroy_session.c */
diff --git a/src/ats/test_ats_api_scheduling_init.c b/src/ats/test_ats_api_scheduling_init.c
new file mode 100644
index 0000000..bd96a4d
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_init.c
@@ -0,0 +1,141 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_scheduling_init.c
+ * @brief test automatic transport selection scheduling API init/shutdown
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ *
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
+#define DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+static GNUNET_SCHEDULER_TaskIdentifier wait_task;
+
+static struct GNUNET_ATS_SchedulingHandle *ats;
+
+static int ret;
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ if (GNUNET_SCHEDULER_NO_TASK != wait_task)
+ {
+ GNUNET_SCHEDULER_cancel (wait_task);
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (ats != NULL)
+ {
+ GNUNET_ATS_scheduling_done (ats);
+ ats = NULL;
+ }
+ ret = 1;
+}
+
+static void
+end_badly_now ()
+{
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
+}
+
+static void
+delay (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ static int v_delay = 5;
+ static int v_cur = 0;
+
+ if (v_cur < v_delay)
+ {
+ wait_task = GNUNET_SCHEDULER_NO_TASK;
+ wait_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &delay, NULL);
+ fprintf (stderr,".");
+ v_cur ++;
+ return;
+ }
+
+ fprintf (stderr,"\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutdown ATS\n");
+ GNUNET_ATS_scheduling_done (ats);
+ ats = NULL;
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ ret = 0;
+}
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *ats,
+ uint32_t ats_count)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Received address without asking for it!\n");
+ end_badly_now ();
+}
+
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ ret = 1;
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Initializing ATS\n");
+ ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to initialize ATS\n");
+ end_badly_now ();
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Waiting for %llu sec\n", (long long unsigned int) DELAY.rel_value);
+ wait_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &delay, NULL);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_init",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+/* end of file test_ats_api_scheduling_init.c */
diff --git a/src/ats/test_ats_api_scheduling_min_bw.c b/src/ats/test_ats_api_scheduling_min_bw.c
new file mode 100644
index 0000000..5a59c23
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_min_bw.c
@@ -0,0 +1,185 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_scheduling_min_bw.c
+ * @brief add in address for a network where quota is below min bw: no suggest expected
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+#define WAIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+static GNUNET_SCHEDULER_TaskIdentifier wait_task;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr;
+
+/**
+ * Test peer
+ */
+static struct PeerContext p;
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address;
+
+/**
+ * Session
+ */
+static void *test_session;
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[2];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (NULL != sched_ats)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+ free_test_address (&test_addr);
+}
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Did not expect suggestion!\n");
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ ret = 1;
+}
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ GNUNET_SCHEDULER_add_now (&end , NULL);
+ return;
+ }
+
+ /* Set up peer */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p.id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ GNUNET_SCHEDULER_add_now (&end , NULL);
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p.id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s_full(&p.id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WLAN); /* WLAN quota is below min bw */
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address without session */
+ test_session = NULL;
+ create_test_address (&test_addr, "test", test_session, "test", strlen ("test") + 1);
+ test_hello_address.peer = p.id;
+ test_hello_address.transport_name = test_addr.plugin;
+ test_hello_address.address = test_addr.addr;
+ test_hello_address.address_length = test_addr.addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);
+
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+
+ ret = 0;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Waiting for wait period for no suggest...\n");
+ wait_task = GNUNET_SCHEDULER_add_delayed (WAIT, &end, NULL);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_add_address",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+/* end of file test_ats_api_scheduling_min_bw.c */
diff --git a/src/ats/test_ats_api_scheduling_update_address.c b/src/ats/test_ats_api_scheduling_update_address.c
new file mode 100644
index 0000000..2f52d64
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_update_address.c
@@ -0,0 +1,247 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_scheduling_update_address.c
+ * @brief test updating an address: add address, get and compare it, update it
+ * get it again and compre
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr;
+
+/**
+ * Test peer
+ */
+static struct PeerContext p;
+
+/**
+ * HELLO test address
+ */
+
+struct GNUNET_HELLO_Address test_hello_address;
+
+/**
+ * Test session
+ */
+static void *test_session;
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[3];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+ free_test_address (&test_addr);
+}
+
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+ if (0 == stage)
+ {
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ if (GNUNET_OK == compare_addresses(address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback for correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 0: Callback with incorrect address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 1;
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 0: Callback with incorrect ats info \n");
+ ret = 1;
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ /* Update address */
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(3);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
+ test_ats_info[1].value = htonl(30);
+ test_ats_count = 2;
+
+ GNUNET_ATS_address_update (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);
+
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+ stage ++;
+ }
+ else if (1 == stage)
+ {
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ if (GNUNET_OK == compare_addresses(address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 1: Callback with correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 1: Callback with incorrect address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 1: Callback with incorrect ats info \n");
+ ret = 1;
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+}
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p.id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p.id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s_full(&p.id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
+ test_ats_info[1].value = htonl(10);
+ test_ats_count = 2;
+
+ /* Adding address without session */
+ test_session = &test_addr;
+ create_test_address (&test_addr, "test", &test_addr, "test", strlen ("test") + 1);
+ test_hello_address.peer = p.id;
+ test_hello_address.transport_name = test_addr.plugin;
+ test_hello_address.address = test_addr.addr;
+ test_hello_address.address_length = test_addr.addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);
+
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_update_address",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+/* end of file test_ats_api_scheduling_update_address.c */
diff --git a/src/ats/test_ats_mlp.c b/src/ats/test_ats_mlp.c
deleted file mode 100644
index c467210..0000000
--- a/src/ats/test_ats_mlp.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 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 ats/test_ats_mlp.c
- * @brief test for the MLP solver
- * @author Christian Grothoff
- * @author Matthias Wachs
-
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_statistics_service.h"
-#include "gnunet_ats_service.h"
-#include "gnunet-service-ats_addresses_mlp.h"
-
-#define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3)
-#define MLP_MAX_ITERATIONS INT_MAX
-
-
-static int ret;
-
-struct GNUNET_STATISTICS_Handle * stats;
-
-struct GNUNET_CONTAINER_MultiHashMap * addresses;
-
-struct GAS_MLP_Handle *mlp;
-
-
-static void
-create_address (struct ATS_Address *addr, char * plugin, int ats_count, struct GNUNET_ATS_Information *ats)
-{
- addr->mlp_information = NULL;
- addr->next = NULL;
- addr->prev = NULL;
- addr->plugin = GNUNET_strdup (plugin);
- addr->ats_count = ats_count;
- addr->ats = ats;
-}
-
-static void
-set_ats (struct GNUNET_ATS_Information *ats, uint32_t type, uint32_t value)
-{
- ats->type = type;
- ats->value = value;
-}
-
-static void
-check (void *cls, char *const *args, const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
-#if !HAVE_LIBGLPK
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!");
- ret = 1;
- return;
-#endif
- struct ATS_Address addr[10];
- struct ATS_PreferedAddress *res[10];
- struct GAS_MLP_SolutionContext ctx;
-
- stats = GNUNET_STATISTICS_create("ats", cfg);
-
- addresses = GNUNET_CONTAINER_multihashmap_create (10);
-
- mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
- mlp->auto_solve = GNUNET_NO;
-
- struct GNUNET_PeerIdentity p[10];
-
- /* Creating peer 1 */
- GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &p[0].hashPubKey);
- /* Creating peer 2 */
- GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &p[1].hashPubKey);
-
- /* Creating peer 1 address 1 */
- addr[0].peer.hashPubKey = p[0].hashPubKey;
- struct GNUNET_ATS_Information a1_ats[3];
- set_ats (&a1_ats[0], GNUNET_ATS_QUALITY_NET_DISTANCE, 1);
- set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 1);
- set_ats (&a1_ats[2], GNUNET_ATS_ARRAY_TERMINATOR, 0);
- create_address (&addr[0], "dummy", 3, &a1_ats[0]);
- addr[0].atsp_network_type = GNUNET_ATS_NET_WAN;
-
- /* Creating peer 1 address 2 */
- addr[1].peer.hashPubKey = p[0].hashPubKey;
- struct GNUNET_ATS_Information a2_ats[3];
- set_ats (&a2_ats[1], GNUNET_ATS_QUALITY_NET_DISTANCE, 1);
- set_ats (&a2_ats[0], GNUNET_ATS_QUALITY_NET_DELAY, 1);
- set_ats (&a2_ats[2], GNUNET_ATS_ARRAY_TERMINATOR, 0);
- create_address (&addr[1], "dummy2", 3, &a2_ats[0]);
- addr[1].atsp_network_type = GNUNET_ATS_NET_LAN;
-
- /* Creating peer 2 address 1 */
- addr[2].peer.hashPubKey = p[1].hashPubKey;
- struct GNUNET_ATS_Information a3_ats[3];
- set_ats (&a3_ats[1], GNUNET_ATS_QUALITY_NET_DISTANCE, 1);
- set_ats (&a3_ats[0], GNUNET_ATS_QUALITY_NET_DELAY, 1);
- set_ats (&a3_ats[2], GNUNET_ATS_ARRAY_TERMINATOR, 0);
- create_address (&addr[2], "dummy3", 3, &a3_ats[0]);
- addr[2].atsp_network_type = GNUNET_ATS_NET_LAN;
-
- GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[0], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
-
- /* Add peer 1 address 1 */
- GAS_mlp_address_update (mlp, addresses, &addr[0]);
-
- GNUNET_assert (mlp != NULL);
- GNUNET_assert (mlp->addr_in_problem == 1);
-
- /* Update an peer 1 address 1 */
- set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 1);
- GAS_mlp_address_update (mlp, addresses, &addr[0]);
- GNUNET_assert (mlp->addr_in_problem == 1);
-
- /* Add peer 1 address 2 */
- GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[1], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- GAS_mlp_address_update (mlp, addresses, &addr[1]);
- GNUNET_assert (mlp->addr_in_problem == 2);
-
- /* Add peer 2 address 1 */
- GNUNET_CONTAINER_multihashmap_put(addresses, &addr[2].peer.hashPubKey, &addr[2], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- GAS_mlp_address_update (mlp, addresses, &addr[2]);
- GNUNET_assert (mlp->addr_in_problem == 3);
-
- GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp, &ctx));
- GNUNET_assert (GNUNET_OK == ctx.lp_result);
- GNUNET_assert (GNUNET_OK == ctx.mlp_result);
-
- res[0] = GAS_mlp_get_preferred_address(mlp, addresses, &p[0]);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Preferred address `%s' outbound bandwidth: %u Bps\n",res[0]->address->plugin, res[0]->bandwidth_out);
- res[1] = GAS_mlp_get_preferred_address(mlp, addresses, &p[1]);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Preferred address `%s' outbound bandwidth: %u Bps\n",res[1]->address->plugin, res[1]->bandwidth_out);
-
- /* Delete an address */
- GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[0].peer.hashPubKey, &addr[0]);
- GAS_mlp_address_delete (mlp, addresses, &addr[0]);
- GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[1].peer.hashPubKey, &addr[1]);
- GAS_mlp_address_delete (mlp, addresses, &addr[1]);
- GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[2].peer.hashPubKey, &addr[2]);
- GAS_mlp_address_delete (mlp, addresses, &addr[2]);
-
- GNUNET_assert (mlp->addr_in_problem == 0);
-
- GAS_mlp_done (mlp);
-
- GNUNET_free (addr[0].plugin);
- GNUNET_free (addr[1].plugin);
- GNUNET_CONTAINER_multihashmap_destroy (addresses);
- GNUNET_STATISTICS_destroy(stats, GNUNET_NO);
-
- ret = 0;
- return;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-
- static char *const argv2[] = { "test_ats_mlp",
- "-c",
- "test_ats_api.conf",
- "-L", "WARNING",
- NULL
- };
-
- static struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
-
- GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
- "test_ats_mlp", "nohelp", options,
- &check, NULL);
-
-
- return ret;
-}
-
-/* end of file test_ats_api_bandwidth_consumption.c */
diff --git a/src/ats/test_ats_mlp_averaging.c b/src/ats/test_ats_mlp_averaging.c
deleted file mode 100644
index 97e9aa7..0000000
--- a/src/ats/test_ats_mlp_averaging.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 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 ats/test_ats_mlp.c
- * @brief test for the MLP solver
- * @author Christian Grothoff
- * @author Matthias Wachs
-
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_statistics_service.h"
-#include "gnunet_ats_service.h"
-#include "gnunet-service-ats_addresses_mlp.h"
-
-#define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3)
-#define MLP_MAX_ITERATIONS INT_MAX
-
-
-static int ret;
-
-struct GNUNET_STATISTICS_Handle * stats;
-
-struct GNUNET_CONTAINER_MultiHashMap * addresses;
-
-struct GAS_MLP_Handle *mlp;
-
-
-static void
-create_address (struct ATS_Address *addr, char * plugin, int ats_count, struct GNUNET_ATS_Information *ats)
-{
- addr->mlp_information = NULL;
- addr->next = NULL;
- addr->prev = NULL;
- addr->plugin = GNUNET_strdup (plugin);
- addr->ats_count = ats_count;
- addr->ats = ats;
-}
-
-static void
-set_ats (struct GNUNET_ATS_Information *ats, uint32_t type, uint32_t value)
-{
- ats->type = type;
- ats->value = value;
-}
-
-static void
-check (void *cls, char *const *args, const char *cfgfile,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
-#if !HAVE_LIBGLPK
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!");
- ret = 1;
- return;
-#endif
- struct ATS_Address addr[10];
- struct ATS_PreferedAddress *res[10];
- struct MLP_information *mlpi;
- struct GAS_MLP_SolutionContext ctx;
-
- stats = GNUNET_STATISTICS_create("ats", cfg);
-
- addresses = GNUNET_CONTAINER_multihashmap_create (10);
-
- mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
- mlp->auto_solve = GNUNET_NO;
-
- struct GNUNET_PeerIdentity p[10];
-
- /* Creating peer 1 */
- GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &p[0].hashPubKey);
-
- /* Creating peer 1 address 1 */
- addr[0].peer.hashPubKey = p[0].hashPubKey;
- struct GNUNET_ATS_Information a1_ats[3];
- set_ats (&a1_ats[0], GNUNET_ATS_QUALITY_NET_DISTANCE, 1);
- set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 0);
- set_ats (&a1_ats[2], GNUNET_ATS_ARRAY_TERMINATOR, 0);
- create_address (&addr[0], "dummy", 3, &a1_ats[0]);
- addr[0].atsp_network_type = GNUNET_ATS_NET_LAN;
-
- GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[0], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
-
- /* Add peer 1 address 1 */
- GAS_mlp_address_update (mlp, addresses, &addr[0]);
- mlpi = addr[0].mlp_information;
-
- GNUNET_assert (mlp != NULL);
- GNUNET_assert (mlp->addr_in_problem == 1);
-
- /* Update an peer 1 address 1 */
- set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 20);
- GAS_mlp_address_update (mlp, addresses, &addr[0]);
- GNUNET_assert (mlp->addr_in_problem == 1);
-
-
- /* Update an peer 1 address 1 */
- set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 10);
- GAS_mlp_address_update (mlp, addresses, &addr[0]);
- GNUNET_assert (mlp->addr_in_problem == 1);
-
- /* Update an peer 1 address 1 */
- set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 10);
- GAS_mlp_address_update (mlp, addresses, &addr[0]);
- GNUNET_assert (mlp->addr_in_problem == 1);
-
- /* Update an peer 1 address 1 */
- set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 30);
- GAS_mlp_address_update (mlp, addresses, &addr[0]);
- GNUNET_assert (mlp->addr_in_problem == 1);
-
-
- GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp, &ctx));
- GNUNET_assert (GNUNET_OK == ctx.lp_result);
- GNUNET_assert (GNUNET_OK == ctx.mlp_result);
-
- res[0] = GAS_mlp_get_preferred_address(mlp, addresses, &p[0]);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Preferred address `%s' outbound bandwidth: %u Bps\n",res[0]->address->plugin, res[0]->bandwidth_out);
- GNUNET_free (res[0]);
-
- /* Delete an address */
- GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[0].peer.hashPubKey, &addr[0]);
- GAS_mlp_address_delete (mlp, addresses, &addr[0]);
-
- GNUNET_assert (mlp->addr_in_problem == 0);
-
- GAS_mlp_done (mlp);
-
- GNUNET_free (addr[0].plugin);
- GNUNET_CONTAINER_multihashmap_destroy (addresses);
- GNUNET_STATISTICS_destroy(stats, GNUNET_NO);
-
- ret = 0;
- return;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-
- static char *const argv2[] = { "test_ats_mlp",
- "-c",
- "test_ats_api.conf",
- "-L", "WARNING",
- NULL
- };
-
- static struct GNUNET_GETOPT_CommandLineOption options[] = {
- GNUNET_GETOPT_OPTION_END
- };
-
- GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
- "test_ats_mlp", "nohelp", options,
- &check, NULL);
-
-
- return ret;
-}
-
-/* end of file test_ats_api_bandwidth_consumption.c */
diff --git a/src/ats/test_ats_simplistic.c b/src/ats/test_ats_simplistic.c
new file mode 100644
index 0000000..b11ae4e
--- /dev/null
+++ b/src/ats/test_ats_simplistic.c
@@ -0,0 +1,380 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_mlp.c
+ * @brief test for the MLP solver
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+
+ */
+/**
+ * @file ats/test_ats_api_scheduling_add_address.c
+ * @brief test for ats simplistic solver
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+#define DEBUG_ATS_INFO GNUNET_NO
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr[2];
+
+/**
+ * Test peer
+ */
+static struct PeerContext p[2];
+
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address[2];
+
+/**
+ * Session
+ */
+static void *test_session[2];
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[2];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+/**
+ * Configured WAN out quota
+ */
+unsigned long long wan_quota_out;
+
+/**
+ * Configured WAN in quota
+ */
+unsigned long long wan_quota_in;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr[0]);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+ free_test_address (&test_addr[0]);
+}
+
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+ unsigned int bw_in = ntohl(bandwidth_in.value__);
+ unsigned int bw_out = ntohl(bandwidth_out.value__);
+ if (0 == stage)
+ {
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address[0], test_session[0]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 0: Callback with invalid address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 0: Callback with incorrect ats info \n");
+ ret = 1;
+ }
+
+ if (bw_in > wan_quota_in)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN inbound quota %u bigger than allowed quota %llu \n",
+ bw_in, wan_quota_in);
+ ret = 1;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN inbound quota %u, allowed quota %llu \n",
+ bw_in, wan_quota_in);
+
+ if (bw_out > wan_quota_out)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN outbound quota %u bigger than allowed quota %llu \n",
+ bw_out, wan_quota_out);
+ ret = 1;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN outbound quota %u, allowed quota %llu \n",
+ bw_out, wan_quota_out);
+
+ if (1 == ret)
+ {
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+ p[0].bw_out_assigned = bw_out;
+ p[0].bw_in_assigned = bw_in;
+ stage ++;
+
+ /* Add a 2nd address */
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address with session */
+ test_session[1] = &test_addr[1];
+ create_test_address (&test_addr[1], "test1", test_session[1], "test1", strlen ("test1") + 1);
+ test_hello_address[1].peer = p[1].id;
+ test_hello_address[1].transport_name = test_addr[1].plugin;
+ test_hello_address[1].address = test_addr[1].addr;
+ test_hello_address[1].address_length = test_addr[1].addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address[1], test_session[1], test_ats_info, test_ats_count);
+ }
+ if (1 == stage)
+ {
+ /* Expecting callback for address[0] with updated quota and no callback for address[1]*/
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address[0], test_session[0]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 1: Callback with correct address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage 1: Callback with invalid address `%s'\n",
+ GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage 1: Callback with incorrect ats info \n");
+ ret = 1;
+ }
+
+ if (bw_in > wan_quota_in)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN inbound quota %u bigger than allowed quota %llu \n",
+ bw_in, wan_quota_in);
+ ret = 1;
+ }
+ else if (p[0].bw_in_assigned > bw_in)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN inbound quota %u bigger than last quota %llu \n",
+ bw_in, p[0].bw_in_assigned);
+ ret = 1;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN inbound quota %u, allowed quota %llu \n",
+ bw_in, wan_quota_in);
+
+ if (bw_out > wan_quota_out)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN outbound quota %u bigger than allowed quota %llu \n",
+ bw_out, wan_quota_out);
+ ret = 1;
+ }
+ else if (p[0].bw_out_assigned > bw_out)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN inbound quota %u bigger than last quota %llu \n",
+ bw_out, p[0].bw_out_assigned);
+ ret = 1;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN outbound quota %u, allowed quota %llu \n",
+ bw_out, wan_quota_out);
+
+ if (1 == ret)
+ {
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+ stage ++;
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+}
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ char *quota_str;
+
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_OUT", &quota_str))
+ {
+ fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n");
+ ret = 1;
+ return;
+ }
+ if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_out))
+ {
+ fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n");
+ ret = 1;
+ GNUNET_free (quota_str);
+ return;
+ }
+ GNUNET_free (quota_str);
+ quota_str = NULL;
+
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_IN", &quota_str))
+ {
+ fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n");
+ ret = 1;
+ return;
+ }
+ if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_in))
+ {
+ fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n");
+ GNUNET_free (quota_str);
+ ret = 1;
+ return;
+ }
+ GNUNET_free (quota_str);
+ quota_str = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN inbound quota: %llu\n", wan_quota_in);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN outbound quota: %llu\n", wan_quota_out);
+
+
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer 0 */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p[0].id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p[0].id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s(&p[0].id));
+
+ /* Set up peer 1*/
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID1, &p[1].id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID1, GNUNET_i2s_full (&p[1].id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s(&p[1].id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address with session */
+ test_session[0] = &test_addr[0];
+ create_test_address (&test_addr[0], "test0", test_session[0], "test0", strlen ("test0") + 1);
+ test_hello_address[0].peer = p[0].id;
+ test_hello_address[0].transport_name = test_addr[0].plugin;
+ test_hello_address[0].address = test_addr[0].addr;
+ test_hello_address[0].address_length = test_addr[0].addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address[0], test_session[0], test_ats_info, test_ats_count);
+
+ GNUNET_ATS_suggest_address (sched_ats, &p[0].id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_simplististic",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+
+/* end of file test_ats_api_bandwidth_consumption.c */
diff --git a/src/ats/test_ats_simplistic_change_preference.c b/src/ats/test_ats_simplistic_change_preference.c
new file mode 100644
index 0000000..793d0cb
--- /dev/null
+++ b/src/ats/test_ats_simplistic_change_preference.c
@@ -0,0 +1,418 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_mlp.c
+ * @brief test for the MLP solver
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+
+ */
+/**
+ * @file ats/test_ats_simplistic_change_preference.c
+ * @brief test for changing preferences in ats simplistic solver
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+#define DEBUG_ATS_INFO GNUNET_NO
+
+#define SLEEP GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_PerformanceHandle *perf_ats;
+
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr[2];
+
+/**
+ * Test peer
+ */
+static struct PeerContext p[2];
+
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address[2];
+
+/**
+ * Session
+ */
+static void *test_session[2];
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[2];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+/**
+ * Configured WAN out quota
+ */
+unsigned long long wan_quota_out;
+
+/**
+ * Configured WAN in quota
+ */
+unsigned long long wan_quota_in;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ if (perf_ats != NULL)
+ GNUNET_ATS_performance_done (perf_ats);
+ free_test_address (&test_addr[0]);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_ATS_performance_done (perf_ats);
+ perf_ats = NULL;
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+ free_test_address (&test_addr[0]);
+}
+
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+ unsigned int bw_in = ntohl(bandwidth_in.value__);
+ unsigned int bw_out = ntohl(bandwidth_out.value__);
+ if (0 == stage)
+ {
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address[0], test_session[0]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n",
+ stage,
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with invalid address `%s'\n",
+ stage,
+ GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n",
+ stage);
+ ret = 1;
+ }
+
+ if (bw_in > wan_quota_in)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN inbound quota %u bigger than allowed quota %llu \n",
+ bw_in, wan_quota_in);
+ ret = 1;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN inbound quota %u, allowed quota %llu \n",
+ bw_in, wan_quota_in);
+
+ if (bw_out > wan_quota_out)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN outbound quota %u bigger than allowed quota %llu \n",
+ bw_out, wan_quota_out);
+ ret = 1;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN outbound quota %u, allowed quota %llu \n",
+ bw_out, wan_quota_out);
+
+ if (1 == ret)
+ {
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ stage ++;
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
+ GNUNET_ATS_suggest_address (sched_ats, &p[1].id);
+ return;
+ }
+ if (1 == stage)
+ {
+ if (GNUNET_OK == compare_addresses (address, session, &test_hello_address[1], test_session[1]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n",
+ stage,
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with invalid address `%s'\n",
+ stage,
+ GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n",
+ stage);
+ ret = 1;
+ }
+
+ if (bw_in > wan_quota_in)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN inbound quota %u bigger than allowed quota %llu \n",
+ bw_in, wan_quota_in);
+ ret = 1;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN inbound quota %u, allowed quota %llu \n",
+ bw_in, wan_quota_in);
+
+ if (bw_out > wan_quota_out)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Suggested WAN outbound quota %u bigger than allowed quota %llu \n",
+ bw_out, wan_quota_out);
+ ret = 1;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Suggested WAN outbound quota %u, allowed quota %llu \n",
+ bw_out, wan_quota_out);
+
+ if (1 == ret)
+ {
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ stage ++;
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[1].id);
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+
+ return;
+ }
+}
+
+static void
+sleep_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ GNUNET_ATS_suggest_address (sched_ats, &p[0].id);
+}
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ char *quota_str;
+
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_OUT", &quota_str))
+ {
+ fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n");
+ ret = 1;
+ return;
+ }
+ if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_out))
+ {
+ fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n");
+ ret = 1;
+ GNUNET_free (quota_str);
+ return;
+ }
+ GNUNET_free (quota_str);
+ quota_str = NULL;
+
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_IN", &quota_str))
+ {
+ fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n");
+ ret = 1;
+ return;
+ }
+ if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_in))
+ {
+ fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n");
+ GNUNET_free (quota_str);
+ ret = 1;
+ return;
+ }
+ GNUNET_free (quota_str);
+ quota_str = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN inbound quota: %llu\n", wan_quota_in);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN outbound quota: %llu\n", wan_quota_out);
+
+
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ perf_ats = GNUNET_ATS_performance_init (cfg, NULL, NULL);
+ if (perf_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS performance!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer 0 */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p[0].id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p[0].id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s(&p[0].id));
+
+
+ /* Set up peer 0 */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID1, &p[1].id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID1, GNUNET_i2s_full (&p[1].id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s(&p[1].id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Adding address with session */
+ test_session[0] = &test_addr[0];
+ create_test_address (&test_addr[0], "test0", test_session[0], "test0", strlen ("test0") + 1);
+ test_hello_address[0].peer = p[0].id;
+ test_hello_address[0].transport_name = test_addr[0].plugin;
+ test_hello_address[0].address = test_addr[0].addr;
+ test_hello_address[0].address_length = test_addr[0].addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address[0], test_session[0], test_ats_info, test_ats_count);
+
+
+ /* Adding address with session */
+ test_session[1] = &test_addr[1];
+ create_test_address (&test_addr[1], "test1", test_session[1], "test1", strlen ("test1") + 1);
+ test_hello_address[1].peer = p[1].id;
+ test_hello_address[1].transport_name = test_addr[0].plugin;
+ test_hello_address[1].address = test_addr[0].addr;
+ test_hello_address[1].address_length = test_addr[0].addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address[1], test_session[1], test_ats_info, test_ats_count);
+
+
+ /* Change bandwidth preference */
+ GNUNET_ATS_change_preference (perf_ats,
+ &p[0].id,
+ GNUNET_ATS_PREFERENCE_BANDWIDTH,(double) 1000, GNUNET_ATS_PREFERENCE_END);
+ GNUNET_ATS_change_preference (perf_ats,
+ &p[1].id,
+ GNUNET_ATS_PREFERENCE_BANDWIDTH,(double) 1000, GNUNET_ATS_PREFERENCE_END);
+
+
+ /* Change latency preference */
+
+ GNUNET_ATS_change_preference (perf_ats,
+ &p[0].id,
+ GNUNET_ATS_PREFERENCE_LATENCY,(double) 10, GNUNET_ATS_PREFERENCE_END);
+ GNUNET_ATS_change_preference (perf_ats,
+ &p[1].id,
+ GNUNET_ATS_PREFERENCE_LATENCY,(double) 100, GNUNET_ATS_PREFERENCE_END);
+ GNUNET_SCHEDULER_add_delayed (SLEEP, &sleep_task, NULL);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_simplistic_change_preference",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+
+/* end of file test_ats_simplistic_change_preference.c */
diff --git a/src/ats/test_ats_simplistic_pref_aging.c b/src/ats/test_ats_simplistic_pref_aging.c
new file mode 100644
index 0000000..8591ef1
--- /dev/null
+++ b/src/ats/test_ats_simplistic_pref_aging.c
@@ -0,0 +1,448 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_mlp.c
+ * @brief test for the MLP solver
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+
+ */
+/**
+ * @file ats/test_ats_api_scheduling_add_address.c
+ * @brief test for ats simplistic solver preference aging:
+ * Add 2 addresses and set high preference for one. Expect higher bw for this
+ * address, wait. Preferences should age and so bw assigned should decrease.
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+#define DEBUG_ATS_INFO GNUNET_NO
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Performance handle
+ */
+static struct GNUNET_ATS_PerformanceHandle *perf_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr[2];
+
+/**
+ * Test peer
+ */
+static struct PeerContext p[2];
+
+
+/**
+ * HELLO address
+ */
+struct GNUNET_HELLO_Address test_hello_address[2];
+
+/**
+ * Session
+ */
+static void *test_session[2];
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[2];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+/**
+ * Configured WAN out quota
+ */
+unsigned long long wan_quota_out;
+
+/**
+ * Configured WAN in quota
+ */
+unsigned long long wan_quota_in;
+
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (sched_ats != NULL)
+ {
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+ }
+ if (perf_ats != NULL)
+ {
+ GNUNET_ATS_performance_done (perf_ats);
+ perf_ats = NULL;
+ }
+ free_test_address (&test_addr[0]);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[0].id);
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p[1].id);
+
+ if (NULL != sched_ats)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ if (NULL != perf_ats)
+ GNUNET_ATS_performance_done (perf_ats);
+ sched_ats = NULL;
+ perf_ats = NULL;
+ free_test_address (&test_addr[0]);
+ free_test_address (&test_addr[1]);
+}
+
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+ static int sug_p0 = GNUNET_NO;
+ static int sug_p1 = GNUNET_NO;
+
+ static uint32_t p0_last_bandwidth_out;
+ static uint32_t p0_last_bandwidth_in;
+
+ static uint32_t p1_last_bandwidth_out;
+ static uint32_t p1_last_bandwidth_in;
+
+ uint32_t cur_bandwidth_out = ntohl (bandwidth_out.value__);
+ uint32_t cur_bandwidth_in = ntohl (bandwidth_in.value__);
+
+ if (0 == stage)
+ {
+ /* Callback for initial suggestion */
+ if (0 == memcmp (&address->peer, &p[0].id, sizeof (p[0].id)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %u: Callback for peer 0 `%s': (in/out) %llu/%llu\n",
+ stage,
+ GNUNET_i2s (&address->peer),
+ ntohl (bandwidth_in.value__),
+ ntohl (bandwidth_out.value__));
+ sug_p0 = GNUNET_YES;
+ p0_last_bandwidth_out = ntohl(bandwidth_out.value__);
+ p0_last_bandwidth_in = ntohl(bandwidth_in.value__);
+ }
+ if (0 == memcmp (&address->peer, &p[1].id, sizeof (p[1].id)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %u: Callback for peer 1 `%s': (in/out) %llu/%llu\n",
+ stage,
+ GNUNET_i2s (&address->peer),
+ ntohl (bandwidth_in.value__),
+ ntohl (bandwidth_out.value__));
+ sug_p1 = GNUNET_YES;
+ p1_last_bandwidth_out = ntohl(bandwidth_out.value__);
+ p1_last_bandwidth_in = ntohl(bandwidth_in.value__);
+ }
+ if ((GNUNET_YES == sug_p0) && (GNUNET_YES == sug_p1))
+ {
+ /* Changing preference for peer 0 */
+ stage ++;
+ GNUNET_ATS_change_preference (perf_ats, &p[0].id, GNUNET_ATS_PREFERENCE_BANDWIDTH,(double) 1000, GNUNET_ATS_PREFERENCE_END);
+ sug_p0 = GNUNET_NO;
+ sug_p1 = GNUNET_NO;
+ return;
+ }
+
+ }
+ if (1 == stage)
+ {
+ /* Callback due to preference change */
+ if (0 == memcmp (&address->peer, &p[0].id, sizeof (p[0].id)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %u: Callback for peer 0 `%s': (in/out) %llu/%llu\n",
+ stage,
+ GNUNET_i2s (&address->peer),
+ ntohl (bandwidth_in.value__),
+ ntohl (bandwidth_out.value__));
+ sug_p0 = GNUNET_YES;
+
+ /* Peer 0 should get more bandwidth */
+ if (cur_bandwidth_out <= p0_last_bandwidth_out)
+ GNUNET_break (0);
+ if (cur_bandwidth_in <= p0_last_bandwidth_in)
+ GNUNET_break (0);
+ p0_last_bandwidth_out = ntohl(bandwidth_out.value__);
+ p0_last_bandwidth_in = ntohl(bandwidth_in.value__);
+ }
+ if (0 == memcmp (&address->peer, &p[1].id, sizeof (p[1].id)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %u: Callback for peer 1 `%s': (in/out) %llu/%llu\n",
+ stage,
+ GNUNET_i2s (&address->peer),
+ ntohl (bandwidth_in.value__),
+ ntohl (bandwidth_out.value__));
+ sug_p1 = GNUNET_YES;
+
+ /* Peer 1 should get less bandwidth */
+ if (cur_bandwidth_out >= p1_last_bandwidth_out)
+ {
+ GNUNET_break (0);
+ goto error;
+ }
+ if (cur_bandwidth_in >= p1_last_bandwidth_in)
+ {
+ GNUNET_break (0);
+ goto error;
+ }
+ p1_last_bandwidth_out = ntohl(bandwidth_out.value__);
+ p1_last_bandwidth_in = ntohl(bandwidth_in.value__);
+ }
+ if ((GNUNET_YES == sug_p0) && (GNUNET_YES == sug_p1))
+ {
+ stage ++;
+ sug_p0 = GNUNET_NO;
+ sug_p1 = GNUNET_NO;
+ return;
+ }
+ }
+ if (2 == stage)
+ {
+ /* Callback due to preference aging */
+ if (0 == memcmp (&address->peer, &p[0].id, sizeof (p[0].id)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %u: Callback for peer 0 `%s': (in/out) %llu/%llu\n",
+ stage,
+ GNUNET_i2s (&address->peer),
+ ntohl (bandwidth_in.value__),
+ ntohl (bandwidth_out.value__));
+ sug_p0 = GNUNET_YES;
+
+ /* Peer 0 should get less bandwidth */
+ if (cur_bandwidth_out <= p0_last_bandwidth_out)
+ GNUNET_break (0);
+ if (cur_bandwidth_in <= p0_last_bandwidth_in)
+ GNUNET_break (0);
+ p0_last_bandwidth_out = ntohl(bandwidth_out.value__);
+ p0_last_bandwidth_in = ntohl(bandwidth_in.value__);
+ }
+ if (0 == memcmp (&address->peer, &p[1].id, sizeof (p[1].id)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Stage %u: Callback for peer 1 `%s': (in/out) %llu/%llu\n",
+ stage,
+ GNUNET_i2s (&address->peer),
+ ntohl (bandwidth_in.value__),
+ ntohl (bandwidth_out.value__));
+ sug_p1 = GNUNET_YES;
+ /* Peer 1 should get more bandwidth */
+ if (cur_bandwidth_out <= p1_last_bandwidth_out)
+ {
+ GNUNET_break (0);
+ goto error;
+ }
+ if (cur_bandwidth_in <= p1_last_bandwidth_in)
+ {
+ GNUNET_break (0);
+ goto error;
+ }
+ p0_last_bandwidth_out = ntohl(bandwidth_out.value__);
+ p0_last_bandwidth_in = ntohl(bandwidth_in.value__);
+ }
+
+ if ((GNUNET_YES == sug_p0) && (GNUNET_YES == sug_p1))
+ {
+ /* Done ! */
+ stage ++;
+ ret = 0;
+ GNUNET_SCHEDULER_add_now (&end,NULL);
+ return;
+ }
+ }
+ return;
+
+error:
+ /* Error ! */
+ ret = 1;
+ GNUNET_SCHEDULER_add_now (&end,NULL);
+}
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ char *quota_str;
+
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_OUT", &quota_str))
+ {
+ fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n");
+ ret = 1;
+ return;
+ }
+ if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_out))
+ {
+ fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n");
+ ret = 1;
+ GNUNET_free (quota_str);
+ return;
+ }
+ GNUNET_free (quota_str);
+ quota_str = NULL;
+
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_IN", &quota_str))
+ {
+ fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n");
+ ret = 1;
+ return;
+ }
+ if (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_in))
+ {
+ fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n");
+ GNUNET_free (quota_str);
+ ret = 1;
+ return;
+ }
+ GNUNET_free (quota_str);
+ quota_str = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN inbound quota: %llu\n", wan_quota_in);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN outbound quota: %llu\n", wan_quota_out);
+
+
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Connect to ATS performance */
+ perf_ats = GNUNET_ATS_performance_init(cfg, NULL, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+
+ /* Set up peer 0 */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p[0].id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p[0].id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s(&p[0].id));
+
+ /* Set up peer 1*/
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID1, &p[1].id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID1, GNUNET_i2s_full (&p[1].id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s(&p[1].id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_count = 2;
+
+ /* Peer 0: Adding address with session */
+ test_session[0] = &test_addr[0];
+ create_test_address (&test_addr[0], "test0", test_session[0], "test0", strlen ("test0") + 1);
+ test_hello_address[0].peer = p[0].id;
+ test_hello_address[0].transport_name = test_addr[0].plugin;
+ test_hello_address[0].address = test_addr[0].addr;
+ test_hello_address[0].address_length = test_addr[0].addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address[0], test_session[0], test_ats_info, test_ats_count);
+
+ /* Peer 1: Adding address with session */
+ test_session[1] = &test_addr[1];
+ create_test_address (&test_addr[1], "test1", test_session[1], "test1", strlen ("test1") + 1);
+ test_hello_address[1].peer = p[1].id;
+ test_hello_address[1].transport_name = test_addr[1].plugin;
+ test_hello_address[1].address = test_addr[1].addr;
+ test_hello_address[1].address_length = test_addr[1].addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address[1], test_session[1], test_ats_info, test_ats_count);
+
+ GNUNET_ATS_suggest_address (sched_ats, &p[0].id);
+ GNUNET_ATS_suggest_address (sched_ats, &p[1].id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_simplistic_pref_aging",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+
+/* end of file test_ats_simplistic_pref_aging.c */
diff --git a/src/ats/test_ats_simplistic_switch_networks.c b/src/ats/test_ats_simplistic_switch_networks.c
new file mode 100644
index 0000000..47a4e44
--- /dev/null
+++ b/src/ats/test_ats_simplistic_switch_networks.c
@@ -0,0 +1,451 @@
+/*
+ This file is part of GNUnet.
+ (C) 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 ats/test_ats_api_scheduling_update_address.c
+ * @brief test updating networtk type of an address
+ * @author Christian Grothoff
+ * @author Matthias Wachs
+ */
+#include "platform.h"
+#include "gnunet_ats_service.h"
+#include "gnunet_testing_lib.h"
+#include "ats.h"
+#include "test_ats_api_common.h"
+
+#define BIG_M_STRING "unlimited"
+
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+/**
+ * Scheduling handle
+ */
+static struct GNUNET_ATS_SchedulingHandle *sched_ats;
+
+/**
+ * Return value
+ */
+static int ret;
+
+/**
+ * Test address
+ */
+static struct Test_Address test_addr;
+
+/**
+ * Test peer
+ */
+static struct PeerContext p;
+
+/**
+ * HELLO test address
+ */
+
+struct GNUNET_HELLO_Address test_hello_address;
+
+/**
+ * Test session
+ */
+static void *test_session;
+
+/**
+ * Test ats info
+ */
+struct GNUNET_ATS_Information test_ats_info[3];
+
+/**
+ * Test ats count
+ */
+uint32_t test_ats_count;
+
+unsigned long long int quota_out[GNUNET_ATS_NetworkTypeCount];
+unsigned long long int quota_in[GNUNET_ATS_NetworkTypeCount];
+
+static void
+end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (sched_ats != NULL)
+ GNUNET_ATS_scheduling_done (sched_ats);
+ free_test_address (&test_addr);
+ ret = GNUNET_SYSERR;
+}
+
+
+static void
+end ()
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
+ if (die_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (die_task);
+ die_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_ATS_scheduling_done (sched_ats);
+ sched_ats = NULL;
+ free_test_address (&test_addr);
+}
+
+static uint32_t
+find_ats_value (const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count,
+ uint32_t value)
+{
+ int c;
+ for (c = 0; c < ats_count; c ++)
+ {
+ if (ntohl(atsi[c].type) == value)
+ return ntohl (atsi[c].value);
+ }
+ GNUNET_break (0);
+ return UINT32_MAX;
+}
+
+
+static void
+address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
+ const struct GNUNET_ATS_Information *atsi,
+ uint32_t ats_count)
+{
+ static int stage = 0;
+ int level;
+ char *text;
+ if (0 == stage)
+ {
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ if (GNUNET_OK == compare_addresses(address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback for correct address `%s'\n",
+ stage, GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect address `%s'\n",
+ stage, GNUNET_i2s (&address->peer));
+ ret = 1;
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n", stage);
+ ret = 1;
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ if (ntohl(bandwidth_out.value__) == quota_out[GNUNET_ATS_NET_WAN])
+ {
+ level = GNUNET_ERROR_TYPE_DEBUG;
+ text = "correct";
+ ret = 0;
+ }
+ else
+ {
+ level = GNUNET_ERROR_TYPE_ERROR;
+ text = "wrong";
+ ret = 1;
+ }
+
+ GNUNET_log (level, "Stage %u: WAN outbound quota out %s: Received %llu, configured %llu\n",
+ stage,
+ text,
+ (unsigned long long int) ntohl(bandwidth_out.value__),
+ quota_out[GNUNET_ATS_NET_WAN]);
+
+ if (ntohl(bandwidth_in.value__) == quota_in[GNUNET_ATS_NET_WAN])
+ {
+ level = GNUNET_ERROR_TYPE_DEBUG;
+ text = "correct";
+ ret = 0;
+ }
+ else
+ {
+ level = GNUNET_ERROR_TYPE_ERROR;
+ text = "wrong";
+ ret = 1;
+ }
+
+ GNUNET_log (level, "Stage %u: WAN inbound quota out %s: Received %llu, configured %llu\n",
+ stage,
+ text,
+ (unsigned long long int) ntohl(bandwidth_out.value__),
+ quota_out[GNUNET_ATS_NET_WAN]);
+
+ if (GNUNET_ATS_NET_WAN != find_ats_value (atsi, ats_count, GNUNET_ATS_NETWORK_TYPE))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Incorrect network type, exptected %s, got %s \n",
+ stage,
+ GNUNET_ATS_print_network_type(GNUNET_ATS_NET_WAN),
+ GNUNET_ATS_print_network_type(find_ats_value (atsi, ats_count, GNUNET_ATS_NETWORK_TYPE)));
+ ret = 1;
+ }
+
+ if (1 == ret)
+ {
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ /* Update address */
+ /* Prepare ATS Information: change network */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_LAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(3);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
+ test_ats_info[1].value = htonl(30);
+ test_ats_count = 2;
+
+ GNUNET_ATS_address_update (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);
+
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+ stage ++;
+ }
+ else if (1 == stage)
+ {
+ GNUNET_ATS_suggest_address_cancel (sched_ats, &p.id);
+ if (GNUNET_OK == compare_addresses(address, session, &test_hello_address, test_session))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stage %u: Callback with correct address `%s'\n", stage,
+ GNUNET_i2s (&address->peer));
+ ret = 0;
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect address `%s'\n", stage,
+ GNUNET_i2s (&address->peer));
+ ret = 1;
+ }
+
+ if (GNUNET_OK != compare_ats(atsi, ats_count, test_ats_info, test_ats_count))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Callback with incorrect ats info \n");
+ ret = 1;
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ return;
+ }
+
+ if (ntohl(bandwidth_out.value__) == quota_out[GNUNET_ATS_NET_LAN])
+ {
+ level = GNUNET_ERROR_TYPE_DEBUG;
+ text = "correct";
+ ret = 0;
+ }
+ else
+ {
+ level = GNUNET_ERROR_TYPE_ERROR;
+ text = "wrong";
+ ret = 1;
+ }
+
+ GNUNET_log (level, "Stage %u: LAN outbound quota out %s: Received %llu, configured %llu\n",
+ stage,
+ text,
+ (unsigned long long int) ntohl(bandwidth_out.value__),
+ quota_out[GNUNET_ATS_NET_LAN]);
+
+ if (ntohl(bandwidth_in.value__) == quota_in[GNUNET_ATS_NET_LAN])
+ {
+ level = GNUNET_ERROR_TYPE_DEBUG;
+ text = "correct";
+ ret = 0;
+ }
+ else
+ {
+ level = GNUNET_ERROR_TYPE_ERROR;
+ text = "wrong";
+ ret = 1;
+ }
+
+ GNUNET_log (level, "Stage %u: LAN inbound quota out %s: Received %llu, configured %llu\n",
+ stage,
+ text,
+ (unsigned long long int) ntohl(bandwidth_out.value__),
+ quota_out[GNUNET_ATS_NET_LAN]);
+
+ if (GNUNET_ATS_NET_LAN != find_ats_value (atsi, ats_count, GNUNET_ATS_NETWORK_TYPE))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Stage %u: Incorrect network type, exptected %s, got %s \n",
+ stage,
+ GNUNET_ATS_print_network_type(GNUNET_ATS_NET_LAN),
+ GNUNET_ATS_print_network_type(find_ats_value (atsi, ats_count, GNUNET_ATS_NETWORK_TYPE)));
+ ret = 1;
+ }
+
+ GNUNET_SCHEDULER_add_now (&end, NULL);
+ }
+}
+
+static unsigned int
+load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned long long *out_dest, unsigned long long *in_dest, int dest_length)
+{
+ int quotas[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
+ char * entry_in = NULL;
+ char * entry_out = NULL;
+ char * quota_out_str;
+ char * quota_in_str;
+ int c;
+
+ for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
+ {
+ in_dest[c] = 0;
+ out_dest[c] = 0;
+ switch (quotas[c]) {
+ case GNUNET_ATS_NET_UNSPECIFIED:
+ entry_out = "UNSPECIFIED_QUOTA_OUT";
+ entry_in = "UNSPECIFIED_QUOTA_IN";
+ break;
+ case GNUNET_ATS_NET_LOOPBACK:
+ entry_out = "LOOPBACK_QUOTA_OUT";
+ entry_in = "LOOPBACK_QUOTA_IN";
+ break;
+ case GNUNET_ATS_NET_LAN:
+ entry_out = "LAN_QUOTA_OUT";
+ entry_in = "LAN_QUOTA_IN";
+ break;
+ case GNUNET_ATS_NET_WAN:
+ entry_out = "WAN_QUOTA_OUT";
+ entry_in = "WAN_QUOTA_IN";
+ break;
+ case GNUNET_ATS_NET_WLAN:
+ entry_out = "WLAN_QUOTA_OUT";
+ entry_in = "WLAN_QUOTA_IN";
+ break;
+ default:
+ break;
+ }
+
+ if ((entry_in == NULL) || (entry_out == NULL))
+ continue;
+
+ /* quota out */
+ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, &quota_out_str))
+ {
+ if (0 == strcmp(quota_out_str, BIG_M_STRING) ||
+ (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &out_dest[c])))
+ out_dest[c] = UINT32_MAX;
+
+ GNUNET_free (quota_out_str);
+ quota_out_str = NULL;
+ }
+ else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c])
+ out_dest[c] = UINT32_MAX;
+ else
+ out_dest[c] = UINT32_MAX;
+
+ /* quota in */
+ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, &quota_in_str))
+ {
+ if (0 == strcmp(quota_in_str, BIG_M_STRING) ||
+ (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
+ in_dest[c] = UINT32_MAX;
+
+ GNUNET_free (quota_in_str);
+ quota_in_str = NULL;
+ }
+ else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c])
+ {
+ in_dest[c] = UINT32_MAX;
+ }
+ else
+ {
+ in_dest[c] = UINT32_MAX;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded quota: %s %u, %s %u\n", entry_in, in_dest[c], entry_out, out_dest[c]);
+
+ }
+ return GNUNET_ATS_NetworkTypeCount;
+}
+
+static void
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ struct GNUNET_TESTING_Peer *peer)
+{
+ die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
+
+ load_quotas (cfg, quota_out, quota_in, GNUNET_ATS_NetworkTypeCount);
+
+ /* Connect to ATS scheduling */
+ sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
+ if (sched_ats == NULL)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
+ ret = 1;
+ end ();
+ return;
+ }
+
+ /* Set up peer */
+ if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p.id.hashPubKey))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
+ ret = GNUNET_SYSERR;
+ end ();
+ return;
+ }
+
+ GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p.id)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
+ GNUNET_i2s_full(&p.id));
+
+ /* Prepare ATS Information */
+ test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+ test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ test_ats_info[1].value = htonl(1);
+ test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
+ test_ats_info[1].value = htonl(10);
+ test_ats_count = 2;
+
+ /* Adding address without session */
+ test_session = &test_addr;
+ create_test_address (&test_addr, "test", &test_addr, "test", strlen ("test") + 1);
+ test_hello_address.peer = p.id;
+ test_hello_address.transport_name = test_addr.plugin;
+ test_hello_address.address = test_addr.addr;
+ test_hello_address.address_length = test_addr.addr_len;
+ GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);
+
+ /* Request address */
+ GNUNET_ATS_suggest_address (sched_ats, &p.id);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ if (0 != GNUNET_TESTING_peer_run ("test_ats_api_scheduling_update_address",
+ "test_ats_api.conf",
+ &run, NULL))
+ return 1;
+ return ret;
+}
+
+/* end of file test_ats_api_scheduling_update_address.c */