summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-10-06 21:03:33 +0200
committerChristian Grothoff <christian@grothoff.org>2019-10-06 21:03:33 +0200
commit622fd12c7101c53c1fa0f9563a831f3196732dc5 (patch)
treed86047807232d9921341b8ed84558dea2b9df929
parent6c38429f96ff9128ebd983a85aa6a2024112ed25 (diff)
remove dead, obsolete or never-to-become ATS logic (DCE)
-rw-r--r--src/ats-tests/Makefile.am116
-rw-r--r--src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_mlp.conf24
-rw-r--r--src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_mlp.exp46
-rw-r--r--src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_ril.conf24
-rw-r--r--src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_ril.exp46
-rw-r--r--src/ats-tests/perf_ats_mlp_bandwidth.conf4
-rw-r--r--src/ats-tests/perf_ats_mlp_latency.conf4
-rw-r--r--src/ats-tests/perf_ats_mlp_none.conf4
-rw-r--r--src/ats-tests/perf_ats_ril_bandwidth.conf4
-rw-r--r--src/ats-tests/perf_ats_ril_latency.conf4
-rw-r--r--src/ats-tests/perf_ats_ril_none.conf4
-rw-r--r--src/ats/Makefile.am127
-rw-r--r--src/ats/ats2.h294
-rw-r--r--src/ats/ats_api2_application.c366
-rw-r--r--src/ats/ats_api2_transport.c689
-rw-r--r--src/ats/gnunet-service-ats-new.c804
-rw-r--r--src/ats/perf_ats_solver_mlp.conf0
-rw-r--r--src/ats/perf_ats_solver_ril.conf0
-rw-r--r--src/ats/plugin_ats2_common.c99
-rw-r--r--src/ats/plugin_ats2_simple.c1087
-rw-r--r--src/ats/plugin_ats_mlp.c2924
-rw-r--r--src/ats/plugin_ats_ril.c2997
-rw-r--r--src/ats/test_ats2_lib.c259
-rw-r--r--src/ats/test_ats2_lib.conf13
-rw-r--r--src/ats/test_ats2_lib.h523
-rw-r--r--src/ats/test_ats_api_mlp.conf45
-rw-r--r--src/ats/test_ats_api_ril.conf24
-rw-r--r--src/ats/test_ats_solver_delayed_mlp.conf20
-rw-r--r--src/ats/test_ats_solver_delayed_ril.conf31
-rw-r--r--src/include/Makefile.am1
-rw-r--r--src/include/gnunet_ats_plugin_new.h247
31 files changed, 8 insertions, 10822 deletions
diff --git a/src/ats-tests/Makefile.am b/src/ats-tests/Makefile.am
index 1804a43bf..c965fcc9f 100644
--- a/src/ats-tests/Makefile.am
+++ b/src/ats-tests/Makefile.am
@@ -9,18 +9,6 @@ if USE_COVERAGE
AM_CFLAGS = -fprofile-arcs -ftest-coverage
endif
-if HAVE_EXPERIMENTAL
-if HAVE_LIBGLPK
- PERF_MLP = \
- perf_ats_mlp_transport_none \
- perf_ats_mlp_transport_bandwidth \
- perf_ats_mlp_transport_latency \
- perf_ats_mlp_core_none \
- perf_ats_mlp_core_bandwidth \
- perf_ats_mlp_core_latency
-endif
-endif
-
if HAVE_TESTING
TESTING_TESTS = \
perf_ats_proportional_transport_none \
@@ -31,8 +19,6 @@ TESTING_TESTS = \
perf_ats_proportional_core_latency \
$(PERF_MLP)
-# RIL-tests commented out as RIL is currently badly broken.
-# perf_ats_ril_transport_none perf_ats_ril_core_none perf_ats_ril_transport_bandwidth perf_ats_ril_core_bandwidth perf_ats_ril_transport_latency perf_ats_ril_core_latency
endif
lib_LTLIBRARIES = \
@@ -56,7 +42,7 @@ libgnunetatstesting_la_SOURCES = \
libgnunetatstesting_la_LIBADD = \
$(top_builddir)/src/testbed/libgnunettestbed.la \
$(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/transport/libgnunettransport.la \
+ $(top_builddir)/src/transport/libgnunettransport.la \
$(top_builddir)/src/ats/libgnunetats.la \
$(top_builddir)/src/util/libgnunetutil.la \
$(GN_LIBINTL)
@@ -168,106 +154,8 @@ perf_ats_proportional_transport_latency_DEPENDENCIES = \
libgnunetatstesting.la \
$(top_builddir)/src/util/libgnunetutil.la
-perf_ats_mlp_core_none_SOURCES = \
- perf_ats.c
-perf_ats_mlp_core_none_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
- $(top_builddir)/src/testbed/libgnunettestbed.la \
- $(top_builddir)/src/ats/libgnunetats.la \
- $(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/transport/libgnunettransport.la
-perf_ats_mlp_core_none_DEPENDENCIES = \
- libgnunetatstesting.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-perf_ats_mlp_transport_none_SOURCES = \
- perf_ats.c
-perf_ats_mlp_transport_none_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
- $(top_builddir)/src/testbed/libgnunettestbed.la \
- $(top_builddir)/src/ats/libgnunetats.la \
- $(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/transport/libgnunettransport.la
-perf_ats_mlp_transport_none_DEPENDENCIES = \
- libgnunetatstesting.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-perf_ats_mlp_core_bandwidth_SOURCES = \
- perf_ats.c
-perf_ats_mlp_core_bandwidth_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
- $(top_builddir)/src/testbed/libgnunettestbed.la \
- $(top_builddir)/src/ats/libgnunetats.la \
- $(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/transport/libgnunettransport.la
-perf_ats_mlp_core_bandwidth_DEPENDENCIES = \
- libgnunetatstesting.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-perf_ats_mlp_transport_bandwidth_SOURCES = \
- perf_ats.c
-perf_ats_mlp_transport_bandwidth_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
- $(top_builddir)/src/testbed/libgnunettestbed.la \
- $(top_builddir)/src/ats/libgnunetats.la \
- $(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/transport/libgnunettransport.la
-perf_ats_mlp_transport_bandwidth_DEPENDENCIES = \
- libgnunetatstesting.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-perf_ats_mlp_core_latency_SOURCES = \
- perf_ats.c
-perf_ats_mlp_core_latency_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
- $(top_builddir)/src/testbed/libgnunettestbed.la \
- $(top_builddir)/src/ats/libgnunetats.la \
- $(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/transport/libgnunettransport.la
-perf_ats_mlp_core_latency_DEPENDENCIES = \
- libgnunetatstesting.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-perf_ats_mlp_transport_latency_SOURCES = \
- perf_ats.c
-perf_ats_mlp_transport_latency_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
- $(top_builddir)/src/testbed/libgnunettestbed.la \
- $(top_builddir)/src/ats/libgnunetats.la \
- $(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/transport/libgnunettransport.la
-perf_ats_mlp_transport_latencyDEPENDENCIES = \
- $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-#perf_ats_ril_core_none_SOURCES = \
-# perf_ats.c
-#perf_ats_ril_core_none_LDADD = \
-# $(top_builddir)/src/util/libgnunetutil.la \
-# $(top_builddir)/src/ats-tests/libgnunetatstesting.la \
-# $(top_builddir)/src/testbed/libgnunettestbed.la \
-# $(top_builddir)/src/ats/libgnunetats.la \
-# $(top_builddir)/src/core/libgnunetcore.la \
-# $(top_builddir)/src/transport/libgnunettransport.la
-#perf_ats_ril_core_none_DEPENDENCIES = \
-# libgnunetatstesting.la \
-# $(top_builddir)/src/util/libgnunetutil.la
-
-
EXTRA_DIST = \
gnunet_ats_sim_default.conf \
perf_ats_proportional_none.conf \
perf_ats_proportional_bandwidth.conf \
- perf_ats_proportional_latency.conf \
- perf_ats_mlp_none.conf \
- perf_ats_mlp_bandwidth.conf \
- perf_ats_mlp_latency.conf \
- perf_ats_ril_none.conf \
- perf_ats_ril_bandwidth.conf \
- perf_ats_ril_latency.conf
+ perf_ats_proportional_latency.conf
diff --git a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_mlp.conf b/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_mlp.conf
deleted file mode 100644
index 91697eda9..000000000
--- a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_mlp.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-@INLINE@ template_perf_ats.conf
-
-[transport]
-plugins = unix
-
-[ats]
-MODE = PROPORTIONAL
-UNSPECIFIED_QUOTA_IN = 128 KiB
-UNSPECIFIED_QUOTA_OUT = 128 KiB
-# LOOPBACK
-LOOPBACK_QUOTA_IN = 128 KiB
-LOOPBACK_QUOTA_OUT = 128 KiB
-# LAN
-LAN_QUOTA_IN = 128 KiB
-LAN_QUOTA_OUT = 128 KiB
-# WAN
-WAN_QUOTA_IN = 128 KiB
-WAN_QUOTA_OUT = 128 KiB
-# WLAN
-WLAN_QUOTA_IN = 128 KiB
-WLAN_QUOTA_OUT = 128 KiB
-# BLUETOOTH
-BLUETOOTH_QUOTA_IN = 128 KiB
-BLUETOOTH_QUOTA_OUT = 128 KiB \ No newline at end of file
diff --git a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_mlp.exp b/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_mlp.exp
deleted file mode 100644
index 9b4c998c4..000000000
--- a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_mlp.exp
+++ /dev/null
@@ -1,46 +0,0 @@
-[experiment]
-name = sc1_eval_dru_mlp
-masters = 1
-slaves = 3
-max_duration = 20 s
-log_freq = 100 ms
-cfg_file = experiments/evaluation1_dru_3_peers_1addr_1scope_mlp.conf
-
-[episode-0]
-# operations = start_send, stop_send, start_preference, stop_preference
-duration = 1 s
-op-0-operation = start_send
-op-0-src = 0
-op-0-dest = 0
-op-0-type = constant
-#op-0-period = 10 s
-op-0-base-rate= 10000
-#op-0-max-rate = 10000
-
-op-1-operation = start_send
-op-1-src = 0
-op-1-dest = 1
-op-1-type = constant
-#op-1-period = 10 s
-op-1-base-rate= 10000
-#op-1-max-rate = 10000
-
-op-2-operation = start_send
-op-2-src = 0
-op-2-dest = 2
-op-2-type = constant
-#op-1-period = 10 s
-op-2-base-rate= 10000
-#op-1-max-rate = 10000
-
-[episode-1]
-duration = 1 s
-op-0-operation = start_preference
-op-0-src = 0
-op-0-dest = 2
-op-0-type = constant
-#op-0-period = 10 s
-op-0-pref = bandwidth
-op-0-frequency = 1 s
-op-0-base-rate= 50
-#op-0-max-rate = 10000 \ No newline at end of file
diff --git a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_ril.conf b/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_ril.conf
deleted file mode 100644
index 4b66e5aea..000000000
--- a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_ril.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-@INLINE@ template_perf_ats.conf
-
-[transport]
-plugins = unix
-
-[ats]
-MODE = MLP
-UNSPECIFIED_QUOTA_IN = 128 KiB
-UNSPECIFIED_QUOTA_OUT = 128 KiB
-# LOOPBACK
-LOOPBACK_QUOTA_IN = 128 KiB
-LOOPBACK_QUOTA_OUT = 128 KiB
-# LAN
-LAN_QUOTA_IN = 128 KiB
-LAN_QUOTA_OUT = 128 KiB
-# WAN
-WAN_QUOTA_IN = 128 KiB
-WAN_QUOTA_OUT = 128 KiB
-# WLAN
-WLAN_QUOTA_IN = 128 KiB
-WLAN_QUOTA_OUT = 128 KiB
-# BLUETOOTH
-BLUETOOTH_QUOTA_IN = 128 KiB
-BLUETOOTH_QUOTA_OUT = 128 KiB \ No newline at end of file
diff --git a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_ril.exp b/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_ril.exp
deleted file mode 100644
index 280b1605c..000000000
--- a/src/ats-tests/experiments/evaluation1_dru_3_peers_1addr_1scope_ril.exp
+++ /dev/null
@@ -1,46 +0,0 @@
-[experiment]
-name = sc1_eval_dru_ril
-masters = 1
-slaves = 3
-max_duration = 20 s
-log_freq = 100 ms
-cfg_file = experiments/evaluation1_dru_3_peers_1addr_1scope_ril.conf
-
-[episode-0]
-# operations = start_send, stop_send, start_preference, stop_preference
-duration = 10 s
-op-0-operation = start_send
-op-0-src = 0
-op-0-dest = 0
-op-0-type = constant
-#op-0-period = 10 s
-op-0-base-rate= 10000
-#op-0-max-rate = 10000
-
-op-1-operation = start_send
-op-1-src = 0
-op-1-dest = 1
-op-1-type = constant
-#op-1-period = 10 s
-op-1-base-rate= 10000
-#op-1-max-rate = 10000
-
-op-2-operation = start_send
-op-2-src = 0
-op-2-dest = 2
-op-2-type = constant
-#op-1-period = 10 s
-op-2-base-rate= 10000
-#op-1-max-rate = 10000
-
-[episode-1]
-duration = 10 s
-op-0-operation = start_preference
-op-0-src = 0
-op-0-dest = 2
-op-0-type = constant
-#op-0-period = 10 s
-op-0-pref = bandwidth
-op-0-frequency = 1 s
-op-0-base-rate= 50
-#op-0-max-rate = 10000 \ No newline at end of file
diff --git a/src/ats-tests/perf_ats_mlp_bandwidth.conf b/src/ats-tests/perf_ats_mlp_bandwidth.conf
deleted file mode 100644
index b803d683d..000000000
--- a/src/ats-tests/perf_ats_mlp_bandwidth.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-@INLINE@ template_perf_ats.conf
-
-[ats]
-MODE = mlp
diff --git a/src/ats-tests/perf_ats_mlp_latency.conf b/src/ats-tests/perf_ats_mlp_latency.conf
deleted file mode 100644
index b803d683d..000000000
--- a/src/ats-tests/perf_ats_mlp_latency.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-@INLINE@ template_perf_ats.conf
-
-[ats]
-MODE = mlp
diff --git a/src/ats-tests/perf_ats_mlp_none.conf b/src/ats-tests/perf_ats_mlp_none.conf
deleted file mode 100644
index b803d683d..000000000
--- a/src/ats-tests/perf_ats_mlp_none.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-@INLINE@ template_perf_ats.conf
-
-[ats]
-MODE = mlp
diff --git a/src/ats-tests/perf_ats_ril_bandwidth.conf b/src/ats-tests/perf_ats_ril_bandwidth.conf
deleted file mode 100644
index 3e7969a84..000000000
--- a/src/ats-tests/perf_ats_ril_bandwidth.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-@INLINE@ template_perf_ats.conf
-
-[ats]
-MODE = ril
diff --git a/src/ats-tests/perf_ats_ril_latency.conf b/src/ats-tests/perf_ats_ril_latency.conf
deleted file mode 100644
index 3e7969a84..000000000
--- a/src/ats-tests/perf_ats_ril_latency.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-@INLINE@ template_perf_ats.conf
-
-[ats]
-MODE = ril
diff --git a/src/ats-tests/perf_ats_ril_none.conf b/src/ats-tests/perf_ats_ril_none.conf
deleted file mode 100644
index 3e7969a84..000000000
--- a/src/ats-tests/perf_ats_ril_none.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-@INLINE@ template_perf_ats.conf
-
-[ats]
-MODE = ril
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am
index d7e5b68c7..bd8962158 100644
--- a/src/ats/Makefile.am
+++ b/src/ats/Makefile.am
@@ -15,22 +15,10 @@ if USE_COVERAGE
endif
lib_LTLIBRARIES = \
- libgnunetats.la \
- libgnunetatsapplication.la \
- libgnunetatstransport.la
+ libgnunetats.la
plugin_LTLIBRARIES = \
- libgnunet_plugin_ats_proportional.la \
- libgnunet_plugin_ats2_simple.la
-
-if HAVE_EXPERIMENTAL
-plugin_LTLIBRARIES += \
- libgnunet_plugin_ats_ril.la
-if HAVE_LIBGLPK
-plugin_LTLIBRARIES += \
- libgnunet_plugin_ats_mlp.la
-endif
-endif
+ libgnunet_plugin_ats_proportional.la
libgnunetats_la_SOURCES = \
ats_api_connectivity.c \
@@ -45,74 +33,20 @@ libgnunetats_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) $(WINFLAGS) \
-version-info 4:0:0
-
-libgnunetatsapplication_la_SOURCES = \
- ats_api2_application.c
-libgnunetatsapplication_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(LTLIBINTL)
-libgnunetatsapplication_la_LDFLAGS = \
- $(GN_LIB_LDFLAGS) $(WINFLAGS) \
- -version-info 0:0:0
-
-libgnunetatstransport_la_SOURCES = \
- ats_api2_transport.c
-libgnunetatstransport_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(LTLIBINTL)
-libgnunetatstransport_la_LDFLAGS = \
- $(GN_LIB_LDFLAGS) $(WINFLAGS) \
- -version-info 0:0:0
-
libgnunet_plugin_ats_proportional_la_SOURCES = \
plugin_ats_proportional.c
libgnunet_plugin_ats_proportional_la_LIBADD = \
libgnunetats.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/nt/libgnunetnt.la \
- $(LTLIBINTL)
-libgnunet_plugin_ats_proportional_la_LDFLAGS = \
- $(GN_PLUGIN_LDFLAGS)
-
-libgnunet_plugin_ats2_simple_la_SOURCES = \
- plugin_ats2_simple.c
-libgnunet_plugin_ats2_simple_la_LIBADD = \
- $(top_builddir)/src/hello/libgnunethello.la \
- $(top_builddir)/src/peerstore/libgnunetpeerstore.la \
$(top_builddir)/src/nt/libgnunetnt.la \
- $(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/util/libgnunetutil.la \
$(LTLIBINTL)
-libgnunet_plugin_ats2_simple_la_LDFLAGS = \
+libgnunet_plugin_ats_proportional_la_LDFLAGS = \
$(GN_PLUGIN_LDFLAGS)
-libgnunet_plugin_ats_mlp_la_SOURCES = \
- plugin_ats_mlp.c
-libgnunet_plugin_ats_mlp_la_LIBADD = \
- libgnunetats.la \
- $(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/nt/libgnunetnt.la \
- $(top_builddir)/src/util/libgnunetutil.la
-libgnunet_plugin_ats_mlp_la_LDFLAGS = \
- $(GN_PLUGIN_LDFLAGS) \
- -lglpk
-
-libgnunet_plugin_ats_ril_la_SOURCES = \
- plugin_ats_ril.c
-libgnunet_plugin_ats_ril_la_LIBADD = \
- libgnunetats.la \
- $(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/nt/libgnunetnt.la \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(LTLIBINTL)
-libgnunet_plugin_ats_ril_la_LDFLAGS = \
- $(GN_PLUGIN_LDFLAGS)
-
libexec_PROGRAMS = \
- gnunet-service-ats \
- gnunet-service-ats-new
+ gnunet-service-ats
gnunet_service_ats_SOURCES = \
gnunet-service-ats.c gnunet-service-ats.h \
@@ -131,27 +65,10 @@ gnunet_service_ats_LDADD = \
libgnunetats.la \
$(GN_LIBINTL)
-gnunet_service_ats_new_SOURCES = \
- gnunet-service-ats-new.c
-gnunet_service_ats_new_LDADD = \
- $(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(GN_LIBINTL)
-
-
if HAVE_TESTING
TESTING_TESTS = \
test_ats_api_proportional \
- test_ats_reservation_api_proportional \
- test_ats2_lib
-if HAVE_EXPERIMENTAL
-TESTING_TESTS += \
- test_ats_api_ril
-if HAVE_LIBGLPK
-TESTING_TESTS += \
- test_ats_api_mlp
-endif
-endif
+ test_ats_reservation_api_proportional
endif
check_PROGRAMS = \
@@ -180,40 +97,8 @@ test_ats_reservation_api_proportional_LDADD = \
$(top_builddir)/src/testing/libgnunettesting.la \
libgnunetats.la
-test_ats_api_ril_SOURCES = \
- test_ats_api.c \
- test_ats_lib.c test_ats_lib.h
-test_ats_api_ril_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/hello/libgnunethello.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- libgnunetats.la
-
-test_ats_api_mlp_SOURCES = \
- test_ats_api.c \
- test_ats_lib.c test_ats_lib.h
-test_ats_api_mlp_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/hello/libgnunethello.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- libgnunetats.la
-
-test_ats2_lib_SOURCES = \
- test_ats2_lib.c test_ats2_lib.h
-test_ats2_lib_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/hello/libgnunethello.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- libgnunetatsapplication.la \
- libgnunetatstransport.la
-
-
EXTRA_DIST = \
- ats.h ats2.h \
- plugin_ats2_common.c \
+ ats.h \
test_delay \
- test_ats2_lib.conf \
test_ats_api.conf \
- test_ats_api_mlp.conf \
- test_ats_api_ril.conf \
test_ats_api_proportional.conf
diff --git a/src/ats/ats2.h b/src/ats/ats2.h
deleted file mode 100644
index df402dba2..000000000
--- a/src/ats/ats2.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2010-2015 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-/**
- * @file ats/ats2.h
- * @brief automatic transport selection messages
- * @author Christian Grothoff
- * @author Matthias Wachs
- */
-#ifndef ATS2_H
-#define ATS2_H
-
-#include "gnunet_util_lib.h"
-#include "gnunet_ats_transport_service.h"
-
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
-
-/**
- * ATS performance characteristics for an address.
- */
-struct PropertiesNBO
-{
- /**
- * Delay. Time between when the time packet is sent and the packet
- * arrives. FOREVER if we did not (successfully) measure yet.
- */
- struct GNUNET_TIME_RelativeNBO delay;
-
- /**
- * Confirmed successful payload on this connection from this peer to
- * the other peer. In NBO.
- *
- * Unit: [bytes/second]
- */
- uint32_t goodput_out;
-
- /**
- * Confirmed useful payload on this connection to this peer from
- * the other peer. In NBO.
- *
- * Unit: [bytes/second]
- */
- uint32_t goodput_in;
-
- /**
- * Actual traffic on this connection from this peer to the other peer.
- * Includes transport overhead. In NBO.
- *
- * Unit: [bytes/second]
- */
- uint32_t utilization_out;
-
- /**
- * Actual traffic on this connection from the other peer to this peer.
- * Includes transport overhead. In NBO.
- *
- * Unit: [bytes/second]
- */
- uint32_t utilization_in;
-
- /**
- * Distance on network layer (required for distance-vector routing)
- * in hops. Zero for direct connections (i.e. plain TCP/UDP). In NBO.
- */
- uint32_t distance;
-
- /**
- * MTU of the network layer, UINT32_MAX for no MTU (stream).
- *
- * Unit: [bytes]. In NBO.
- */
- uint32_t mtu;
-
- /**
- * Which network scope does the respective address belong to?
- * A `enum GNUNET_NetworkType nt` in NBO.
- */
- uint32_t nt;
-
- /**
- * What characteristics does this communicator have?
- * A `enum GNUNET_TRANSPORT_CommunicatorCharacteristics` in NBO.
- */
- uint32_t cc;
-};
-
-
-/**
- * Application client to ATS service: we would like to have
- * address suggestions for this peer.
- */
-struct ExpressPreferenceMessage
-{
- /**
- * Type is #GNUNET_MESSAGE_TYPE_ATS_SUGGEST or
- * #GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL to stop
- * suggestions.
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * What type of performance preference does the client have?
- * A `enum GNUNET_MQ_PreferenceKind` in NBO.
- */
- uint32_t pk GNUNET_PACKED;
-
- /**
- * Peer to get address suggestions for.
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * How much bandwidth in bytes/second does the application expect?
- */
- struct GNUNET_BANDWIDTH_Value32NBO bw;
-};
-
-
-/**
- * Transport client to ATS service: here is another session you can use.
- */
-struct SessionAddMessage
-{
- /**
- * Type is #GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD or
- * #GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Internal number this client will henceforth use to
- * refer to this session.
- */
- uint32_t session_id GNUNET_PACKED;
-
- /**
- * Identity of the peer that this session is for.
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * Performance properties of the session.
- */
- struct PropertiesNBO properties;
-
- /* followed by:
- * - char * address (including '\0'-termination).
- */
-};
-
-
-/**
- * Message used to notify ATS that the performance
- * characteristics for an session have changed.
- */
-struct SessionUpdateMessage
-{
- /**
- * Message of type #GNUNET_MESSAGE_TYPE_ATS_SESSION_UPDATE.
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Internal number this client uses to refer to this session.
- */
- uint32_t session_id GNUNET_PACKED;
-
- /**
- * Which peer is this about? (Technically redundant, as the
- * @e session_id should be sufficient, but enables ATS service
- * to find the session faster).
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * Performance properties of the session.
- */
- struct PropertiesNBO properties;
-};
-
-
-/**
- * Message sent by ATS client to ATS service when an session
- * was destroyed and must thus henceforth no longer be considered
- * for scheduling.
- */
-struct SessionDelMessage
-{
- /**
- * Type is #GNUNET_MESSAGE_TYPE_ATS_SESSION_DEL.
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Internal number this client uses to refer to this session.
- */
- uint32_t session_id GNUNET_PACKED;
-
- /**
- * Which peer is this about? (Technically redundant, as the
- * @e session_id should be sufficient, but enables ATS service
- * to find the session faster).
- */
- struct GNUNET_PeerIdentity peer;
-};
-
-
-/**
- * ATS Service allocates resources to an session
- * identified by the given @e session_id for the given @e peer with
- * the given @e bandwidth_in and @e bandwidth_out limits from now on.
- */
-struct SessionAllocationMessage
-{
- /**
- * A message of type #GNUNET_MESSAGE_TYPE_ATS_SESSION_ALLOCATION.
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Internal number this client uses to refer to the session this
- * suggestion is about.
- */
- uint32_t session_id GNUNET_PACKED;
-
- /**
- * Which peer is this about? (Technically redundant, as the
- * @e session_id should be sufficient, but may enable client
- * to find the session faster and/or check consistency).
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * How much bandwidth we are allowed for sending.
- */
- struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out;
-
- /**
- * How much bandwidth we are allowed for receiving.
- */
- struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
-};
-
-
-/**
- * ATS Service suggests to the transport service to try the address
- * for the given @e peer.
- */
-struct AddressSuggestionMessage
-{
- /**
- * A message of type #GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION.
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Zero.
- */
- uint32_t reserved GNUNET_PACKED;
-
- /**
- * Which peer is this about? (Technically redundant, as the
- * @e session_id should be sufficient, but may enable client
- * to find the session faster and/or check consistency).
- */
- struct GNUNET_PeerIdentity peer;
-
- /* Followed by 0-terminated address */
-};
-
-
-GNUNET_NETWORK_STRUCT_END
-
-
-
-#endif
diff --git a/src/ats/ats_api2_application.c b/src/ats/ats_api2_application.c
deleted file mode 100644
index 46e57c5bb..000000000
--- a/src/ats/ats_api2_application.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2010-2016 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-/**
- * @file ats/ats_api2_application.c
- * @brief enable clients to ask ATS about establishing connections to peers
- * @author Christian Grothoff
- * @author Matthias Wachs
- */
-#include "platform.h"
-#include "gnunet_ats_application_service.h"
-#include "ats2.h"
-
-
-#define LOG(kind, ...) GNUNET_log_from (kind, "ats-application-api", \
- __VA_ARGS__)
-
-
-/**
- * Handle for ATS address suggestion requests.
- */
-struct GNUNET_ATS_ApplicationSuggestHandle
-{
- /**
- * ID of the peer for which address suggestion was requested.
- */
- struct GNUNET_PeerIdentity id;
-
- /**
- * Connecitivity handle this suggestion handle belongs to.
- */
- struct GNUNET_ATS_ApplicationHandle *ch;
-
- /**
- * What preference is being expressed?
- */
- enum GNUNET_MQ_PreferenceKind pk;
-
- /**
- * How much bandwidth does the client expect?
- */
- struct GNUNET_BANDWIDTH_Value32NBO bw;
-};
-
-
-/**
- * Handle to the ATS subsystem for application management.
- */
-struct GNUNET_ATS_ApplicationHandle
-{
- /**
- * Our configuration.
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- /**
- * Map with the identities of all the peers for which we would
- * like to have address suggestions. The key is the PID, the
- * value is currently the `struct GNUNET_ATS_ApplicationSuggestHandle`
- */
- struct GNUNET_CONTAINER_MultiPeerMap *sug_requests;
-
- /**
- * Message queue for sending requests to the ATS service.
- */
- struct GNUNET_MQ_Handle *mq;
-
- /**
- * Task to trigger reconnect.
- */
- struct GNUNET_SCHEDULER_Task *task;
-
- /**
- * Reconnect backoff delay.
- */
- struct GNUNET_TIME_Relative backoff;
-};
-
-
-/**
- * Re-establish the connection to the ATS service.
- *
- * @param ch handle to use to re-connect.
- */
-static void
-reconnect (struct GNUNET_ATS_ApplicationHandle *ch);
-
-
-/**
- * Re-establish the connection to the ATS service.
- *
- * @param cls handle to use to re-connect.
- */
-static void
-reconnect_task (void *cls)
-{
- struct GNUNET_ATS_ApplicationHandle *ch = cls;
-
- ch->task = NULL;
- reconnect (ch);
-}
-
-
-/**
- * Disconnect from ATS and then reconnect.
- *
- * @param ch our handle
- */
-static void
-force_reconnect (struct GNUNET_ATS_ApplicationHandle *ch)
-{
- if (NULL != ch->mq)
- {
- GNUNET_MQ_destroy (ch->mq);
- ch->mq = NULL;
- }
- ch->backoff = GNUNET_TIME_STD_BACKOFF (ch->backoff);
- ch->task = GNUNET_SCHEDULER_add_delayed (ch->backoff,
- &reconnect_task,
- ch);
-}
-
-
-/**
- * We encountered an error handling the MQ to the
- * ATS service. Reconnect.
- *
- * @param cls the `struct GNUNET_ATS_ApplicationHandle`
- * @param error details about the error
- */
-static void
-error_handler (void *cls,
- enum GNUNET_MQ_Error error)
-{
- struct GNUNET_ATS_ApplicationHandle *ch = cls;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "ATS connection died (code %d), reconnecting\n",
- (int) error);
- force_reconnect (ch);
-}
-
-
-/**
- * Transmit request for an address suggestion.
- *
- * @param cls the `struct GNUNET_ATS_ApplicationHandle`
- * @param peer peer to ask for an address suggestion for
- * @param value the `struct GNUNET_ATS_SuggestHandle`
- * @return #GNUNET_OK (continue to iterate), #GNUNET_SYSERR on
- * failure (message queue no longer exists)
- */
-static int
-transmit_suggestion (void *cls,
- const struct GNUNET_PeerIdentity *peer,
- void *value)
-{
- struct GNUNET_ATS_ApplicationHandle *ch = cls;
- struct GNUNET_ATS_ApplicationSuggestHandle *sh = value;
- struct GNUNET_MQ_Envelope *ev;
- struct ExpressPreferenceMessage *m;
-
- if (NULL == ch->mq)
- return GNUNET_SYSERR;
- ev = GNUNET_MQ_msg (m,
- GNUNET_MESSAGE_TYPE_ATS_SUGGEST);
- m->pk = htonl ((uint32_t) sh->pk);
- m->bw = sh->bw;
- m->peer = *peer;
- GNUNET_MQ_send (ch->mq, ev);
- return GNUNET_OK;
-}
-
-
-/**
- * Re-establish the connection to the ATS service.
- *
- * @param ch handle to use to re-connect.
- */
-static void
-reconnect (struct GNUNET_ATS_ApplicationHandle *ch)
-{
- static const struct GNUNET_MQ_MessageHandler handlers[] = {
- { NULL, 0, 0 }
- };
-
- GNUNET_assert (NULL == ch->mq);
- ch->mq = GNUNET_CLIENT_connect (ch->cfg,
- "ats",
- handlers,
- &error_handler,
- ch);
- if (NULL == ch->mq)
- {
- force_reconnect (ch);
- return;
- }
- GNUNET_CONTAINER_multipeermap_iterate (ch->sug_requests,
- &transmit_suggestion,
- ch);
-}
-
-
-/**
- * Initialize the ATS application suggestion client handle.
- *
- * @param cfg configuration to use
- * @return ats application handle, NULL on error
- */
-struct GNUNET_ATS_ApplicationHandle *
-GNUNET_ATS_application_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- struct GNUNET_ATS_ApplicationHandle *ch;
-
- ch = GNUNET_new (struct GNUNET_ATS_ApplicationHandle);
- ch->cfg = cfg;
- ch->sug_requests = GNUNET_CONTAINER_multipeermap_create (32,
- GNUNET_YES);
- reconnect (ch);
- return ch;
-}
-
-
-/**
- * Function called to free all `struct GNUNET_ATS_ApplicationSuggestHandle`s
- * in the map.
- *
- * @param cls NULL
- * @param key the key
- * @param value the value to free
- * @return #GNUNET_OK (continue to iterate)
- */
-static int
-free_sug_handle (void *cls,
- const struct GNUNET_PeerIdentity *key,
- void *value)
-{
- struct GNUNET_ATS_ApplicationSuggestHandle *cur = value;
-
- GNUNET_free (cur);
- return GNUNET_OK;
-}
-
-
-/**
- * Client is done with ATS application management, release resources.
- *
- * @param ch handle to release
- */
-void
-GNUNET_ATS_application_done (struct GNUNET_ATS_ApplicationHandle *ch)
-{
- if (NULL != ch->mq)
- {
- GNUNET_MQ_destroy (ch->mq);
- ch->mq = NULL;
- }
- if (NULL != ch->task)
- {
- GNUNET_SCHEDULER_cancel (ch->task);
- ch->task = NULL;
- }
- GNUNET_CONTAINER_multipeermap_iterate (ch->sug_requests,
- &free_sug_handle,
- NULL);
- GNUNET_CONTAINER_multipeermap_destroy (ch->sug_requests);
- GNUNET_free (ch);
-}
-
-
-/**
- * We would like to receive address suggestions for a peer. ATS will
- * respond with a call to the continuation immediately containing an address or
- * no address if none is available. ATS can suggest more addresses until we call
- * #GNUNET_ATS_application_suggest_cancel().
- *
- * @param ch handle
- * @param peer identity of the peer we need an address for
- * @param pk what kind of application will the application require (can be
- * #GNUNET_MQ_PREFERENCE_NONE, we will still try to connect)
- * @param bw desired bandwith, can be zero (we will still try to connect)
- * @return suggest handle, NULL if a request is already pending
- */
-struct GNUNET_ATS_ApplicationSuggestHandle *
-GNUNET_ATS_application_suggest (struct GNUNET_ATS_ApplicationHandle *ch,
- const struct GNUNET_PeerIdentity *peer,
- enum GNUNET_MQ_PreferenceKind pk,
- struct GNUNET_BANDWIDTH_Value32NBO bw)
-{
- struct GNUNET_ATS_ApplicationSuggestHandle *s;
-
- s = GNUNET_new (struct GNUNET_ATS_ApplicationSuggestHandle);
- s->ch = ch;
- s->id = *peer;
- s->pk = pk;
- s->bw = bw;
- (void) GNUNET_CONTAINER_multipeermap_put (ch->sug_requests,
- &s->id,
- s,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting ATS to suggest address for `%s'\n",
- GNUNET_i2s (peer));
- if (NULL == ch->mq)
- return s;
- GNUNET_assert (GNUNET_OK ==
- transmit_suggestion (ch,
- &s->id,
- s));
- return s;
-}
-
-
-/**
- * We no longer care about being connected to a peer.
- *
- * @param sh handle to stop
- */
-void
-GNUNET_ATS_application_suggest_cancel (struct
- GNUNET_ATS_ApplicationSuggestHandle *sh)
-{
- struct GNUNET_ATS_ApplicationHandle *ch = sh->ch;
- struct GNUNET_MQ_Envelope *ev;
- struct ExpressPreferenceMessage *m;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Telling ATS we no longer care for an address for `%s'\n",
- GNUNET_i2s (&sh->id));
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multipeermap_remove (ch->sug_requests,
- &sh->id,
- sh));
- if (NULL == ch->mq)
- {
- GNUNET_free (sh);
- return;
- }
- ev = GNUNET_MQ_msg (m,
- GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL);
- m->pk = htonl ((uint32_t) sh->pk);
- m->bw = sh->bw;
- m->peer = sh->id;
- GNUNET_MQ_send (ch->mq,
- ev);
- GNUNET_free (sh);
-}
-
-
-/* end of ats_api2_application.c */
diff --git a/src/ats/ats_api2_transport.c b/src/ats/ats_api2_transport.c
deleted file mode 100644
index da02ca592..000000000
--- a/src/ats/ats_api2_transport.c
+++ /dev/null
@@ -1,689 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2010-2015, 2018 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-/**
- * @file ats/ats_api2_transport.c
- * @brief address suggestions and bandwidth allocation
- * @author Christian Grothoff
- * @author Matthias Wachs
- */
-#include "platform.h"
-#include "gnunet_ats_transport_service.h"
-#include "ats2.h"
-
-#define LOG(kind, ...) GNUNET_log_from (kind, "ats-transport-api", __VA_ARGS__)
-
-
-/**
- * Information we track per session, incoming or outgoing. It also
- * doesn't matter if we have a session, any session that ATS is
- * allowed to suggest right now should be tracked.
- */
-struct GNUNET_ATS_SessionRecord
-{
- /**
- * Transport handle this session record belongs to.
- */
- struct GNUNET_ATS_TransportHandle *ath;
-
- /**
- * Address data.
- */
- const char *address;
-
- /**
- * Session handle, NULL if inbound-only (also implies we cannot
- * actually control inbound traffic via transport!). So if
- * @e session is NULL, the @e properties are informative for
- * ATS (connection exists, utilization) but ATS cannot directly
- * influence it (and should thus not call the
- * #GNUNET_ATS_AllocationCallback for this @e session, which is
- * obvious as NULL is not a meaningful session to allocation
- * resources to).
- */
- struct GNUNET_ATS_Session *session;
-
- /**
- * Identity of the peer reached at @e address.
- */
- struct GNUNET_PeerIdentity pid;
-
- /**
- * Performance data about the @e session.
- */
- struct GNUNET_ATS_Properties properties;
-
- /**
- * Unique ID to identify this session at this @a pid in IPC
- * messages.
- */
- uint32_t slot;
-};
-
-
-/**
- * Handle to the ATS subsystem for bandwidth/transport transport information.
- */
-struct GNUNET_ATS_TransportHandle
-{
- /**
- * Our configuration.
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- /**
- * Callback to invoke on suggestions.
- */
- GNUNET_ATS_SuggestionCallback suggest_cb;
-
- /**
- * Closure for @e suggest_cb.
- */
- void *suggest_cb_cls;
-
- /**
- * Callback to invoke on allocations.
- */
- GNUNET_ATS_AllocationCallback alloc_cb;
-
- /**
- * Closure for @e alloc_cb.
- */
- void *alloc_cb_cls;
-
- /**
- * Message queue for sending requests to the ATS service.
- */
- struct GNUNET_MQ_Handle *mq;
-
- /**
- * Task to trigger reconnect.
- */
- struct GNUNET_SCHEDULER_Task *task;
-
- /**
- * Hash map mapping PIDs to session records.
- */
- struct GNUNET_CONTAINER_MultiPeerMap *records;
-
- /**
- * Reconnect backoff delay.
- */
- struct GNUNET_TIME_Relative backoff;
-};
-
-
-
-/**
- * Convert ATS properties from host to network byte order.
- *
- * @param nbo[OUT] value written
- * @param hbo value read
- */
-static void
-properties_hton (struct PropertiesNBO *nbo,
- const struct GNUNET_ATS_Properties *hbo)
-{
- nbo->delay = GNUNET_TIME_relative_hton (hbo->delay);
- nbo->goodput_out = htonl (hbo->goodput_out);
- nbo->goodput_in = htonl (hbo->goodput_in);
- nbo->utilization_out = htonl (hbo->utilization_out);
- nbo->utilization_in = htonl (hbo->utilization_in);
- nbo->distance = htonl (hbo->distance);
- nbo->mtu = htonl (hbo->mtu);
- nbo->nt = htonl ((uint32_t) hbo->nt);
- nbo->cc = htonl ((uint32_t) hbo->cc);
-}
-
-
-/**
- * Re-establish the connection to the ATS service.
- *
- * @param sh handle to use to re-connect.
- */
-static void
-reconnect (struct GNUNET_ATS_TransportHandle *ath);
-
-
-/**
- * Re-establish the connection to the ATS service.
- *
- * @param cls handle to use to re-connect.
- */
-static void
-reconnect_task (void *cls)
-{
- struct GNUNET_ATS_TransportHandle *ath = cls;
-
- ath->task = NULL;
- reconnect (ath);
-}
-
-
-/**
- * Disconnect from ATS and then reconnect.
- *
- * @param ath our handle
- */
-static void
-force_reconnect (struct GNUNET_ATS_TransportHandle *ath)
-{
- if (NULL != ath->mq)
- {
- GNUNET_MQ_destroy (ath->mq);
- ath->mq = NULL;
- }
- /* FIXME: do we tell transport service about disconnect events? CON:
- initially ATS will have a really screwed picture of the world and
- the rapid change would be bad. PRO: if we don't, ATS and
- transport may disagree about the allocation for a while...
- For now: lazy: do nothing. */
- ath->backoff = GNUNET_TIME_STD_BACKOFF (ath->backoff);
- ath->task = GNUNET_SCHEDULER_add_delayed (ath->backoff,
- &reconnect_task,
- ath);
-}
-
-
-/**
- * Check format of address suggestion message from the service.
- *
- * @param cls the `struct GNUNET_ATS_TransportHandle`
- * @param m message received
- */
-static int
-check_ats_address_suggestion (void *cls,
- const struct AddressSuggestionMessage *m)
-{
- (void) cls;
- GNUNET_MQ_check_zero_termination (m);
- return GNUNET_SYSERR;
-}
-
-
-/**
- * We received an address suggestion message from the service.
- *
- * @param cls the `struct GNUNET_ATS_TransportHandle`
- * @param m message received
- */
-static void
-handle_ats_address_suggestion (void *cls,
- const struct AddressSuggestionMessage *m)
-{
- struct GNUNET_ATS_TransportHandle *ath = cls;
- const char *address = (const char *) &m[1];
-
- ath->suggest_cb (ath->suggest_cb_cls,
- &m->peer,
- address);
-}
-
-
-/**
- * Closure for #match_session_cb.
- */
-struct FindContext
-{
- /**
- * Key to look for.
- */
- uint32_t session_id;
-
- /**
- * Where to store the result.
- */
- struct GNUNET_ATS_SessionRecord *sr;
-};
-
-
-/**
- * Finds matching session record.
- *
- * @param cls a `struct FindContext`
- * @param pid peer identity (unused)
- * @param value a `struct GNUNET_ATS_SessionRecord`
- * @return #GNUNET_NO if match found, #GNUNET_YES to continue searching
- */
-static int
-match_session_cb (void *cls,
- const struct GNUNET_PeerIdentity *pid,
- void *value)
-{
- struct FindContext *fc = cls;
- struct GNUNET_ATS_SessionRecord *sr = value;
-
- (void) pid;
- if (fc->session_id == sr->slot)
- {
- fc->sr = sr;
- return GNUNET_NO;
- }
- return GNUNET_YES;
-}
-
-
-
-/**
- * Find session record for peer @a pid and session @a session_id
- *
- * @param ath transport handle to search
- * @param session_id session ID to match
- * @param pid peer to search under
- * @return NULL if no such record exists
- */
-static struct GNUNET_ATS_SessionRecord *
-find_session (struct GNUNET_ATS_TransportHandle *ath,
- uint32_t session_id,
- const struct GNUNET_PeerIdentity *pid)
-{
- struct FindContext fc = {
- .session_id = session_id,
- .sr = NULL
- };
-
- GNUNET_CONTAINER_multipeermap_get_multiple (ath->records,
- pid,
- &match_session_cb,
- &fc);
- return fc.sr;
-}
-
-
-/**
- * We received a session allocation message from the service.
- *
- * @param cls the `struct GNUNET_ATS_TransportHandle`
- * @param m message received
- */
-static void
-handle_ats_session_allocation (void *cls,
- const struct SessionAllocationMessage *m)
-{
- struct GNUNET_ATS_TransportHandle *ath = cls;
- struct GNUNET_ATS_SessionRecord *ar;
- uint32_t session_id;
-
- session_id = ntohl (m->session_id);
- ar = find_session (ath,
- session_id,
- &m->peer);
- if (NULL == ar)
- {
- /* this can (rarely) happen if ATS changes an sessiones allocation
- just when the transport service deleted it */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Allocation ignored, session unknown\n");
- return;
- }
- ath->backoff = GNUNET_TIME_UNIT_ZERO;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "ATS allocates bandwidth for peer `%s' using address %s\n",
- GNUNET_i2s (&ar->pid),
- ar->address);
- ath->alloc_cb (ath->alloc_cb_cls,
- ar->session,
- m->bandwidth_out,
- m->bandwidth_in);
-}
-
-
-/**
- * We encountered an error handling the MQ to the ATS service.
- * Reconnect.
- *
- * @param cls the `struct GNUNET_ATS_TransportHandle`
- * @param error details about the error
- */
-static void
-error_handler (void *cls,
- enum GNUNET_MQ_Error error)
-{
- struct GNUNET_ATS_TransportHandle *ath = cls;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "ATS connection died (code %d), reconnecting\n",
- (int) error);
- force_reconnect (ath);
-}
-
-
-/**
- * Generate and transmit the `struct SessionAddMessage` for the given
- * session record.
- *
- * @param ar the session to inform the ATS service about
- */
-static void
-send_add_session_message (const struct GNUNET_ATS_SessionRecord *ar)
-{
- struct GNUNET_ATS_TransportHandle *ath = ar->ath;
- struct GNUNET_MQ_Envelope *ev;
- struct SessionAddMessage *m;
- size_t alen;
-
- if (NULL == ath->mq)
- return; /* disconnected, skip for now */
- alen = strlen (ar->address) + 1;
- ev = GNUNET_MQ_msg_extra (m,
- alen,
- (NULL == ar->session)
- ? GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY
- : GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD);
- m->peer = ar->pid;
- m->session_id = htonl (ar->slot);
- properties_hton (&m->properties,
- &ar->properties);
- GNUNET_memcpy (&m[1],
- ar->address,
- alen);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Adding address `%s' for peer `%s'\n",
- ar->address,
- GNUNET_i2s (&ar->pid));
- GNUNET_MQ_send (ath->mq,
- ev);
-}
-
-
-/**
- * Send ATS information about the session record.
- *
- * @param cls our `struct GNUNET_ATS_TransportHandle *`, unused
- * @param pid unused
- * @param value the `struct GNUNET_ATS_SessionRecord *` to add
- * @return #GNUNET_OK
- */
-static int
-send_add_session_cb (void *cls,
- const struct GNUNET_PeerIdentity *pid,
- void *value)
-{
- struct GNUNET_ATS_SessionRecord *ar = value;
-
- (void) cls;
- (void) pid;
- send_add_session_message (ar);
- return GNUNET_OK;
-}
-
-
-/**
- * Re-establish the connection to the ATS service.
- *
- * @param ath handle to use to re-connect.
- */
-static void
-reconnect (struct GNUNET_ATS_TransportHandle *ath)
-{
- struct GNUNET_MQ_MessageHandler handlers[] = {
- GNUNET_MQ_hd_var_size (ats_address_suggestion,
- GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION,
- struct AddressSuggestionMessage,
- ath),
- GNUNET_MQ_hd_fixed_size (ats_session_allocation,
- GNUNET_MESSAGE_TYPE_ATS_SESSION_ALLOCATION,
- struct SessionAllocationMessage,
- ath),
- GNUNET_MQ_handler_end ()
- };
- struct GNUNET_MQ_Envelope *ev;
- struct GNUNET_MessageHeader *init;
-
- GNUNET_assert (NULL == ath->mq);
- ath->mq = GNUNET_CLIENT_connect (ath->cfg,
- "ats",
- handlers,
- &error_handler,
- ath);
- if (NULL == ath->mq)
- {
- GNUNET_break (0);
- force_reconnect (ath);
- return;
- }
- ev = GNUNET_MQ_msg (init,
- GNUNET_MESSAGE_TYPE_ATS_START);
- GNUNET_MQ_send (ath->mq,
- ev);
- if (NULL == ath->mq)
- return;
- GNUNET_CONTAINER_multipeermap_iterate (ath->records,
- &send_add_session_cb,
- ath);
-}
-
-
-/**
- * Initialize the ATS subsystem.
- *
- * @param cfg configuration to use
- * @param alloc_cb notification to call whenever the allocation changed
- * @param alloc_cb_cls closure for @a alloc_cb
- * @param suggest_cb notification to call whenever the suggestation is made
- * @param suggest_cb_cls closure for @a suggest_cb
- * @return ats context
- */
-struct GNUNET_ATS_TransportHandle *
-GNUNET_ATS_transport_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_ATS_AllocationCallback alloc_cb,
- void *alloc_cb_cls,
- GNUNET_ATS_SuggestionCallback suggest_cb,
- void *suggest_cb_cls)
-{
- struct GNUNET_ATS_TransportHandle *ath;
-
- ath = GNUNET_new (struct GNUNET_ATS_TransportHandle);
- ath->cfg = cfg;
- ath->suggest_cb = suggest_cb;
- ath->suggest_cb_cls = suggest_cb_cls;
- ath->alloc_cb = alloc_cb;
- ath->alloc_cb_cls = alloc_cb_cls;
- ath->records = GNUNET_CONTAINER_multipeermap_create (128,
- GNUNET_YES);
- reconnect (ath);
- return ath;
-}
-
-
-/**
- * Release memory associated with the session record.
- *
- * @param cls NULL
- * @param pid unused
- * @param value a `struct GNUNET_ATS_SessionRecord`
- * @return #GNUNET_OK
- */
-static int
-free_record (void *cls,
- const struct GNUNET_PeerIdentity *pid,
- void *value)
-{
- struct GNUNET_ATS_SessionRecord *ar = value;
-
- (void) cls;
- (void) pid;
- GNUNET_free (ar);
- return GNUNET_OK;
-}
-
-
-/**
- * Client is done with ATS transport, release resources.
- *
- * @param ath handle to release
- */
-void
-GNUNET_ATS_transport_done (struct GNUNET_ATS_TransportHandle *ath)
-{
- if (NULL != ath->mq)
- {
- GNUNET_MQ_destroy (ath->mq);
- ath->mq = NULL;
- }
- if (NULL != ath->task)
- {
- GNUNET_SCHEDULER_cancel (ath->task);
- ath->task = NULL;
- }
- GNUNET_CONTAINER_multipeermap_iterate (ath->records,
- &free_record,
- NULL);
- GNUNET_CONTAINER_multipeermap_destroy (ath->records);
- GNUNET_free (ath);
-}
-
-
-/**
- * We have a new session ATS should know. Sessiones have to be added
- * with this function before they can be: updated, set in use and
- * destroyed.
- *
- * @param ath handle
- * @param pid peer we connected to
- * @param address the address (human readable version)
- * @param session transport-internal handle for the session/queue, NULL if
- * the session is inbound-only
- * @param prop performance data for the session
- * @return handle to the session representation inside ATS, NULL
- * on error (i.e. ATS knows this exact session already)
- */
-struct GNUNET_ATS_SessionRecord *
-GNUNET_ATS_session_add (struct GNUNET_ATS_TransportHandle *ath,
- const struct GNUNET_PeerIdentity *pid,
- const char *address,
- struct GNUNET_ATS_Session *session,
- const struct GNUNET_ATS_Properties *prop)
-{
- struct GNUNET_ATS_SessionRecord *ar;
- uint32_t s;
- size_t alen;
-
- if (NULL == address)
- {
- /* we need a valid address */
- GNUNET_break (0);
- return NULL;
- }
- alen = strlen (address) + 1;
- if ((alen + sizeof(struct SessionAddMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
- (alen >= GNUNET_MAX_MESSAGE_SIZE))
- {
- /* address too large for us, this should not happen */
- GNUNET_break (0);
- return NULL;
- }
-
- /* Spin 's' until we find an unused session ID for this pid */
- for (s = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
- UINT32_MAX);
- NULL != find_session (ath,
- s,
- pid);
- s++)
- ;
-
- alen = strlen (address) + 1;
- ar = GNUNET_malloc (sizeof(struct GNUNET_ATS_SessionRecord) + alen);
- ar->ath = ath;
- ar->slot = s;
- ar->session = session;
- ar->address = (const char *) &ar[1];
- ar->pid = *pid;
- ar->properties = *prop;
- memcpy (&ar[1],
- address,
- alen);
- (void) GNUNET_CONTAINER_multipeermap_put (ath->records,
- &ar->pid,
- ar,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- send_add_session_message (ar);
- return ar;
-}
-
-
-/**
- * We have updated performance statistics for a given session. Note
- * that this function can be called for sessiones that are currently
- * in use as well as sessiones that are valid but not actively in use.
- * Furthermore, the peer may not even be connected to us right now (in
- * which case the call may be ignored or the information may be stored
- * for later use). Update bandwidth assignments.
- *
- * @param ar session record to update information for
- * @param prop performance data for the session
- */
-void
-GNUNET_ATS_session_update (struct GNUNET_ATS_SessionRecord *ar,
- const struct GNUNET_ATS_Properties *prop)
-{
- struct GNUNET_ATS_TransportHandle *ath = ar->ath;
- struct GNUNET_MQ_Envelope *ev;
- struct SessionUpdateMessage *m;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Updating address `%s' for peer `%s'\n",
- ar->address,
- GNUNET_i2s (&ar->pid));
- ar->properties = *prop;
- if (NULL == ath->mq)
- return; /* disconnected, skip for now */
- ev = GNUNET_MQ_msg (m,
- GNUNET_MESSAGE_TYPE_ATS_SESSION_UPDATE);
- m->session_id = htonl (ar->slot);
- m->peer = ar->pid;
- properties_hton (&m->properties,
- &ar->properties);
- GNUNET_MQ_send (ath->mq,
- ev);
-}
-
-
-/**
- * A session was destroyed, ATS should now schedule and
- * allocate under the assumption that this @a ar is no
- * longer in use.
- *
- * @param ar session record to drop
- */
-void
-GNUNET_ATS_session_del (struct GNUNET_ATS_SessionRecord *ar)
-{
- struct GNUNET_ATS_TransportHandle *ath = ar->ath;
- struct GNUNET_MQ_Envelope *ev;
- struct SessionDelMessage *m;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Deleting address `%s' for peer `%s'\n",
- ar->address,
- GNUNET_i2s (&ar->pid));
- if (NULL == ath->mq)
- return;
- ev = GNUNET_MQ_msg (m,
- GNUNET_MESSAGE_TYPE_ATS_SESSION_DEL);
- m->session_id = htonl (ar->slot);
- m->peer = ar->pid;
- GNUNET_MQ_send (ath->mq,
- ev);
-}
-
-
-/* end of ats_api2_transport.c */
diff --git a/src/ats/gnunet-service-ats-new.c b/src/ats/gnunet-service-ats-new.c
deleted file mode 100644
index f2ef92436..000000000
--- a/src/ats/gnunet-service-ats-new.c
+++ /dev/null
@@ -1,804 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2011, 2018 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-/**
- * @file ats/gnunet-service-ats-new.c
- * @brief ats service
- * @author Matthias Wachs
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_statistics_service.h"
-#include "gnunet_ats_plugin_new.h"
-#include "ats2.h"
-
-
-/**
- * What type of client is this client?
- */
-enum ClientType
-{
- /**
- * We don't know yet.
- */
- CT_NONE = 0,
-
- /**
- * Transport service.
- */
- CT_TRANSPORT,
-
- /**
- * Application.
- */
- CT_APPLICATION
-};
-
-
-/**
- * Information we track per client.
- */
-struct Client;
-
-/**
- * Preferences expressed by a client are kept in a DLL per client.
- */
-struct ClientPreference
-{
- /**
- * DLL pointer.
- */
- struct ClientPreference *next;
-
- /**
- * DLL pointer.
- */
- struct ClientPreference *prev;
-
- /**
- * Which client expressed the preference?
- */
- struct Client *client;
-
- /**
- * Plugin's representation of the preference.
- */
- struct GNUNET_ATS_PreferenceHandle *ph;
-
- /**
- * Details about the preference.
- */
- struct GNUNET_ATS_Preference pref;
-};
-
-
-/**
- * Information about ongoing sessions of the transport client.
- */
-struct GNUNET_ATS_Session
-{
- /**
- * Session data exposed to the plugin.
- */
- struct GNUNET_ATS_SessionData data;
-
- /**
- * The transport client that provided the session.
- */
- struct Client *client;
-
- /**
- * Session state in the plugin.
- */
- struct GNUNET_ATS_SessionHandle *sh;
-
- /**
- * Unique ID for the session when talking with the client.
- */
- uint32_t session_id;
-};
-
-
-/**
- * Information we track per client.
- */
-struct Client
-{
- /**
- * Type of the client, initially #CT_NONE.
- */
- enum ClientType type;
-
- /**
- * Service handle of the client.
- */
- struct GNUNET_SERVICE_Client *client;
-
- /**
- * Message queue to talk to the client.
- */
- struct GNUNET_MQ_Handle *mq;
-
- /**
- * Details depending on @e type.
- */
- union
- {
- struct
- {
- /**
- * Head of DLL of preferences expressed by this client.
- */
- struct ClientPreference *cp_head;
-
- /**
- * Tail of DLL of preferences expressed by this client.
- */
- struct ClientPreference *cp_tail;
- } application;
-
- struct
- {
- /**
- * Map from session IDs to `struct GNUNET_ATS_Session` objects.
- */
- struct GNUNET_CONTAINER_MultiHashMap32 *sessions;
- } transport;
- } details;
-};
-
-
-/**
- * Handle for statistics.
- */
-static struct GNUNET_STATISTICS_Handle *stats;
-
-/**
- * Our solver.
- */
-static struct GNUNET_ATS_SolverFunctions *plugin;
-
-/**
- * Solver plugin name as string
- */
-static char *plugin_name;
-
-/**
- * The transport client (there can only be one at a time).
- */
-static struct Client *transport_client;
-
-
-/**
- * Function called by the solver to prompt the transport to
- * try out a new address.
- *
- * @param cls closure, NULL
- * @param pid peer this is about
- * @param address address the transport should try
- */
-static void
-suggest_cb (void *cls,
- const struct GNUNET_PeerIdentity *pid,
- const char *address)
-{
- struct GNUNET_MQ_Envelope *env;
- size_t slen = strlen (address) + 1;
- struct AddressSuggestionMessage *as;
-
- if (NULL == transport_client)
- {
- // FIXME: stats!
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Suggesting address `%s' of peer `%s'\n",
- address,
- GNUNET_i2s (pid));
- env = GNUNET_MQ_msg_extra (as,
- slen,
- GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION);
- as->peer = *pid;
- memcpy (&as[1],
- address,
- slen);
- GNUNET_MQ_send (transport_client->mq,
- env);
-}
-
-
-/**
- * Function called by the solver to tell the transpor to
- * allocate bandwidth for the specified session.
- *
- * @param cls closure, NULL
- * @param session session this is about
- * @param peer peer this is about
- * @param bw_in suggested bandwidth for receiving
- * @param bw_out suggested bandwidth for transmission
- */
-static void
-allocate_cb (void *cls,
- struct GNUNET_ATS_Session *session,
- const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_BANDWIDTH_Value32NBO bw_in,
- struct GNUNET_BANDWIDTH_Value32NBO bw_out)
-{
- struct GNUNET_MQ_Envelope *env;
- struct SessionAllocationMessage *sam;
-
- (void) cls;
- if ((NULL == transport_client) ||
- (session->client != transport_client))
- {
- /* transport must have just died and solver is addressing the
- losses of sessions (possibly of previous transport), ignore! */
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Allocating %u/%u bytes for %p of peer `%s'\n",
- ntohl (bw_in.value__),
- ntohl (bw_out.value__),
- session,
- GNUNET_i2s (peer));
- env = GNUNET_MQ_msg (sam,
- GNUNET_MESSAGE_TYPE_ATS_SESSION_ALLOCATION);
- sam->session_id = session->session_id;
- sam->peer = *peer;
- sam->bandwidth_in = bw_in;
- sam->bandwidth_out = bw_out;
- GNUNET_MQ_send (transport_client->mq,
- env);
-}
-
-
-/**
- * Convert @a properties to @a prop
- *
- * @param properties in NBO
- * @param prop[out] in HBO
- */
-static void
-prop_ntoh (const struct PropertiesNBO *properties,
- struct GNUNET_ATS_Properties *prop)
-{
- prop->delay = GNUNET_TIME_relative_ntoh (properties->delay);
- prop->goodput_out = ntohl (properties->goodput_out);
- prop->goodput_in = ntohl (properties->goodput_in);
- prop->utilization_out = ntohl (properties->utilization_out);
- prop->utilization_in = ntohl (properties->utilization_in);
- prop->distance = ntohl (properties->distance);
- prop->mtu = ntohl (properties->mtu);
- prop->nt = (enum GNUNET_NetworkType) ntohl (properties->nt);
- prop->cc = (enum GNUNET_TRANSPORT_CommunicatorCharacteristics) ntohl (
- properties->cc);
-}
-
-
-/**
- * We have received a `struct ExpressPreferenceMessage` from an application client.
- *
- * @param cls handle to the client
- * @param msg the start message
- */
-static void
-handle_suggest (void *cls,
- const struct ExpressPreferenceMessage *msg)
-{
- struct Client *c = cls;
- struct ClientPreference *cp;
-
- if (CT_NONE == c->type)
- c->type = CT_APPLICATION;
- if (CT_APPLICATION != c->type)
- {
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (c->client);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Client suggested we talk to %s with preference %d at rate %u\n",
- GNUNET_i2s (&msg->peer),
- (int) ntohl (msg->pk),
- (int) ntohl (msg->bw.value__));
- cp = GNUNET_new (struct ClientPreference);
- cp->client = c;
- cp->pref.peer = msg->peer;
- cp->pref.bw = msg->bw;
- cp->pref.pk = (enum GNUNET_MQ_PreferenceKind) ntohl (msg->pk);
- cp->ph = plugin->preference_add (plugin->cls,
- &cp->pref);
- GNUNET_CONTAINER_DLL_insert (c->details.application.cp_head,
- c->details.application.cp_tail,
- cp);
- GNUNET_SERVICE_client_continue (c->client);
-}
-
-
-/**
- * We have received a `struct ExpressPreferenceMessage` from an application client.
- *
- * @param cls handle to the client
- * @param msg the start message
- */
-static void
-handle_suggest_cancel (void *cls,
- const struct ExpressPreferenceMessage *msg)
-{
- struct Client *c = cls;
- struct ClientPreference *cp;
-
- if (CT_NONE == c->type)
- c->type = CT_APPLICATION;
- if (CT_APPLICATION != c->type)
- {
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (c->client);
- return;
- }
- for (cp = c->details.application.cp_head;
- NULL != cp;
- cp = cp->next)
- if ((cp->pref.pk == (enum GNUNET_MQ_PreferenceKind) ntohl (msg->pk)) &&
- (cp->pref.bw.value__ == msg->bw.value__) &&
- (0 == GNUNET_memcmp (&cp->pref.peer,
- &msg->peer)))
- break;
- if (NULL == cp)
- {
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (c->client);
- return;
- }
- plugin->preference_del (plugin->cls,
- cp->ph,
- &cp->pref);
- GNUNET_CONTAINER_DLL_remove (c->details.application.cp_head,
- c->details.application.cp_tail,
- cp);
- GNUNET_free (cp);
- GNUNET_SERVICE_client_continue (c->client);
-}
-
-
-/**
- * Handle 'start' messages from transport clients.
- *
- * @param cls client that sent the request
- * @param message the request message
- */
-static void
-handle_start (void *cls,
- const struct GNUNET_MessageHeader *hdr)
-{
- struct Client *c = cls;
-
- if (CT_NONE != c->type)
- {
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (c->client);
- return;
- }
- c->type = CT_TRANSPORT;
- c->details.transport.sessions
- = GNUNET_CONTAINER_multihashmap32_create (128);
- if (NULL != transport_client)
- {
- GNUNET_SERVICE_client_drop (transport_client->client);
- transport_client = NULL;
- }
- transport_client = c;
- GNUNET_SERVICE_client_continue (c->client);
-}
-
-
-/**
- * Check 'session_add' message is well-formed and comes from a
- * transport client.
- *
- * @param cls client that sent the request
- * @param message the request message
- * @return #GNUNET_OK if @a message is well-formed
- */
-static int
-check_session_add (void *cls,
- const struct SessionAddMessage *message)
-{
- struct Client *c = cls;
-
- GNUNET_MQ_check_zero_termination (message);
- if (CT_TRANSPORT != c->type)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Handle 'session add' messages from transport clients.
- *
- * @param cls client that sent the request
- * @param message the request message
- */
-static void
-handle_session_add (void *cls,
- const struct SessionAddMessage *message)
-{
- struct Client *c = cls;
- const char *address = (const char *) &message[1];
- struct GNUNET_ATS_Session *session;
- int inbound_only = (GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY ==
- ntohs (message->header.type));
-
- session = GNUNET_CONTAINER_multihashmap32_get (c->details.transport.sessions,
- message->session_id);
- if (NULL != session)
- {
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (c->client);
- return;
- }
- session = GNUNET_new (struct GNUNET_ATS_Session);
- session->data.session = session;
- session->client = c;
- session->session_id = message->session_id;
- session->data.peer = message->peer;
- prop_ntoh (&message->properties,
- &session->data.prop);
- session->data.inbound_only = inbound_only;
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap32_put (
- c->details.transport.sessions,
- message->session_id,
- session,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
- session->sh = plugin->session_add (plugin->cls,
- &session->data,
- address);
- GNUNET_assert (NULL != session->sh);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Transport has new session %p to %s\n",
- session,
- GNUNET_i2s (&message->peer));
- GNUNET_SERVICE_client_continue (c->client);
-}
-
-
-/**
- * Handle 'session update' messages from transport clients.
- *
- * @param cls client that sent the request
- * @param msg the request message
- */
-static void
-handle_session_update (void *cls,
- const struct SessionUpdateMessage *msg)
-{
- struct Client *c = cls;
- struct GNUNET_ATS_Session *session;
-
- if (CT_TRANSPORT != c->type)
- {
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (c->client);
- return;
- }
- session = GNUNET_CONTAINER_multihashmap32_get (c->details.transport.sessions,
- msg->session_id);
- if (NULL == session)
- {
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (c->client);
- return;
- }
- prop_ntoh (&msg->properties,
- &session->data.prop);
- plugin->session_update (plugin->cls,
- session->sh,
- &session->data);
- GNUNET_SERVICE_client_continue (c->client);
-}
-
-
-/**
- * Handle 'session delete' messages from transport clients.
- *
- * @param cls client that sent the request
- * @param message the request message
- */
-static void
-handle_session_del (void *cls,
- const struct SessionDelMessage *message)
-{
- struct Client *c = cls;
- struct GNUNET_ATS_Session *session;
-
- if (CT_TRANSPORT != c->type)
- {
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (c->client);
- return;
- }
- session = GNUNET_CONTAINER_multihashmap32_get (c->details.transport.sessions,
- message->session_id);
- if (NULL == session)
- {
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (c->client);
- return;
- }
- GNUNET_assert (NULL != session->sh);
- plugin->session_del (plugin->cls,
- session->sh,
- &session->data);
- session->sh = NULL;
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap32_remove (
- c->details.transport.sessions,
- session->session_id,
- session));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Transport lost session %p to %s\n",
- session,
- GNUNET_i2s (&session->data.peer));
- GNUNET_free (session);
- GNUNET_SERVICE_client_continue (c->client);
-}
-
-
-/**
- * A client connected to us. Setup the local client
- * record.
- *
- * @param cls unused
- * @param client handle of the client
- * @param mq message queue to talk to @a client
- * @return @a client
- */
-static void *
-client_connect_cb (void *cls,
- struct GNUNET_SERVICE_Client *client,
- struct GNUNET_MQ_Handle *mq)
-{
- struct Client *c = GNUNET_new (struct Client);
-
- c->client = client;
- c->mq = mq;
- return c;
-}
-
-
-/**
- * Function called on each session to release associated state
- * on transport disconnect.
- *
- * @param cls the `struct Client`
- * @param key unused (session_id)
- * @param value a `struct GNUNET_ATS_Session`
- */
-static int
-free_session (void *cls,
- uint32_t key,
- void *value)
-{
- struct Client *c = cls;
- struct GNUNET_ATS_Session *session = value;
-
- (void) key;
- GNUNET_assert (c == session->client);
- GNUNET_assert (NULL != session->sh);
- plugin->session_del (plugin->cls,
- session->sh,
- &session->data);
- session->sh = NULL;
- GNUNET_free (session);
- return GNUNET_OK;
-}
-
-
-/**
- * A client disconnected from us. Tear down the local client
- * record.
- *
- * @param cls unused
- * @param client handle of the client
- * @param app_ctx our `struct Client`
- */
-static void
-client_disconnect_cb (void *cls,
- struct GNUNET_SERVICE_Client *client,
- void *app_ctx)
-{
- struct Client *c = app_ctx;
-
- (void) cls;
- GNUNET_assert (c->client == client);
- switch (c->type)
- {
- case CT_NONE:
- break;
-
- case CT_APPLICATION:
- for (struct ClientPreference *cp = c->details.application.cp_head;
- NULL != cp;
- cp = c->details.application.cp_head)
- {
- plugin->preference_del (plugin->cls,
- cp->ph,
- &cp->pref);
- GNUNET_CONTAINER_DLL_remove (c->details.application.cp_head,
- c->details.application.cp_tail,
- cp);
- GNUNET_free (cp);
- }
- break;
-
- case CT_TRANSPORT:
- if (transport_client == c)
- transport_client = NULL;
- GNUNET_CONTAINER_multihashmap32_iterate (c->details.transport.sessions,
- &free_session,
- c);
- GNUNET_CONTAINER_multihashmap32_destroy (c->details.transport.sessions);
- break;
- }
- GNUNET_free (c);
-}
-
-
-/**
- * Task run at the end during shutdown.
- *
- * @param cls unused
- */
-static void
-final_cleanup (void *cls)
-{
- (void) cls;
- if (NULL != stats)
- {
- GNUNET_STATISTICS_destroy (stats,
- GNUNET_NO);
- stats = NULL;
- }
- if (NULL != plugin)
- {
- GNUNET_PLUGIN_unload (plugin_name,
- plugin);
- plugin = NULL;
- }
- if (NULL != plugin_name)
- {
- GNUNET_free (plugin_name);
- plugin_name = NULL;
- }
-}
-
-
-/**
- * Task run during shutdown.
- *
- * @param cls unused
- */
-static void
-cleanup_task (void *cls)
-{
- (void) cls;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "ATS shutdown initiated\n");
- GNUNET_SCHEDULER_add_now (&final_cleanup,
- NULL);
-}
-
-
-/**
- * Process template requests.
- *
- * @param cls closure
- * @param cfg configuration to use
- * @param service the initialized service
- */
-static void
-run (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_SERVICE_Handle *service)
-{
- static struct GNUNET_ATS_PluginEnvironment env;
- char *solver;
-
- stats = GNUNET_STATISTICS_create ("ats",
- cfg);
- if (GNUNET_SYSERR ==
- GNUNET_CONFIGURATION_get_value_string (cfg,
- "ats",
- "SOLVER",
- &solver))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "No ATS solver configured, using 'simple' approach\n");
- solver = GNUNET_strdup ("simple");
- }
- GNUNET_SCHEDULER_add_shutdown (&cleanup_task,
- NULL);
- env.cls = NULL;
- env.cfg = cfg;
- env.stats = stats;
- env.suggest_cb = &suggest_cb;
- env.allocate_cb = &allocate_cb;
- GNUNET_asprintf (&plugin_name,
- "libgnunet_plugin_ats2_%s",
- solver);
- GNUNET_free (solver);
- if (NULL == (plugin = GNUNET_PLUGIN_load (plugin_name,
- &env)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _ ("Failed to initialize solver `%s'!\n"),
- plugin_name);
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-}
-
-
-/**
- * Define "main" method using service macro.
- */
-GNUNET_SERVICE_MAIN
- ("ats",
- GNUNET_SERVICE_OPTION_NONE,
- &run,
- &client_connect_cb,
- &client_disconnect_cb,
- NULL,
- GNUNET_MQ_hd_fixed_size (suggest,
- GNUNET_MESSAGE_TYPE_ATS_SUGGEST,
- struct ExpressPreferenceMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (suggest_cancel,
- GNUNET_MESSAGE_TYPE_ATS_SUGGEST_CANCEL,
- struct ExpressPreferenceMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (start,
- GNUNET_MESSAGE_TYPE_ATS_START,
- struct GNUNET_MessageHeader,
- NULL),
- GNUNET_MQ_hd_var_size (session_add,
- GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD,
- struct SessionAddMessage,
- NULL),
- GNUNET_MQ_hd_var_size (session_add,
- GNUNET_MESSAGE_TYPE_ATS_SESSION_ADD_INBOUND_ONLY,
- struct SessionAddMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (session_update,
- GNUNET_MESSAGE_TYPE_ATS_SESSION_UPDATE,
- struct SessionUpdateMessage,
- NULL),
- GNUNET_MQ_hd_fixed_size (session_del,
- GNUNET_MESSAGE_TYPE_ATS_SESSION_DEL,
- struct SessionDelMessage,
- NULL),
- GNUNET_MQ_handler_end ());
-
-
-/* end of gnunet-service-ats.c */
diff --git a/src/ats/perf_ats_solver_mlp.conf b/src/ats/perf_ats_solver_mlp.conf
deleted file mode 100644
index e69de29bb..000000000
--- a/src/ats/perf_ats_solver_mlp.conf
+++ /dev/null
diff --git a/src/ats/perf_ats_solver_ril.conf b/src/ats/perf_ats_solver_ril.conf
deleted file mode 100644
index e69de29bb..000000000
--- a/src/ats/perf_ats_solver_ril.conf
+++ /dev/null
diff --git a/src/ats/plugin_ats2_common.c b/src/ats/plugin_ats2_common.c
deleted file mode 100644
index da20a342c..000000000
--- a/src/ats/plugin_ats2_common.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2011-2015, 2018 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-/**
- * @file ats/plugin_ats2_common.c
- * @brief ATS solver helper functions to be inlined
- * @author Matthias Wachs
- * @author Christian Grothoff
- */
-
-/**
- * Default bandwidth assigned to a network: 64 KB/s
- */
-#define DEFAULT_BANDWIDTH 65536
-
-
-/**
- * Parse @a cfg for @a quota as specified for @a direction of
- * network type @a nts.
- *
- * @param cfg configuration to parse
- * @param nts network type string to get quota for
- * @param direction direction to get quota for ("IN" or "OUT")
- * @param quota[out] set to quota, #DEFAULT_BANDWIDTH if @a cfg does not say anything useful
- */
-static void
-get_quota (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *nts,
- const char *direction,
- unsigned long long *quota)
-{
- char *quota_str;
- char *quota_s;
- int res;
-
- GNUNET_asprintf (&quota_s,
- "%s_QUOTA_%s",
- nts,
- direction);
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (cfg,
- "ATS",
- quota_s,
- &quota_str))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
- "ATS",
- quota_s);
- GNUNET_free (quota_s);
- return;
- }
- GNUNET_free (quota_s);
- res = GNUNET_NO;
- if (0 == strcmp (quota_str,
- "unlimited"))
- {
- *quota = ULONG_MAX;
- res = GNUNET_YES;
- }
- if ((GNUNET_NO == res) &&
- (GNUNET_OK ==
- GNUNET_STRINGS_fancy_size_to_bytes (quota_str,
- quota)))
- res = GNUNET_YES;
- if ((GNUNET_NO == res) &&
- (1 ==
- sscanf (quota_str,
- "%llu",
- quota)))
- res = GNUNET_YES;
- if (GNUNET_NO == res)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _ (
- "Could not load %s quota for network `%s': `%s', assigning default bandwidth %llu\n"),
- direction,
- nts,
- quota_str,
- (unsigned long long) DEFAULT_BANDWIDTH);
- *quota = DEFAULT_BANDWIDTH;
- }
- GNUNET_free (quota_str);
-}
diff --git a/src/ats/plugin_ats2_simple.c b/src/ats/plugin_ats2_simple.c
deleted file mode 100644
index 3062b6019..000000000
--- a/src/ats/plugin_ats2_simple.c
+++ /dev/null
@@ -1,1087 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2011-2015, 2018 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-/**
- * @file ats/plugin_ats2_simple.c
- * @brief ATS simple solver
- * @author Matthias Wachs
- * @author Christian Grothoff
- *
- * TODO:
- * - needs testing
- */
-#include "platform.h"
-#include "gnunet_ats_plugin_new.h"
-#include "gnunet_hello_lib.h"
-#include "gnunet_peerstore_service.h"
-
-#define LOG(kind, ...) GNUNET_log_from (kind, "ats-simple", __VA_ARGS__)
-
-
-/**
- * Base frequency at which we suggest addresses to transport.
- * Multiplied by the square of the number of active connections
- * (and randomized) to calculate the actual frequency at which
- * we will suggest addresses to the transport. Furthermore, each
- * address is also bounded by an exponential back-off.
- */
-#define SUGGEST_FREQ GNUNET_TIME_UNIT_SECONDS
-
-/**
- * What is the minimum bandwidth we always try to allocate for
- * any session that is up? (May still be scaled down lower if
- * the number of sessions is so high that the total bandwidth
- * is insufficient to allow for this value to be granted.)
- */
-#define MIN_BANDWIDTH_PER_SESSION 1024
-
-
-/**
- * A handle for the proportional solver
- */
-struct SimpleHandle;
-
-
-/**
- * Information about preferences and sessions we track
- * per peer.
- */
-struct Peer;
-
-
-/**
- * Entry in list of addresses we could try per peer.
- */
-struct Hello
-{
- /**
- * Kept in a DLL.
- */
- struct Hello *next;
-
- /**
- * Kept in a DLL.
- */
- struct Hello *prev;
-
- /**
- * Peer this hello belongs to.
- */
- struct Peer *peer;
-
- /**
- * The address we could try.
- */
- const char *address;
-
- /**
- * Is a session with this address already up?
- * If not, set to NULL.
- */
- struct GNUNET_ATS_SessionHandle *sh;
-
- /**
- * When does the HELLO expire?
- */
- struct GNUNET_TIME_Absolute expiration;
-
- /**
- * When did we try it last?
- */
- struct GNUNET_TIME_Absolute last_attempt;
-
- /**
- * Current exponential backoff value.
- */
- struct GNUNET_TIME_Relative backoff;
-
- /**
- * Type of the network for this HELLO.
- */
- enum GNUNET_NetworkType nt;
-};
-
-
-/**
- * Internal representation of a session by the plugin.
- * (If desired, plugin may just use NULL.)
- */
-struct GNUNET_ATS_SessionHandle
-{
- /**
- * Kept in DLL per peer.
- */
- struct GNUNET_ATS_SessionHandle *next;
-
- /**
- * Kept in DLL per peer.
- */
- struct GNUNET_ATS_SessionHandle *prev;
-
- /**
- * The session in the main ATS service.
- */
- struct GNUNET_ATS_Session *session;
-
- /**
- * Current performance data for this @e session
- */
- const struct GNUNET_ATS_SessionData *data;
-
- /**
- * Hello matching this session, or NULL for none.
- */
- struct Hello *hello;
-
- /**
- * Peer this session is for.
- */
- struct Peer *peer;
-
- /**
- * Address used by this session (largely for debugging).
- */
- const char *address;
-
- /**
- * When did we last update transport about the allocation?
- * Used to dampen the frequency of updates.
- */
- struct GNUNET_TIME_Absolute last_allocation;
-
- /**
- * Last BW-in allocation given to the transport service.
- */
- struct GNUNET_BANDWIDTH_Value32NBO bw_in;
-
- /**
- * Last BW-out allocation given to the transport service.
- */
- struct GNUNET_BANDWIDTH_Value32NBO bw_out;
-
- /**
- * New BW-in allocation given to the transport service.
- */
- uint64_t target_in;
-
- /**
- * New BW-out allocation given to the transport service.
- */
- uint64_t target_out;
-};
-
-
-/**
- * Information about preferences and sessions we track
- * per peer.
- */
-struct Peer
-{
- /**
- * Kept in DLL per peer.
- */
- struct GNUNET_ATS_SessionHandle *sh_head;
-
- /**
- * Kept in DLL per peer.
- */
- struct GNUNET_ATS_SessionHandle *sh_tail;
-
- /**
- * Kept in a DLL.
- */
- struct Hello *h_head;
-
- /**
- * Kept in a DLL.
- */
- struct Hello *h_tail;
-
- /**
- * The handle for the proportional solver
- */
- struct SimpleHandle *h;
-
- /**
- * Watch context where we are currently looking for HELLOs for
- * this peer.
- */
- struct GNUNET_PEERSTORE_WatchContext *wc;
-
- /**
- * Task used to try again to suggest an address for this peer.
- */
- struct GNUNET_SCHEDULER_Task *task;
-
- /**
- * Which peer is this for?
- */
- struct GNUNET_PeerIdentity pid;
-
- /**
- * When did we last suggest an address to connect to for this peer?
- */
- struct GNUNET_TIME_Absolute last_suggestion;
-
- /**
- * Array where we sum up the bandwidth requests received indexed
- * by preference kind (see `enum GNUNET_MQ_PreferenceKind`)
- */
- uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT];
-};
-
-
-/**
- * Representation of a network (to be expanded...)
- */
-struct Network
-{
- /**
- * Total inbound quota
- */
- unsigned long long total_quota_in;
-
- /**
- * Total outbound quota
- */
- unsigned long long total_quota_out;
-
- /**
- * ATS network type
- */
- enum GNUNET_NetworkType type;
-};
-
-
-/**
- * A handle for the proportional solver
- */
-struct SimpleHandle
-{
- /**
- * Our execution environment.
- */
- struct GNUNET_ATS_PluginEnvironment *env;
-
- /**
- * Information we track for each peer.
- */
- struct GNUNET_CONTAINER_MultiPeerMap *peers;
-
- /**
- * Handle to the peerstore service.
- */
- struct GNUNET_PEERSTORE_Handle *ps;
-
- /**
- * Array where we sum up the bandwidth requests received indexed
- * by preference kind (see `enum GNUNET_MQ_PreferenceKind`) (sums
- * over all peers).
- */
- uint64_t bw_by_pk[GNUNET_MQ_PREFERENCE_COUNT];
-
- /**
- * Information we track per network type (quotas).
- */
- struct Network networks[GNUNET_NT_COUNT];
-};
-
-
-/**
- * Lookup peer in the peers map.
- *
- * @param h handle to look up in
- * @param pid peer identity to look up by
- * @return NULL for not found
- */
-struct Peer *
-lookup_peer (struct SimpleHandle *h, const struct GNUNET_PeerIdentity *pid)
-{
- return GNUNET_CONTAINER_multipeermap_get (h->peers, pid);
-}
-
-
-/**
- * Check if there is _any_ interesting information left we
- * store about the peer in @a p.
- *
- * @param p peer to test if we can drop the data structure
- * @return #GNUNET_YES if no information is left in @a p
- */
-static int
-peer_test_dead (struct Peer *p)
-{
- for (enum GNUNET_MQ_PreferenceKind pk = 0; pk < GNUNET_MQ_PREFERENCE_COUNT;
- pk++)
- if (0 != p->bw_by_pk[pk])
- return GNUNET_NO;
- if (NULL != p->sh_head)
- return GNUNET_NO;
- return GNUNET_YES;
-}
-
-
-/**
- * Contact the transport service and suggest to it to
- * try connecting to the address of @a hello. Updates
- * backoff and timestamp values in the @a hello.
- *
- * @param hello[in,out] address suggestion to make
- */
-static void
-suggest_hello (struct Hello *hello)
-{
- struct Peer *p = hello->peer;
- struct SimpleHandle *h = p->h;
-
- p->last_suggestion = hello->last_attempt = GNUNET_TIME_absolute_get ();
- hello->backoff =
- GNUNET_TIME_randomized_backoff (hello->backoff,
- GNUNET_TIME_absolute_get_remaining (
- hello->expiration));
- h->env->suggest_cb (h->env->cls, &p->pid, hello->address);
-}
-
-
-/**
- * Consider suggesting a HELLO (without a session) to transport.
- * We look at how many active sessions we have for the peer, and
- * if there are many, reduce the frequency of trying new addresses.
- * Also, for each address we consider when we last tried it, and
- * its exponential backoff if the attempt failed. Note that it
- * is possible that this function is called when no suggestion
- * is to be made.
- *
- * In this case, we only calculate the time until we make the next
- * suggestion.
- *
- * @param cls a `struct Peer`
- */
-static void
-suggest_start_cb (void *cls)
-{
- struct Peer *p = cls;
- struct GNUNET_TIME_Relative delay = GNUNET_TIME_UNIT_ZERO;
- struct Hello *hello = NULL;
- struct GNUNET_TIME_Absolute hpt = GNUNET_TIME_UNIT_FOREVER_ABS;
- struct GNUNET_TIME_Relative xdelay;
- struct GNUNET_TIME_Absolute xnext;
- unsigned int num_sessions = 0;
- uint32_t sq;
-
- /* count number of active sessions */
- for (struct GNUNET_ATS_SessionHandle *sh = p->sh_head; NULL != sh;
- sh = sh->next)
- num_sessions++;
- /* calculate square of number of sessions */
- num_sessions++; /* start with 1, even if we have zero sessions */
- if (num_sessions < UINT16_MAX)
- sq = num_sessions * (uint32_t) num_sessions;
- else
- sq = UINT32_MAX;
- xdelay =
- GNUNET_TIME_randomized_backoff (GNUNET_TIME_relative_multiply (SUGGEST_FREQ,
- sq),
- GNUNET_TIME_UNIT_FOREVER_REL);
- xnext = GNUNET_TIME_relative_to_absolute (xdelay);
-
- p->task = NULL;
- while (0 == delay.rel_value_us)
- {
- struct Hello *next;
- struct GNUNET_TIME_Absolute xmax;
-
- if (NULL != hello)
- {
- /* We went through the loop already once and found
- a HELLO that is due *now*, so make a suggestion! */
- GNUNET_break (NULL == hello->sh);
- suggest_hello (hello);
- hello = NULL;
- hpt = GNUNET_TIME_UNIT_FOREVER_ABS;
- }
- for (struct Hello *pos = p->h_head; NULL != pos; pos = next)
- {
- struct GNUNET_TIME_Absolute pt;
-
- next = pos->next;
- if (NULL != pos->sh)
- continue;
- if (0 ==
- GNUNET_TIME_absolute_get_remaining (pos->expiration).rel_value_us)
- {
- /* expired, remove! */
- GNUNET_CONTAINER_DLL_remove (p->h_head, p->h_tail, pos);
- GNUNET_free (pos);
- continue;
- }
- pt = GNUNET_TIME_absolute_add (pos->last_attempt, pos->backoff);
- if ((NULL == hello) || (pt.abs_value_us < hpt.abs_value_us))
- {
- hello = pos;
- hpt = pt;
- }
- }
- if (NULL == hello)
- return; /* no HELLOs that could still be tried */
-
- /* hpt is now the *earliest* possible time for any HELLO
- but we might not want to go for as early as possible for
- this peer. So the actual time is the max of the earliest
- HELLO and the 'xnext' */
- xmax = GNUNET_TIME_absolute_max (hpt, xnext);
- delay = GNUNET_TIME_absolute_get_remaining (xmax);
- }
- p->task = GNUNET_SCHEDULER_add_delayed (delay, &suggest_start_cb, p);
-}
-
-
-/**
- * Function called by PEERSTORE for each matching record.
- *
- * @param cls closure with a `struct Peer`
- * @param record peerstore record information
- * @param emsg error message, or NULL if no errors
- */
-static void
-watch_cb (void *cls,
- const struct GNUNET_PEERSTORE_Record *record,
- const char *emsg)
-{
- struct Peer *p = cls;
- char *addr;
- size_t alen;
- enum GNUNET_NetworkType nt;
- struct GNUNET_TIME_Absolute expiration;
- struct Hello *hello;
-
- if (0 != GNUNET_memcmp (&p->pid, &record->peer))
- {
- GNUNET_break (0);
- return;
- }
- if (0 != strcmp (record->key, GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY))
- {
- GNUNET_break (0);
- return;
- }
- addr = GNUNET_HELLO_extract_address (record->value,
- record->value_size,
- &p->pid,
- &nt,
- &expiration);
- if (NULL == addr)
- return; /* invalid hello, bad signature, other problem */
- if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
- {
- /* expired, ignore */
- GNUNET_free (addr);
- return;
- }
- /* check if addr is already known */
- for (struct Hello *he = p->h_head; NULL != he; he = he->next)
- {
- if (0 != strcmp (he->address, addr))
- continue;
- if (he->expiration.abs_value_us < expiration.abs_value_us)
- {
- he->expiration = expiration;
- he->nt = nt;
- }
- GNUNET_free (addr);
- return;
- }
- /* create new HELLO */
- alen = strlen (addr) + 1;
- hello = GNUNET_malloc (sizeof(struct Hello) + alen);
- hello->address = (const char *) &hello[1];
- hello->expiration = expiration;
- hello->nt = nt;
- hello->peer = p;
- memcpy (&hello[1], addr, alen);
- GNUNET_CONTAINER_DLL_insert (p->h_head, p->h_tail, hello);
- /* check if sh for this HELLO already exists */
- for (struct GNUNET_ATS_SessionHandle *sh = p->sh_head; NULL != sh;
- sh = sh->next)
- {
- if ((NULL == sh->address) || (0 != strcmp (sh->address, addr)))
- continue;
- GNUNET_assert (NULL == sh->hello);
- sh->hello = hello;
- hello->sh = sh;
- break;
- }
- GNUNET_free (addr);
- if (NULL == p->task)
- p->task = GNUNET_SCHEDULER_add_now (&suggest_start_cb, p);
-}
-
-
-/**
- * Find or add peer if necessary.
- *
- * @param h our plugin handle
- * @param pid the peer identity to add/look for
- * @return a peer handle
- */
-static struct Peer *
-peer_add (struct SimpleHandle *h, const struct GNUNET_PeerIdentity *pid)
-{
- struct Peer *p = lookup_peer (h, pid);
-
- if (NULL != p)
- return p;
- p = GNUNET_new (struct Peer);
- p->h = h;
- p->pid = *pid;
- p->wc = GNUNET_PEERSTORE_watch (h->ps,
- "transport",
- &p->pid,
- GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY,
- &watch_cb,
- p);
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multipeermap_put (
- h->peers,
- &p->pid,
- p,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
-
- return p;
-}
-
-
-/**
- * Free the entry (and associated tasks) of peer @a p.
- * Note that @a p must be dead already (see #peer_test_dead()).
- *
- * @param p the peer to free
- */
-static void
-peer_free (struct Peer *p)
-{
- struct SimpleHandle *h = p->h;
- struct Hello *hello;
-
- GNUNET_assert (NULL == p->sh_head);
- while (NULL != (hello = p->h_head))
- {
- GNUNET_CONTAINER_DLL_remove (p->h_head, p->h_tail, hello);
- GNUNET_assert (NULL == hello->sh);
- GNUNET_free (hello);
- }
- if (NULL != p->task)
- {
- GNUNET_SCHEDULER_cancel (p->task);
- p->task = NULL;
- }
- if (NULL != p->wc)
- {
- GNUNET_PEERSTORE_watch_cancel (p->wc);
- p->wc = NULL;
- }
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multipeermap_remove (h->peers, &p->pid, p));
- GNUNET_free (p);
-}
-
-
-/**
- * Check if the new allocation for @a sh is significantly different
- * from the last one, and if so, tell transport.
- *
- * @param sh session handle to consider updating transport for
- */
-static void
-consider_notify_transport (struct GNUNET_ATS_SessionHandle *sh)
-{
- struct Peer *peer = sh->peer;
- struct SimpleHandle *h = peer->h;
- enum GNUNET_NetworkType nt = sh->data->prop.nt;
- struct GNUNET_TIME_Relative delay;
- uint64_t sig_in;
- uint64_t sig_out;
- int64_t delta_in;
- int64_t delta_out;
-
- delay = GNUNET_TIME_absolute_get_duration (sh->last_allocation);
- /* A significant change is more than 10% of the quota,
- which is given in bytes/second */
- sig_in = h->networks[nt].total_quota_in * (delay.rel_value_us / 1000LL)
- / 1000LL / 10;
- sig_out = h->networks[nt].total_quota_out * (delay.rel_value_us / 1000LL)
- / 1000LL / 10;
- delta_in = ((int64_t) ntohl (sh->bw_in.value__)) - ((int64_t) sh->target_in);
- delta_out = ((int64_t) ntohl (sh->bw_in.value__)) - ((int64_t) sh->target_in);
- /* we want the absolute values */
- if (delta_in < 0)
- delta_in = -delta_in;
- if (INT64_MIN == delta_in)
- delta_in = INT64_MAX; /* Handle corner case: INT_MIN == - INT_MIN */
- if (delta_out < 0)
- delta_out = -delta_out;
- if (INT64_MIN == delta_out)
- delta_out = INT64_MAX; /* Handle corner case: INT_MIN == - INT_MIN */
- if ((sig_in > delta_in) && (sig_out > delta_out))
- return; /* insignificant change */
- /* change is significant, tell transport! */
- if (sh->target_in > UINT32_MAX)
- sh->target_in = UINT32_MAX;
- sh->bw_in.value__ = htonl ((uint32_t) sh->target_in);
- if (sh->target_out > UINT32_MAX)
- sh->target_out = UINT32_MAX;
- sh->bw_out.value__ = htonl ((uint32_t) sh->target_out);
- sh->last_allocation = GNUNET_TIME_absolute_get ();
- h->env->allocate_cb (h->env->cls,
- sh->session,
- &peer->pid,
- sh->bw_in,
- sh->bw_out);
-}
-
-
-/**
- * Closure for #update_counters and #update_allocation.
- */
-struct Counters
-{
- /**
- * Plugin's state.
- */
- struct SimpleHandle *h;
-
- /**
- * Bandwidth that applications would prefer to allocate in this
- * network type. We initially add all requested allocations to the
- * respective network type where the given preference is best
- * satisfied. Later we may rebalance.
- */
- uint64_t bw_out_by_nt[GNUNET_NT_COUNT];
-
- /**
- * Current bandwidth utilization for this network type. We simply
- * add the current goodput up (with some fairness considerations).
- */
- uint64_t bw_in_by_nt[GNUNET_NT_COUNT];
-
- /**
- * By how much do we have to scale (up or down) our expectations
- * for outbound bandwidth?
- */
- double scale_out[GNUNET_NT_COUNT];
-
- /**
- * By how much do we have to scale (up or down) our expectations
- * for inbound bandwidth?
- */
- double scale_in[GNUNET_NT_COUNT];
-};
-
-
-/**
- * Function used to iterate over all peers and collect
- * counter data.
- *
- * @param cls a `struct Counters *`
- * @param pid identity of the peer we process, unused
- * @param value a `struct Peer *`
- * @return #GNUNET_YES (continue to iterate)
- */
-static int
-update_counters (void *cls, const struct GNUNET_PeerIdentity *pid, void *value)
-{
- struct Counters *c = cls;
- struct Peer *peer = value;
- struct GNUNET_ATS_SessionHandle *best[GNUNET_MQ_PREFERENCE_COUNT];
-
- (void) pid;
- if (NULL == peer->sh_head)
- return GNUNET_YES; /* no available session, cannot allocate bandwidth */
- memset (best, 0, sizeof(best));
- for (struct GNUNET_ATS_SessionHandle *sh = peer->sh_head; NULL != sh;
- sh = sh->next)
- {
- enum GNUNET_NetworkType nt = sh->data->prop.nt;
-
- sh->target_out = MIN_BANDWIDTH_PER_SESSION;
- c->bw_out_by_nt[nt] += MIN_BANDWIDTH_PER_SESSION;
- c->bw_in_by_nt[nt] +=
- GNUNET_MAX (MIN_BANDWIDTH_PER_SESSION, sh->data->prop.goodput_in);
- for (enum GNUNET_MQ_PreferenceKind pk = 0; pk < GNUNET_MQ_PREFERENCE_COUNT;
- pk++)
- {
- /* General rule: always prefer smaller distance if possible,
- otherwise decide by pk: */
- switch (pk)
- {
- case GNUNET_MQ_PREFERENCE_NONE:
- break;
-
- case GNUNET_MQ_PREFERENCE_BANDWIDTH:
- /* For bandwidth, we compare the sum of transmitted bytes and
- confirmed transmitted bytes, so confirmed data counts twice */
- if ((NULL == best[pk]) ||
- (sh->data->prop.distance < best[pk]->data->prop.distance) ||
- (sh->data->prop.utilization_out + sh->data->prop.goodput_out >
- best[pk]->data->prop.utilization_out
- + best[pk]->data->prop.goodput_out))
- best[pk] = sh;
- /* If both are equal (i.e. usually this happens if there is a zero), use
- latency as a yardstick */
- if ((sh->data->prop.utilization_out + sh->data->prop.goodput_out ==
- best[pk]->data->prop.utilization_out
- + best[pk]->data->prop.goodput_out) &&
- (sh->data->prop.distance == best[pk]->data->prop.distance) &&
- (sh->data->prop.delay.rel_value_us <
- best[pk]->data->prop.delay.rel_value_us))
- best[pk] = sh;
- break;
-
- case GNUNET_MQ_PREFERENCE_LATENCY:
- if ((NULL == best[pk]) ||
- (sh->data->prop.distance < best[pk]->data->prop.distance) ||
- ((sh->data->prop.distance == best[pk]->data->prop.distance) &&
- (sh->data->prop.delay.rel_value_us <
- best[pk]->data->prop.delay.rel_value_us)))
- best[pk] = sh;
- break;
-
- case GNUNET_MQ_PREFERENCE_RELIABILITY:
- /* For reliability, we consider the ratio of goodput to utilization
- (but use multiplicative formultations to avoid division by zero) */
- if ((NULL == best[pk]) || (1ULL * sh->data->prop.goodput_out
- * best[pk]->data->prop.utilization_out >
- 1ULL * sh->data->prop.utilization_out
- * best[pk]->data->prop.goodput_out))
- best[pk] = sh;
- /* If both are equal (i.e. usually this happens if there is a zero), use
- latency as a yardstick */
- if ((1ULL * sh->data->prop.goodput_out
- * best[pk]->data->prop.utilization_out ==
- 1ULL * sh->data->prop.utilization_out
- * best[pk]->data->prop.goodput_out) &&
- (sh->data->prop.distance == best[pk]->data->prop.distance) &&
- (sh->data->prop.delay.rel_value_us <
- best[pk]->data->prop.delay.rel_value_us))
- best[pk] = sh;
- break;
- }
- }
- }
- /* for first round, assign target bandwidth simply to sum of
- requested bandwidth */
- for (enum GNUNET_MQ_PreferenceKind pk =
- 1 /* skip GNUNET_MQ_PREFERENCE_NONE */;
- pk < GNUNET_MQ_PREFERENCE_COUNT;
- pk++)
- {
- const struct GNUNET_ATS_SessionData *data = best[pk]->data;
- enum GNUNET_NetworkType nt;
-
- GNUNET_assert (NULL != data);
- nt = data->prop.nt;
- best[pk]->target_out =
- GNUNET_MIN (peer->bw_by_pk[pk], MIN_BANDWIDTH_PER_SESSION);
- c->bw_out_by_nt[nt] +=
- (uint64_t) (best[pk]->target_out - MIN_BANDWIDTH_PER_SESSION);
- }
- return GNUNET_YES;
-}
-
-
-/**
- * Function used to iterate over all peers and collect
- * counter data.
- *
- * @param cls a `struct Counters *`
- * @param pid identity of the peer we process, unused
- * @param value a `struct Peer *`
- * @return #GNUNET_YES (continue to iterate)
- */
-static int
-update_allocation (void *cls,
- const struct GNUNET_PeerIdentity *pid,
- void *value)
-{
- struct Counters *c = cls;
- struct Peer *peer = value;
-
- (void) pid;
- for (struct GNUNET_ATS_SessionHandle *sh = peer->sh_head; NULL != sh;
- sh = sh->next)
- {
- enum GNUNET_NetworkType nt = sh->data->prop.nt;
-
- sh->target_out = (uint64_t) (c->scale_out[nt] * sh->target_out);
- sh->target_in = (uint64_t) (c->scale_in[nt] * sh->target_in);
- consider_notify_transport (sh);
- }
- return GNUNET_YES;
-}
-
-
-/**
- * The world changed, recalculate our allocations.
- */
-static void
-update (struct SimpleHandle *h)
-{
- struct Counters cnt = { .h = h };
-
- GNUNET_CONTAINER_multipeermap_iterate (h->peers, &update_counters, &cnt);
- /* calculate how badly the missmatch between requested
- allocations and available bandwidth is per network type */
- for (enum GNUNET_NetworkType nt = 0; nt < GNUNET_NT_COUNT; nt++)
- {
- cnt.scale_out[nt] =
- 1.0 * cnt.bw_out_by_nt[nt] / h->networks[nt].total_quota_out;
- cnt.scale_in[nt] =
- 1.0 * cnt.bw_in_by_nt[nt] / h->networks[nt].total_quota_in;
- }
- /* recalculate allocations, considering scaling factor, and
- update transport if the change is significant */
- GNUNET_CONTAINER_multipeermap_iterate (h->peers, &update_allocation, &cnt);
-}
-
-
-/**
- * The plugin should begin to respect a new preference.
- *
- * @param cls the closure
- * @param pref the preference to add
- * @return plugin's internal representation, or NULL
- */
-static struct GNUNET_ATS_PreferenceHandle *
-simple_preference_add (void *cls, const struct GNUNET_ATS_Preference *pref)
-{
- struct SimpleHandle *h = cls;
- struct Peer *p = peer_add (h, &pref->peer);
-
- GNUNET_assert (pref->pk < GNUNET_MQ_PREFERENCE_COUNT);
- p->bw_by_pk[pref->pk] += ntohl (pref->bw.value__);
- h->bw_by_pk[pref->pk] += ntohl (pref->bw.value__);
- update (h);
- return NULL;
-}
-
-
-/**
- * The plugin should end respecting a preference.
- *
- * @param cls the closure
- * @param ph whatever @e preference_add returned
- * @param pref the preference to delete
- * @return plugin's internal representation, or NULL
- */
-static void
-simple_preference_del (void *cls,
- struct GNUNET_ATS_PreferenceHandle *ph,
- const struct GNUNET_ATS_Preference *pref)
-{
- struct SimpleHandle *h = cls;
- struct Peer *p = lookup_peer (h, &pref->peer);
-
- GNUNET_assert (NULL != p);
- GNUNET_assert (pref->pk < GNUNET_MQ_PREFERENCE_COUNT);
- p->bw_by_pk[pref->pk] -= ntohl (pref->bw.value__);
- h->bw_by_pk[pref->pk] -= ntohl (pref->bw.value__);
- if ((0 == p->bw_by_pk[pref->pk]) && (GNUNET_YES == peer_test_dead (p)))
- peer_free (p);
- update (h);
-}
-
-
-/**
- * Transport established a new session with performance
- * characteristics given in @a data.
- *
- * @param cls closure
- * @param data performance characteristics of @a sh
- * @param address address information (for debugging)
- * @return handle by which the plugin will identify this session
- */
-static struct GNUNET_ATS_SessionHandle *
-simple_session_add (void *cls,
- const struct GNUNET_ATS_SessionData *data,
- const char *address)
-{
- struct SimpleHandle *h = cls;
- struct Peer *p = peer_add (h, &data->peer);
- struct Hello *hello;
- size_t alen;
- struct GNUNET_ATS_SessionHandle *sh;
-
- /* setup session handle */
- GNUNET_assert (NULL != data);
- if (NULL == address)
- alen = 0;
- else
- alen = strlen (address) + 1;
- sh = GNUNET_malloc (sizeof(struct GNUNET_ATS_SessionHandle) + alen);
- sh->peer = p;
- sh->session = data->session;
- sh->data = data;
- if (NULL == address)
- {
- sh->address = NULL;
- }
- else
- {
- memcpy (&sh[1], address, alen);
- sh->address = (const char *) &sh[1];
- }
- GNUNET_CONTAINER_DLL_insert (p->sh_head, p->sh_tail, sh);
- if (NULL != address)
- {
- /* match HELLO */
- hello = p->h_head;
- while ((NULL != hello) && (0 != strcmp (address, hello->address)))
- hello = hello->next;
- if (NULL != hello)
- {
- hello->sh = sh;
- hello->backoff = GNUNET_TIME_UNIT_ZERO;
- sh->hello = hello;
- }
- }
- update (h);
- return sh;
-}
-
-
-/**
- * @a data changed for a given @a sh, solver should consider
- * the updated performance characteristics.
- *
- * @param cls closure
- * @param sh session this is about
- * @param data performance characteristics of @a sh
- */
-static void
-simple_session_update (void *cls,
- struct GNUNET_ATS_SessionHandle *sh,
- const struct GNUNET_ATS_SessionData *data)
-{
- struct SimpleHandle *h = cls;
-
- GNUNET_assert (NULL != data);
- sh->data = data; /* this statement should not really do anything... */
- update (h);
-}
-
-
-/**
- * A session went away. Solver should update accordingly.
- *
- * @param cls closure
- * @param sh session this is about
- * @param data (last) performance characteristics of @a sh
- */
-static void
-simple_session_del (void *cls,
- struct GNUNET_ATS_SessionHandle *sh,
- const struct GNUNET_ATS_SessionData *data)
-{
- struct SimpleHandle *h = cls;
- struct Peer *p = sh->peer;
- struct Hello *hello = sh->hello;
-
- /* clean up sh */
- GNUNET_CONTAINER_DLL_remove (p->sh_head, p->sh_tail, sh);
- if (NULL != hello)
- {
- GNUNET_assert (sh == hello->sh);
- hello->sh = NULL;
- /* session went down, if necessary restart suggesting
- addresses */
- if (NULL == p->task)
- p->task = GNUNET_SCHEDULER_add_now (&suggest_start_cb, p);
- }
- GNUNET_free (sh);
- /* del peer if otherwise dead */
- if ((NULL == p->sh_head) && (GNUNET_YES == peer_test_dead (p)))
- peer_free (p);
- update (h);
-}
-
-
-#include "plugin_ats2_common.c"
-
-
-/**
- * Function invoked when the plugin is loaded.
- *
- * @param[in,out] cls the `struct GNUNET_ATS_PluginEnvironment *` to use;
- * modified to return the API functions (ugh).
- * @return the `struct SimpleHandle` to pass as a closure
- */
-void *
-libgnunet_plugin_ats2_simple_init (void *cls)
-{
- static struct GNUNET_ATS_SolverFunctions sf;
- struct GNUNET_ATS_PluginEnvironment *env = cls;
- struct SimpleHandle *s;
-
- s = GNUNET_new (struct SimpleHandle);
- s->env = env;
- s->peers = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_YES);
- s->ps = GNUNET_PEERSTORE_connect (env->cfg);
- sf.cls = s;
- sf.preference_add = &simple_preference_add;
- sf.preference_del = &simple_preference_del;
- sf.session_add = &simple_session_add;
- sf.session_update = &simple_session_update;
- sf.session_del = &simple_session_del;
- for (enum GNUNET_NetworkType nt = 0; nt < GNUNET_NT_COUNT; nt++)
- {
- const char *name = GNUNET_NT_to_string (nt);
-
- if (NULL == name)
- {
- GNUNET_break (0);
- break;
- }
- get_quota (env->cfg, name, "IN", &s->networks[nt].total_quota_in);
- get_quota (env->cfg, name, "OUT", &s->networks[nt].total_quota_out);
- s->networks[nt].type = nt;
- }
- return &sf;
-}
-
-
-/**
- * Function used to unload the plugin.
- *
- * @param cls return value from #libgnunet_plugin_ats_proportional_init()
- */
-void *
-libgnunet_plugin_ats2_simple_done (void *cls)
-{
- struct GNUNET_ATS_SolverFunctions *sf = cls;
- struct SimpleHandle *s = sf->cls;
-
- GNUNET_break (0 == GNUNET_CONTAINER_multipeermap_size (s->peers));
- GNUNET_CONTAINER_multipeermap_destroy (s->peers);
- GNUNET_PEERSTORE_disconnect (s->ps, GNUNET_NO);
- GNUNET_free (s);
- return NULL;
-}
-
-
-/* end of plugin_ats2_simple.c */
diff --git a/src/ats/plugin_ats_mlp.c b/src/ats/plugin_ats_mlp.c
deleted file mode 100644
index 6ab823b1e..000000000
--- a/src/ats/plugin_ats_mlp.c
+++ /dev/null
@@ -1,2924 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2011-2014 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-
-/**
- * @file ats/plugin_ats_mlp.c
- * @brief ats mlp problem solver
- * @author Matthias Wachs
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_ats_service.h"
-#include "gnunet_ats_plugin.h"
-#include "gnunet-service-ats_addresses.h"
-#include "gnunet_statistics_service.h"
-#include <float.h>
-#include <glpk.h>
-
-
-#define BIG_M_VALUE (UINT32_MAX) / 10
-#define BIG_M_STRING "unlimited"
-
-#define MLP_AVERAGING_QUEUE_LENGTH 3
-
-#define MLP_MAX_EXEC_DURATION GNUNET_TIME_relative_multiply ( \
- GNUNET_TIME_UNIT_SECONDS, 10)
-#define MLP_MAX_ITERATIONS 4096
-
-#define MLP_DEFAULT_D 1.0
-#define MLP_DEFAULT_R 1.0
-#define MLP_DEFAULT_U 1.0
-#define MLP_DEFAULT_QUALITY 1.0
-#define MLP_DEFAULT_MIN_CONNECTIONS 4
-#define MLP_DEFAULT_PEER_PREFERENCE 1.0
-
-#define MLP_NaN -1
-#define MLP_UNDEFINED 0
-#define GLP_YES 1.0
-#define GLP_NO 0.0
-
-enum MLP_Output_Format
-{
- MLP_MPS,
- MLP_CPLEX,
- MLP_GLPK
-};
-
-
-enum QualityMetrics
-{
- RQ_QUALITY_METRIC_DELAY = 0,
- RQ_QUALITY_METRIC_DISTANCE = 1,
- RQ_QUALITY_METRIC_COUNT = 2
-};
-
-
-static const char *
-print_quality_type (enum QualityMetrics qm)
-{
- switch (qm)
- {
- case RQ_QUALITY_METRIC_DELAY:
- return "delay";
-
- case RQ_QUALITY_METRIC_DISTANCE:
- return "distance";
-
- default:
- GNUNET_break (0);
- return NULL;
- }
-}
-
-
-struct MLP_Solution
-{
- int lp_res;
- int lp_presolv;
- int mip_res;
- int mip_presolv;
-
- double lp_objective_value;
- double mlp_objective_value;
- double mlp_gap;
- double lp_mlp_gap;
-
- int p_elements;
- int p_cols;
- int p_rows;
-
- int n_peers;
- int n_addresses;
-};
-
-struct ATS_Peer
-{
- struct GNUNET_PeerIdentity id;
-
- /* Was this peer already added to the current problem? */
- int processed;
-
- /* constraint 2: 1 address per peer*/
- unsigned int r_c2;
-
- /* constraint 9: relativity */
- unsigned int r_c9;
-
- /* Legacy preference value */
- double f;
-};
-
-struct MLP_Problem
-{
- /**
- * GLPK (MLP) problem object
- */
- glp_prob *prob;
-
- /* Number of addresses in problem */
- unsigned int num_addresses;
- /* Number of peers in problem */
- unsigned int num_peers;
- /* Number of elements in problem matrix */
- unsigned int num_elements;
-
- /* Row index constraint 2: */
- unsigned int r_c2;
- /* Row index constraint 4: minimum connections */
- unsigned int r_c4;
- /* Row index constraint 6: maximize diversity */
- unsigned int r_c6;
- /* Row index constraint 8: utilization*/
- unsigned int r_c8;
- /* Row index constraint 9: relativity*/
- unsigned int r_c9;
- /* Row indices quality metrics */
- int r_q[RQ_QUALITY_METRIC_COUNT];
- /* Row indices ATS network quotas */
- int r_quota[GNUNET_NT_COUNT];
-
- /* Column index Diversity (D) column */
- int c_d;
- /* Column index Utilization (U) column */
- int c_u;
- /* Column index Proportionality (R) column */
- int c_r;
- /* Column index quality metrics */
- int c_q[RQ_QUALITY_METRIC_COUNT];
-
- /* Problem matrix */
- /* Current index */
- unsigned int ci;
- /* Row index array */
- int *ia;
- /* Column index array */
- int *ja;
- /* Column index value */
- double *ar;
-};
-
-struct MLP_Variables
-{
- /* Big M value for bandwidth capping */
- double BIG_M;
-
- /* MIP Gap */
- double mip_gap;
-
- /* LP MIP Gap */
- double lp_mip_gap;
-
- /* Number of quality metrics @deprecated, use RQ_QUALITY_METRIC_COUNT */
- int m_q;
-
- /* Number of quality metrics */
- int m_rc;
-
- /* Quality metric coefficients*/
- double co_Q[RQ_QUALITY_METRIC_COUNT];
-
- /* Ressource costs coefficients*/
- double co_RC[RQ_QUALITY_METRIC_COUNT];
-
- /* Diversity coefficient */
- double co_D;
-
- /* Utility coefficient */
- double co_U;
-
- /* Relativity coefficient */
- double co_R;
-
- /* Minimum bandwidth assigned to an address */
- unsigned int b_min;
-
- /* Minimum number of addresses with bandwidth assigned */
- unsigned int n_min;
-
- /* Quotas */
- /* Array mapping array index to ATS network */
- int quota_index[GNUNET_NT_COUNT];
- /* Outbound quotas */
- unsigned long long quota_out[GNUNET_NT_COUNT];
- /* Inbound quotas */
-
- unsigned long long quota_in[GNUNET_NT_COUNT];
-
- /* ATS ressource costs
- * array with GNUNET_ATS_QualityPropertiesCount elements
- * contains mapping to GNUNET_ATS_Property
- * */
- int rc[RQ_QUALITY_METRIC_COUNT];
-};
-
-/**
- * MLP Handle
- */
-struct GAS_MLP_Handle
-{
- struct GNUNET_ATS_PluginEnvironment *env;
-
- /**
- * Exclude peer from next result propagation
- */
- const struct GNUNET_PeerIdentity *exclude_peer;
-
- /**
- * Encapsulation for the MLP problem
- */
- struct MLP_Problem p;
-
- /**
- * Encapsulation for the MLP problem variables
- */
- struct MLP_Variables pv;
-
- /**
- * Encapsulation for the MLP solution
- */
- struct MLP_Solution ps;
-
- /**
- * Bulk lock
- */
- int stat_bulk_lock;
-
- /**
- * Number of changes while solver was locked
- */
- int stat_bulk_requests;
-
- /**
- * GLPK LP control parameter
- */
- glp_smcp control_param_lp;
-
- /**
- * GLPK LP control parameter
- */
- glp_iocp control_param_mlp;
-
- /**
- * Peers with pending address requests
- */
- struct GNUNET_CONTAINER_MultiPeerMap *requested_peers;
-
- /**
- * Was the problem updated since last solution
- */
- int stat_mlp_prob_updated;
-
- /**
- * Has the problem size changed since last solution
- */
- int stat_mlp_prob_changed;
-
- /**
- * Solve the problem automatically when updates occur?
- * Default: GNUNET_YES
- * Can be disabled for test and measurements
- */
- int opt_mlp_auto_solve;
-
- /**
- * Write all MILP problems to a MPS file
- */
- int opt_dump_problem_all;
-
- /**
- * Write all MILP problem solutions to a file
- */
- int opt_dump_solution_all;
-
- /**
- * Write MILP problems to a MPS file when solver fails
- */
- int opt_dump_problem_on_fail;
-
- /**
- * Write MILP problem solutions to a file when solver fails
- */
- int opt_dump_solution_on_fail;
-
- /**
- * solve feasibility only
- */
- int opt_dbg_feasibility_only;
-
- /**
- * solve autoscale the problem
- */
- int opt_dbg_autoscale_problem;
-
- /**
- * use the intopt presolver instead of simplex
- */
- int opt_dbg_intopt_presolver;
-
- /**
- * Print GLPK output
- */
- int opt_dbg_glpk_verbose;
-
- /**
- * solve autoscale the problem
- */
- int opt_dbg_optimize_relativity;
-
- /**
- * solve autoscale the problem
- */
- int opt_dbg_optimize_diversity;
-
- /**
- * solve autoscale the problem
- */
- int opt_dbg_optimize_quality;
-
- /**
- * solve autoscale the problem
- */
- int opt_dbg_optimize_utility;
-
-
- /**
- * Output format
- */
- enum MLP_Output_Format opt_log_format;
-};
-
-/**
- * Address specific MLP information
- */
-struct MLP_information
-{
- /**
- * Bandwidth assigned outbound
- */
- uint32_t b_out;
-
- /**
- * Bandwidth assigned inbound
- */
- uint32_t b_in;
-
- /**
- * Address selected
- */
- int n;
-
- /**
- * bandwidth column index
- */
- signed int c_b;
-
- /**
- * address usage column
- */
- signed int c_n;
-
- /* row indexes */
-
- /**
- * constraint 1: bandwidth capping
- */
- unsigned int r_c1;
-
- /**
- * constraint 3: minimum bandwidth
- */
- unsigned int r_c3;
-};
-
-
-
-/**
- *
- * NOTE: Do not modify this documentation. This documentation is based on
- * gnunet.org:/vcs/fsnsg/ats-paper.git/tech-doku/ats-tech-guide.tex
- * use build_txt.sh to generate plaintext output
- *
- * The MLP solver (mlp) tries to finds an optimal bandwidth assignmentby
- * optimizing an mixed integer programming problem. The MLP solver uses a
- * number of constraints to find the best adddress for a peer and an optimal
- * bandwidth assignment. mlp uses the GNU Linear Programming Kit to solve the
- * MLP problem.
- *
- * We defined a constraint system to find an optimal bandwidth assignment.
- * This constraint system uses as an input data addresses, bandwidth quotas,
- * preferences and quality values. This constraint system is stored in an
- * matrix based equotation system.
- *
- * 5 Using GLPK
- *
- * A (M)LP problem consists of a target function to optimizes, constraints
- * and rows and columns. FIXME GLP uses three arrays to index the matrix: two
- * integer arrays storing the row and column indices in the matrix and an
- * float array to store the coeeficient.
- *
- * To solve the problem we first find an initial solution for the LP problem
- * using the LP solver and then find an MLP solution based on this solution
- * using the MLP solver.
- *
- * Solving (M)LP problems has the property that finding an initial solution
- * for the LP problem is computationally expensive and finding the MLP
- * solution is cheaper. This is especially interesting an existing LP
- * solution can be reused if only coefficients in the matrix have changed
- * (addresses updated). Only when the problem size changes (addresses added
- * or deleted) a new LP solution has to be found.
- *
- * Intended usage
- * The mlp solver solves the bandwidth assignment problem only on demand when
- * an address suggestion is requested. When an address is requested mlp the
- * solves the mlp problem and if the active address or the bandwidth assigned
- * changes it calls the callback to addresses. The mlp solver gets notified
- * about new addresses (adding sessions), removed addresses (address
- * deletions) and address updates. To benefit from the mlp properties
- * mentioned in section 5 the solver rembers if since the last solution
- * addresses were added or deleted (problem size changed, problem has to be
- * rebuild and solved from sratch) or if addresses were updated and the
- * existing solution can be reused.
- *
- * 5.1 Input data
- *
- * The quotas for each network segment are passed by addresses. MLP can be
- * adapted using configuration settings and uses the following parameters:
- * * MLP_MAX_DURATION:
- * Maximum duration for a MLP solution procees (default: 3 sec.)
- * * MLP_MAX_ITERATIONS:
- * Maximum number of iterations for a MLP solution process (default:
- * 1024)
- * * MLP_MIN_CONNECTIONS:
- * Minimum number of desired connections (default: 4)
- * * MLP_MIN_BANDWIDTH:
- * Minimum amount of bandwidth assigned to an address (default: 1024)
- * * MLP_COEFFICIENT_D:
- * Diversity coefficient (default: 1.0)
- * * MLP_COEFFICIENT_R:
- * Relativity coefficient (default: 1.0)
- * * MLP_COEFFICIENT_U:
- * Utilization coefficient (default: 1.0)
- * * MLP_COEFFICIENT_D:
- * Diversity coefficient (default: 1.0)
- * * MLP_COEFFICIENT_QUALITY_DELAY:
- * Quality delay coefficient (default: 1.0)
- * * MLP_COEFFICIENT_QUALITY_DISTANCE:
- * Quality distance coefficient (default: 1.0)
- * * MLP_COEFFICIENT_QUALITY_DISTANCE:
- * Quality distance coefficient (default: 1.0)
- * * MLP_COEFFICIENT_QUALITY_DISTANCE:
- * Quality distance coefficient (default: 1.0)
- * * MLP_COEFFICIENT_QUALITY_DISTANCE:
- * Quality distance coefficient (default: 1.0)
- *
- * 5.2 Data structures used
- *
- * mlp has for each known peer a struct ATS_Peer containing information about
- * a specific peer. The address field solver_information contains information
- * about the mlp properties of this address.
- *
- * 5.3 Initializing
- *
- * During initialization mlp initializes the GLPK libray used to solve the
- * MLP problem: it initializes the glpk environment and creates an initial LP
- * problem. Next it loads the configuration values from the configuration or
- * uses the default values configured in -addresses_mlp.h. The quotas used
- * are given by addresses but may have to be adjusted. mlp uses a upper limit
- * for the bandwidth assigned called BIG M and a minimum amount of bandwidth
- * an address gets assigned as well as a minium desired number of
- * connections. If the configured quota is bigger than BIG M, it is reduced
- * to BIG M. If the configured quota is smaller than MLP_MIN_CONNECTIONS
- * *MLP_MIN_BANDWIDTH it is increased to this value.
- *
- * 5.4 Shutdown
-
- */
-
-#define LOG(kind, ...) GNUNET_log_from (kind, "ats-mlp", __VA_ARGS__)
-
-/**
- * Print debug output for mlp problem creation
- */
-#define DEBUG_MLP_PROBLEM_CREATION GNUNET_NO
-
-
-/**
- * Intercept GLPK terminal output
- * @param info the mlp handle
- * @param s the string to print
- * @return 0: glpk prints output on terminal, 0 != surpress output
- */
-static int
-mlp_term_hook (void *info, const char *s)
-{
- struct GAS_MLP_Handle *mlp = info;
-
- if (mlp->opt_dbg_glpk_verbose)
- LOG (GNUNET_ERROR_TYPE_ERROR, "%s", s);
- return 1;
-}
-
-
-/**
- * Reset peers for next problem creation
- *
- * @param cls not used
- * @param key the key
- * @param value ATS_Peer
- * @return #GNUNET_OK
- */
-static int
-reset_peers (void *cls,
- const struct GNUNET_PeerIdentity *key,
- void *value)
-{
- struct ATS_Peer *peer = value;
-
- peer->processed = GNUNET_NO;
- return GNUNET_OK;
-}
-
-/**
- * Delete the MLP problem and free the constrain matrix
- *
- * @param mlp the MLP handle
- */
-static void
-mlp_delete_problem (struct GAS_MLP_Handle *mlp)
-{
- int c;
-
- if (mlp == NULL)
- return;
- if (mlp->p.prob != NULL)
- {
- glp_delete_prob (mlp->p.prob);
- mlp->p.prob = NULL;
- }
-
- /* delete row index */
- if (mlp->p.ia != NULL)
- {
- GNUNET_free (mlp->p.ia);
- mlp->p.ia = NULL;
- }
-
- /* delete column index */
- if (mlp->p.ja != NULL)
- {
- GNUNET_free (mlp->p.ja);
- mlp->p.ja = NULL;
- }
-
- /* delete coefficients */
- if (mlp->p.ar != NULL)
- {
- GNUNET_free (mlp->p.ar);
- mlp->p.ar = NULL;
- }
- mlp->p.ci = 0;
- mlp->p.prob = NULL;
-
- mlp->p.c_d = MLP_UNDEFINED;
- mlp->p.c_r = MLP_UNDEFINED;
- mlp->p.r_c2 = MLP_UNDEFINED;
- mlp->p.r_c4 = MLP_UNDEFINED;
- mlp->p.r_c6 = MLP_UNDEFINED;
- mlp->p.r_c9 = MLP_UNDEFINED;
- for (c = 0; c < RQ_QUALITY_METRIC_COUNT; c++)
- mlp->p.r_q[c] = MLP_UNDEFINED;
- for (c = 0; c < GNUNET_NT_COUNT; c++)
- mlp->p.r_quota[c] = MLP_UNDEFINED;
- mlp->p.ci = MLP_UNDEFINED;
-
-
- GNUNET_CONTAINER_multipeermap_iterate (mlp->requested_peers,
- &reset_peers, NULL);
-}
-
-
-/**
- * Translate glpk status error codes to text
- * @param retcode return code
- * @return string with result
- */
-static const char *
-mlp_status_to_string (int retcode)
-{
- switch (retcode)
- {
- case GLP_UNDEF:
- return "solution is undefined";
-
- case GLP_FEAS:
- return "solution is feasible";
-
- case GLP_INFEAS:
- return "solution is infeasible";
-
- case GLP_NOFEAS:
- return "no feasible solution exists";
-
- case GLP_OPT:
- return "solution is optimal";
-
- case GLP_UNBND:
- return "solution is unbounded";
-
- default:
- GNUNET_break (0);
- return "unknown error";
- }
-}
-
-
-/**
- * Translate glpk solver error codes to text
- * @param retcode return code
- * @return string with result
- */
-static const char *
-mlp_solve_to_string (int retcode)
-{
- switch (retcode)
- {
- case 0:
- return "ok";
-
- case GLP_EBADB:
- return "invalid basis";
-
- case GLP_ESING:
- return "singular matrix";
-
- case GLP_ECOND:
- return "ill-conditioned matrix";
-
- case GLP_EBOUND:
- return "invalid bounds";
-
- case GLP_EFAIL:
- return "solver failed";
-
- case GLP_EOBJLL:
- return "objective lower limit reached";
-
- case GLP_EOBJUL:
- return "objective upper limit reached";
-
- case GLP_EITLIM:
- return "iteration limit exceeded";
-
- case GLP_ETMLIM:
- return "time limit exceeded";
-
- case GLP_ENOPFS:
- return "no primal feasible solution";
-
- case GLP_ENODFS:
- return "no dual feasible solution";
-
- case GLP_EROOT:
- return "root LP optimum not provided";
-
- case GLP_ESTOP:
- return "search terminated by application";
-
- case GLP_EMIPGAP:
- return "relative mip gap tolerance reached";
-
- case GLP_ENOFEAS:
- return "no dual feasible solution";
-
- case GLP_ENOCVG:
- return "no convergence";
-
- case GLP_EINSTAB:
- return "numerical instability";
-
- case GLP_EDATA:
- return "invalid data";
-
- case GLP_ERANGE:
- return "result out of range";
-
- default:
- GNUNET_break (0);
- return "unknown error";
- }
-}
-
-
-struct CountContext
-{
- const struct GNUNET_CONTAINER_MultiPeerMap *map;
- int result;
-};
-
-static int
-mlp_create_problem_count_addresses_it (void *cls,
- const struct GNUNET_PeerIdentity *key,
- void *value)
-{
- struct CountContext *cctx = cls;
-
- /* Check if we have to add this peer due to a pending request */
- if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (cctx->map, key))
- cctx->result++;
- return GNUNET_OK;
-}
-
-
-static int
-mlp_create_problem_count_addresses (const struct
- GNUNET_CONTAINER_MultiPeerMap *
- requested_peers,
- const struct
- GNUNET_CONTAINER_MultiPeerMap *addresses)
-{
- struct CountContext cctx;
-
- cctx.map = requested_peers;
- cctx.result = 0;
- GNUNET_CONTAINER_multipeermap_iterate (addresses,
- &mlp_create_problem_count_addresses_it,
- &cctx);
- return cctx.result;
-}
-
-
-static int
-mlp_create_problem_count_peers_it (void *cls,
- const struct GNUNET_PeerIdentity *key,
- void *value)
-{
- struct CountContext *cctx = cls;
-
- /* Check if we have to addresses for the requested peer */
- if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (cctx->map, key))
- cctx->result++;
- return GNUNET_OK;
-}
-
-
-static int
-mlp_create_problem_count_peers (const struct
- GNUNET_CONTAINER_MultiPeerMap *requested_peers,
- const struct
- GNUNET_CONTAINER_MultiPeerMap *addresses)
-{
- struct CountContext cctx;
-
- cctx.map = addresses;
- cctx.result = 0;
- GNUNET_CONTAINER_multipeermap_iterate (requested_peers,
- &mlp_create_problem_count_peers_it,
- &cctx);
- return cctx.result;
-}
-
-
-/**
- * Updates an existing value in the matrix
- *
- * Extract the row, updates the value and updates the row in the problem
- *
- * @param p the mlp problem
- * @param row the row to create the value in
- * @param col the column to create the value in
- * @param val the value to set
- * @param line calling line for debbuging
- * @return GNUNET_YES value changed, GNUNET_NO value did not change, GNUNET_SYSERR
- * on error
- */
-static int
-mlp_create_problem_update_value (struct MLP_Problem *p,
- int row, int col, double val,
- int line)
-{
- int c_cols;
- int c_elems;
- int c1;
- int res;
- int found;
- double *val_array;
- int *ind_array;
-
- GNUNET_assert (NULL != p->prob);
-
- /* Get number of columns and prepare data structure */
- c_cols = glp_get_num_cols (p->prob);
- if (0 >= c_cols)
- return GNUNET_SYSERR;
-
- val_array = GNUNET_malloc ((c_cols + 1) * sizeof(double));
- GNUNET_assert (NULL != val_array);
- ind_array = GNUNET_malloc ((c_cols + 1) * sizeof(int));
- GNUNET_assert (NULL != ind_array);
- /* Extract the row */
-
- /* Update the value */
- c_elems = glp_get_mat_row (p->prob, row, ind_array, val_array);
- found = GNUNET_NO;
- for (c1 = 1; c1 < (c_elems + 1); c1++)
- {
- if (ind_array[c1] == col)
- {
- found = GNUNET_YES;
- break;
- }
- }
- if (GNUNET_NO == found)
- {
- ind_array[c_elems + 1] = col;
- val_array[c_elems + 1] = val;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "[P] Setting value in [%s : %s] to `%.2f'\n",
- glp_get_row_name (p->prob, row), glp_get_col_name (p->prob, col),
- val);
- glp_set_mat_row (p->prob, row, c_elems + 1, ind_array, val_array);
- GNUNET_free (ind_array);
- GNUNET_free (val_array);
- return GNUNET_YES;
- }
- else
- {
- /* Update value */
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "[P] Updating value in [%s : %s] from `%.2f' to `%.2f'\n",
- glp_get_row_name (p->prob, row), glp_get_col_name (p->prob, col),
- val_array[c1], val);
- if (val != val_array[c1])
- res = GNUNET_YES;
- else
- res = GNUNET_NO;
- val_array[c1] = val;
- /* Update the row in the matrix */
- glp_set_mat_row (p->prob, row, c_elems, ind_array, val_array);
- }
-
- GNUNET_free (ind_array);
- GNUNET_free (val_array);
- return res;
-}
-
-/**
- * Creates a new value in the matrix
- *
- * Sets the row and column index in the problem array and increments the
- * position field
- *
- * @param p the mlp problem
- * @param row the row to create the value in
- * @param col the column to create the value in
- * @param val the value to set
- * @param line calling line for debbuging
- */
-static void
-mlp_create_problem_set_value (struct MLP_Problem *p,
- int row, int col, double val,
- int line)
-{
- if ((p->ci) >= p->num_elements)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "[P]: line %u: Request for index %u bigger than array size of %u\n",
- line, p->ci + 1, p->num_elements);
- GNUNET_break (0);
- return;
- }
- if ((0 == row) || (0 == col))
- {
- GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "[P]: Invalid call from line %u: row = %u, col = %u\n",
- line, row, col);
- }
- p->ia[p->ci] = row;
- p->ja[p->ci] = col;
- p->ar[p->ci] = val;
-#if DEBUG_MLP_PROBLEM_CREATION
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "[P]: line %u: Set value [%u,%u] in index %u == %.2f\n",
- line, p->ia[p->ci], p->ja[p->ci], p->ci, p->ar[p->ci]);
-#endif
- p->ci++;
-}
-
-static int
-mlp_create_problem_create_column (struct MLP_Problem *p, char *name,
- unsigned int type, unsigned int bound, double
- lb, double ub,
- double coef)
-{
- int col = glp_add_cols (p->prob, 1);
-
- glp_set_col_name (p->prob, col, name);
- glp_set_col_bnds (p->prob, col, bound, lb, ub);
- glp_set_col_kind (p->prob, col, type);
- glp_set_obj_coef (p->prob, col, coef);
-#if DEBUG_MLP_PROBLEM_CREATION
- LOG (GNUNET_ERROR_TYPE_DEBUG, "[P]: Added column [%u] `%s': %.2f\n",
- col, name, coef);
-#endif
- return col;
-}
-
-static int
-mlp_create_problem_create_constraint (struct MLP_Problem *p, char *name,
- unsigned int bound, double lb, double ub)
-{
- char *op;
- int row = glp_add_rows (p->prob, 1);
-
- /* set row name */
- glp_set_row_name (p->prob, row, name);
- /* set row bounds: <= 0 */
- glp_set_row_bnds (p->prob, row, bound, lb, ub);
- switch (bound)
- {
- case GLP_UP:
- GNUNET_asprintf (&op, "-inf <= x <= %.2f", ub);
- break;
-
- case GLP_DB:
- GNUNET_asprintf (&op, "%.2f <= x <= %.2f", lb, ub);
- break;
-
- case GLP_FX:
- GNUNET_asprintf (&op, "%.2f == x == %.2f", lb, ub);
- break;
-
- case GLP_LO:
- GNUNET_asprintf (&op, "%.2f <= x <= inf", lb);
- break;
-
- default:
- GNUNET_asprintf (&op, "ERROR");
- break;
- }
-#if DEBUG_MLP_PROBLEM_CREATION
- LOG (GNUNET_ERROR_TYPE_DEBUG, "[P]: Added row [%u] `%s': %s\n",
- row, name, op);
-#endif
- GNUNET_free (op);
- return row;
-}
-
-/**
- * Create the
- * - address columns b and n
- * - address dependent constraint rows c1, c3
- * - peer dependent rows c2 and c9
- * - Set address dependent entries in problem matrix as well
- */
-static int
-mlp_create_problem_add_address_information (void *cls,
- const struct
- GNUNET_PeerIdentity *key,
- void *value)
-{
- struct GAS_MLP_Handle *mlp = cls;
- struct MLP_Problem *p = &mlp->p;
- struct ATS_Address *address = value;
- struct ATS_Peer *peer;
- struct MLP_information *mlpi;
- char *name;
- double cur_bigm;
- uint32_t addr_net;
- uint32_t addr_net_index;
- unsigned long long max_quota;
- int c;
-
- /* Check if we have to add this peer due to a pending request */
- if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (mlp->requested_peers,
- key))
- return GNUNET_OK;
-
- mlpi = address->solver_information;
- if (NULL == mlpi)
- {
- fprintf (stderr, "%s %p\n", GNUNET_i2s (&address->peer), address);
- GNUNET_break (0);
- return GNUNET_OK;
- }
-
- addr_net = address->properties.scope;
- for (addr_net_index = 0; addr_net_index < GNUNET_NT_COUNT; addr_net_index++)
- {
- if (mlp->pv.quota_index[addr_net_index] == addr_net)
- break;
- }
-
- if (addr_net_index >= GNUNET_NT_COUNT)
- {
- GNUNET_break (0);
- return GNUNET_OK;
- }
-
- max_quota = 0;
- for (c = 0; c < GNUNET_NT_COUNT; c++)
- {
- if (mlp->pv.quota_out[c] > max_quota)
- max_quota = mlp->pv.quota_out[c];
- if (mlp->pv.quota_in[c] > max_quota)
- max_quota = mlp->pv.quota_in[c];
- }
- if (max_quota > mlp->pv.BIG_M)
- cur_bigm = (double) mlp->pv.BIG_M;
- else
- cur_bigm = max_quota;
-
-
- /* Get peer */
- peer = GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers, key);
- GNUNET_assert (NULL != peer);
- if (peer->processed == GNUNET_NO)
- {
- /* Add peer dependent constraints */
- /* Add c2) One address active per peer */
- GNUNET_asprintf (&name, "c2_%s", GNUNET_i2s (&address->peer));
- peer->r_c2 = mlp_create_problem_create_constraint (p, name, GLP_FX, 1.0,
- 1.0);
- GNUNET_free (name);
- if (GNUNET_NO == mlp->opt_dbg_feasibility_only)
- {
- if (GNUNET_YES == mlp->opt_dbg_optimize_relativity)
- {
- /* Add c9) Relativity */
- GNUNET_asprintf (&name, "c9_%s", GNUNET_i2s (&address->peer));
- peer->r_c9 = mlp_create_problem_create_constraint (p, name, GLP_LO, 0.0,
- 0.0);
- GNUNET_free (name);
- /* c9) set coefficient */
- mlp_create_problem_set_value (p, peer->r_c9, p->c_r, -peer->f,
- __LINE__);
- }
- }
- peer->processed = GNUNET_YES;
- }
-
- /* Reset addresses' solver information */
- mlpi->c_b = 0;
- mlpi->c_n = 0;
- mlpi->n = 0;
- mlpi->r_c1 = 0;
- mlpi->r_c3 = 0;
-
- /* Add bandwidth column */
- GNUNET_asprintf (&name, "b_%s_%s_%p", GNUNET_i2s (&address->peer),
- address->plugin, address);
- if (GNUNET_NO == mlp->opt_dbg_feasibility_only)
- {
- mlpi->c_b = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0,
- 0.0, 0.0);
- }
- else
- {
- /* Maximize for bandwidth assignment in feasibility testing */
- mlpi->c_b = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO, 0.0,
- 0.0, 1.0);
- }
- GNUNET_free (name);
-
- /* Add address active column */
- GNUNET_asprintf (&name, "n_%s_%s_%p", GNUNET_i2s (&address->peer),
- address->plugin, address);
- mlpi->c_n = mlp_create_problem_create_column (p, name, GLP_IV, GLP_DB, 0.0,
- 1.0, 0.0);
- GNUNET_free (name);
-
- /* Add address dependent constraints */
- /* Add c1) bandwidth capping: b_t + (-M) * n_t <= 0 */
- GNUNET_asprintf (&name, "c1_%s_%s_%p", GNUNET_i2s (&address->peer),
- address->plugin, address);
- mlpi->r_c1 = mlp_create_problem_create_constraint (p, name, GLP_UP, 0.0, 0.0);
- GNUNET_free (name);
- /* c1) set b = 1 coefficient */
- mlp_create_problem_set_value (p, mlpi->r_c1, mlpi->c_b, 1, __LINE__);
- /* c1) set n = - min (M, quota) coefficient */
- cur_bigm = (double) mlp->pv.quota_out[addr_net_index];
- if (cur_bigm > mlp->pv.BIG_M)
- cur_bigm = (double) mlp->pv.BIG_M;
- mlp_create_problem_set_value (p, mlpi->r_c1, mlpi->c_n, -cur_bigm, __LINE__);
-
- /* Add constraint c 3) minimum bandwidth
- * b_t + (-n_t * b_min) >= 0
- * */
- GNUNET_asprintf (&name, "c3_%s_%s_%p", GNUNET_i2s (&address->peer),
- address->plugin, address);
- mlpi->r_c3 = mlp_create_problem_create_constraint (p, name, GLP_LO, 0.0, 0.0);
- GNUNET_free (name);
-
- /* c3) set b = 1 coefficient */
- mlp_create_problem_set_value (p, mlpi->r_c3, mlpi->c_b, 1, __LINE__);
- /* c3) set n = -b_min coefficient */
- mlp_create_problem_set_value (p, mlpi->r_c3, mlpi->c_n,
- -((double ) mlp->pv.b_min), __LINE__);
-
-
- /* Set coefficient entries in invariant rows */
-
- /* Feasbility */
-
- /* c 4) minimum connections */
- mlp_create_problem_set_value (p, p->r_c4, mlpi->c_n, 1, __LINE__);
- /* c 2) 1 address peer peer */
- mlp_create_problem_set_value (p, peer->r_c2, mlpi->c_n, 1, __LINE__);
- /* c 10) obey network specific quotas
- * (1)*b_1 + ... + (1)*b_m <= quota_n
- */
- mlp_create_problem_set_value (p, p->r_quota[addr_net_index], mlpi->c_b, 1,
- __LINE__);
-
- /* Optimality */
- if (GNUNET_NO == mlp->opt_dbg_feasibility_only)
- {
- /* c 6) maximize diversity */
- mlp_create_problem_set_value (p, p->r_c6, mlpi->c_n, 1, __LINE__);
- /* c 9) relativity */
- if (GNUNET_YES == mlp->opt_dbg_optimize_relativity)
- mlp_create_problem_set_value (p, peer->r_c9, mlpi->c_b, 1, __LINE__);
- /* c 8) utility */
- if (GNUNET_YES == mlp->opt_dbg_optimize_utility)
- mlp_create_problem_set_value (p, p->r_c8, mlpi->c_b, 1, __LINE__);
- /* c 7) Optimize quality */
- /* For all quality metrics, set quality of this address */
- if (GNUNET_YES == mlp->opt_dbg_optimize_quality)
- {
- mlp_create_problem_set_value (p,
- p->r_q[RQ_QUALITY_METRIC_DELAY],
- mlpi->c_b,
- address->norm_delay.norm,
- __LINE__);
- mlp_create_problem_set_value (p,
- p->r_q[RQ_QUALITY_METRIC_DISTANCE],
- mlpi->c_b,
- address->norm_distance.norm,
- __LINE__);
- }
- }
-
- return GNUNET_OK;
-}
-
-
-/**
- * Create the invariant columns c4, c6, c10, c8, c7
- */
-static void
-mlp_create_problem_add_invariant_rows (struct GAS_MLP_Handle *mlp, struct
- MLP_Problem *p)
-{
- int c;
-
- /* Feasibility */
-
- /* Row for c4) minimum connection */
- /* Number of minimum connections is min(|Peers|, n_min) */
- p->r_c4 = mlp_create_problem_create_constraint (p, "c4", GLP_LO,
- (mlp->pv.n_min >
- p->num_peers) ?
- p->num_peers : mlp->pv.n_min,
- 0.0);
-
- /* Rows for c 10) Enforce network quotas */
- for (c = 0; c < GNUNET_NT_COUNT; c++)
- {
- char *text;
- GNUNET_asprintf (&text, "c10_quota_ats_%s",
- GNUNET_NT_to_string (mlp->pv.quota_index[c]));
- p->r_quota[c] = mlp_create_problem_create_constraint (p, text, GLP_DB, 0.0,
- mlp->pv.quota_out[c]);
- GNUNET_free (text);
- }
-
- /* Optimality */
- if (GNUNET_NO == mlp->opt_dbg_feasibility_only)
- {
- char *name;
- /* Add row for c6) Maximize for diversity */
- if (GNUNET_YES == mlp->opt_dbg_optimize_diversity)
- {
- p->r_c6 = mlp_create_problem_create_constraint (p, "c6", GLP_FX, 0.0,
- 0.0);
- /* Set c6 ) Setting -D */
- mlp_create_problem_set_value (p, p->r_c6, p->c_d, -1, __LINE__);
- }
-
- /* Adding rows for c 8) Maximize utility */
- if (GNUNET_YES == mlp->opt_dbg_optimize_utility)
- {
- p->r_c8 = mlp_create_problem_create_constraint (p, "c8", GLP_FX, 0.0,
- 0.0);
- /* -u */
- mlp_create_problem_set_value (p, p->r_c8, p->c_u, -1, __LINE__);
- }
-
- /* For all quality metrics:
- * c 7) Maximize quality, austerity */
- if (GNUNET_YES == mlp->opt_dbg_optimize_quality)
- {
- for (c = 0; c < mlp->pv.m_q; c++)
- {
- GNUNET_asprintf (&name,
- "c7_q%i_%s", c,
- print_quality_type (c));
- p->r_q[c] = mlp_create_problem_create_constraint (p, name, GLP_FX, 0.0,
- 0.0);
- GNUNET_free (name);
- mlp_create_problem_set_value (p,
- p->r_q[c],
- p->c_q[c], -1, __LINE__);
- }
- }
- }
-}
-
-
-/**
- * Create the invariant columns d, u, r, q0 ... qm
- */
-static void
-mlp_create_problem_add_invariant_columns (struct GAS_MLP_Handle *mlp, struct
- MLP_Problem *p)
-{
- if (GNUNET_NO == mlp->opt_dbg_feasibility_only)
- {
- char *name;
- int c;
-
- /* Diversity d column */
- if (GNUNET_YES == mlp->opt_dbg_optimize_diversity)
- p->c_d = mlp_create_problem_create_column (p, "d", GLP_CV, GLP_LO, 0.0,
- 0.0, mlp->pv.co_D);
-
- /* Utilization u column */
- if (GNUNET_YES == mlp->opt_dbg_optimize_utility)
- p->c_u = mlp_create_problem_create_column (p, "u", GLP_CV, GLP_LO, 0.0,
- 0.0, mlp->pv.co_U);
-
- /* Relativity r column */
- if (GNUNET_YES == mlp->opt_dbg_optimize_relativity)
- p->c_r = mlp_create_problem_create_column (p, "r", GLP_CV, GLP_LO, 0.0,
- 0.0, mlp->pv.co_R);
-
- /* Quality metric columns */
- if (GNUNET_YES == mlp->opt_dbg_optimize_quality)
- {
- for (c = 0; c < mlp->pv.m_q; c++)
- {
- GNUNET_asprintf (&name, "q_%u", c);
- p->c_q[c] = mlp_create_problem_create_column (p, name, GLP_CV, GLP_LO,
- 0.0, 0.0,
- mlp->pv.co_Q[c]);
- GNUNET_free (name);
- }
- }
- }
-}
-
-
-/**
- * Create the MLP problem
- *
- * @param mlp the MLP handle
- * @return #GNUNET_OK or #GNUNET_SYSERR
- */
-static int
-mlp_create_problem (struct GAS_MLP_Handle *mlp)
-{
- struct MLP_Problem *p = &mlp->p;
- int res = GNUNET_OK;
-
- GNUNET_assert (p->prob == NULL);
- GNUNET_assert (p->ia == NULL);
- GNUNET_assert (p->ja == NULL);
- GNUNET_assert (p->ar == NULL);
- /* Reset MLP problem struct */
-
- /* create the glpk problem */
- p->prob = glp_create_prob ();
- GNUNET_assert (NULL != p->prob);
- p->num_peers = mlp_create_problem_count_peers (mlp->requested_peers,
- mlp->env->addresses);
- p->num_addresses = mlp_create_problem_count_addresses (mlp->requested_peers,
- mlp->env->addresses);
-
- /* Create problem matrix: 10 * #addresses + #q * #addresses + #q, + #peer + 2 + 1 */
- p->num_elements = (10 * p->num_addresses + mlp->pv.m_q * p->num_addresses
- + mlp->pv.m_q + p->num_peers + 2 + 1);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Rebuilding problem for %u peer(s) and %u addresse(s) and %u quality metrics == %u elements\n",
- p->num_peers,
- p->num_addresses,
- mlp->pv.m_q,
- p->num_elements);
-
- /* Set a problem name */
- glp_set_prob_name (p->prob, "GNUnet ATS bandwidth distribution");
- /* Set optimization direction to maximize */
- glp_set_obj_dir (p->prob, GLP_MAX);
-
- /* Create problem matrix */
- /* last +1 caused by glpk index starting with one: [1..elements]*/
- p->ci = 1;
- /* row index */
- p->ia = GNUNET_malloc (p->num_elements * sizeof(int));
- /* column index */
- p->ja = GNUNET_malloc (p->num_elements * sizeof(int));
- /* coefficient */
- p->ar = GNUNET_malloc (p->num_elements * sizeof(double));
-
- if ((NULL == p->ia) || (NULL == p->ja) || (NULL == p->ar))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ (
- "Problem size too large, cannot allocate memory!\n"));
- return GNUNET_SYSERR;
- }
-
- /* Adding invariant columns */
- mlp_create_problem_add_invariant_columns (mlp, p);
-
- /* Adding address independent constraint rows */
- mlp_create_problem_add_invariant_rows (mlp, p);
-
- /* Adding address dependent columns constraint rows */
- GNUNET_CONTAINER_multipeermap_iterate (mlp->env->addresses,
- &
- mlp_create_problem_add_address_information,
- mlp);
-
- /* Load the matrix */
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Loading matrix\n");
- glp_load_matrix (p->prob, (p->ci) - 1, p->ia, p->ja, p->ar);
- if (GNUNET_YES == mlp->opt_dbg_autoscale_problem)
- {
- glp_scale_prob (p->prob, GLP_SF_AUTO);
- }
-
- return res;
-}
-
-
-/**
- * Solves the LP problem
- *
- * @param mlp the MLP Handle
- * @return #GNUNET_OK if could be solved, #GNUNET_SYSERR on failure
- */
-static int
-mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp)
-{
- int res = 0;
- int res_status = 0;
-
- res = glp_simplex (mlp->p.prob, &mlp->control_param_lp);
- if (0 == res)
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem: %s\n",
- mlp_solve_to_string (res));
- else
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Solving LP problem failed: %s\n",
- mlp_solve_to_string (res));
-
- /* Analyze problem status */
- res_status = glp_get_status (mlp->p.prob);
- switch (res_status)
- {
- case GLP_OPT: /* solution is optimal */
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Solving LP problem: %s, %s\n",
- mlp_solve_to_string (res),
- mlp_status_to_string (res_status));
- return GNUNET_OK;
-
- default:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Solving LP problem failed: %s %s\n",
- mlp_solve_to_string (res),
- mlp_status_to_string (res_status));
- return GNUNET_SYSERR;
- }
-}
-
-
-/**
- * Propagates the results when MLP problem was solved
- *
- * @param cls the MLP handle
- * @param key the peer identity
- * @param value the address
- * @return #GNUNET_OK to continue
- */
-static int
-mlp_propagate_results (void *cls,
- const struct GNUNET_PeerIdentity *key,
- void *value)
-{
- struct GAS_MLP_Handle *mlp = cls;
- struct ATS_Address *address;
- struct MLP_information *mlpi;
- double mlp_bw_in = MLP_NaN;
- double mlp_bw_out = MLP_NaN;
- double mlp_use = MLP_NaN;
-
- /* Check if we have to add this peer due to a pending request */
- if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (mlp->requested_peers,
- key))
- {
- return GNUNET_OK;
- }
- address = value;
- GNUNET_assert (address->solver_information != NULL);
- mlpi = address->solver_information;
-
- mlp_bw_in = glp_mip_col_val (mlp->p.prob, mlpi->c_b);/* FIXME */
- if (mlp_bw_in > (double) UINT32_MAX)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Overflow in assigned bandwidth, reducing ...\n");
- mlp_bw_in = (double) UINT32_MAX;
- }
- mlp_bw_out = glp_mip_col_val (mlp->p.prob, mlpi->c_b);
- if (mlp_bw_out > (double) UINT32_MAX)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Overflow in assigned bandwidth, reducing ...\n");
- mlp_bw_out = (double) UINT32_MAX;
- }
- mlp_use = glp_mip_col_val (mlp->p.prob, mlpi->c_n);
-
- /*
- * Debug: solution
- * LOG (GNUNET_ERROR_TYPE_INFO, "MLP result address: `%s' `%s' length %u session %u, mlp use %.3f\n",
- * GNUNET_i2s(&address->peer), address->plugin,
- * address->addr_len, address->session_id);
- */
-
- if (GLP_YES == mlp_use)
- {
- /* This address was selected by the solver to be used */
- mlpi->n = GNUNET_YES;
- if (GNUNET_NO == address->active)
- {
- /* Address was not used before, enabling address */
- LOG (GNUNET_ERROR_TYPE_DEBUG, "%s %.2f : enabling address\n",
- (1 == mlp_use) ? "[x]" : "[ ]", mlp_bw_out);
- address->active = GNUNET_YES;
- address->assigned_bw_in = mlp_bw_in;
- mlpi->b_in = mlp_bw_in;
- address->assigned_bw_out = mlp_bw_out;
- mlpi->b_out = mlp_bw_out;
- if ((NULL == mlp->exclude_peer) || (0 != GNUNET_memcmp (&address->peer,
- mlp->exclude_peer)))
- mlp->env->bandwidth_changed_cb (mlp->env->cls, address);
- return GNUNET_OK;
- }
- else if (GNUNET_YES == address->active)
- {
- /* Address was used before, check for bandwidth change */
- if ((mlp_bw_out != address->assigned_bw_out) ||
- (mlp_bw_in != address->assigned_bw_in))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "%s %.2f : bandwidth changed\n",
- (1 == mlp_use) ? "[x]" : "[ ]", mlp_bw_out);
- address->assigned_bw_in = mlp_bw_in;
- mlpi->b_in = mlp_bw_in;
- address->assigned_bw_out = mlp_bw_out;
- mlpi->b_out = mlp_bw_out;
- if ((NULL == mlp->exclude_peer) || (0 != GNUNET_memcmp (&address->peer,
- mlp->
- exclude_peer)))
- mlp->env->bandwidth_changed_cb (mlp->env->cls, address);
- return GNUNET_OK;
- }
- }
- else
- GNUNET_break (0);
- }
- else if (GLP_NO == mlp_use)
- {
- /* This address was selected by the solver to be not used */
- mlpi->n = GNUNET_NO;
- if (GNUNET_NO == address->active)
- {
- /* Address was not used before, nothing to do */
- LOG (GNUNET_ERROR_TYPE_DEBUG, "%s %.2f : no change\n",
- (1 == mlp_use) ? "[x]" : "[ ]", mlp_bw_out);
- return GNUNET_OK;
- }
- else if (GNUNET_YES == address->active)
- {
- /* Address was used before, disabling address */
- LOG (GNUNET_ERROR_TYPE_DEBUG, "%s %.2f : disabling address\n",
- (1 == mlp_use) ? "[x]" : "[ ]", mlp_bw_out);
- address->active = GNUNET_NO;
- /* Set bandwidth to 0 */
- address->assigned_bw_in = 0;
- mlpi->b_in = 0;
- address->assigned_bw_out = 0;
- mlpi->b_out = 0;
- return GNUNET_OK;
- }
- else
- GNUNET_break (0);
- }
- else
- GNUNET_break (0);
-
- return GNUNET_OK;
-}
-
-
-static void
-notify (struct GAS_MLP_Handle *mlp,
- enum GAS_Solver_Operation op,
- enum GAS_Solver_Status stat,
- enum GAS_Solver_Additional_Information add)
-{
- mlp->env->info_cb (mlp->env->cls,
- op,
- stat,
- add);
-}
-
-
-static void
-mlp_branch_and_cut_cb (glp_tree *tree, void *info)
-{
- struct GAS_MLP_Handle *mlp = info;
- double mlp_obj = 0;
-
- switch (glp_ios_reason (tree))
- {
- case GLP_ISELECT:
- /* Do nothing here */
- break;
-
- case GLP_IPREPRO:
- /* Do nothing here */
- break;
-
- case GLP_IROWGEN:
- /* Do nothing here */
- break;
-
- case GLP_IHEUR:
- /* Do nothing here */
- break;
-
- case GLP_ICUTGEN:
- /* Do nothing here */
- break;
-
- case GLP_IBRANCH:
- /* Do nothing here */
- break;
-
- case GLP_IBINGO:
- /* A better solution was found */
- mlp->ps.mlp_gap = glp_ios_mip_gap (tree);
- mlp_obj = glp_mip_obj_val (mlp->p.prob);
- mlp->ps.lp_mlp_gap = (abs (mlp_obj - mlp->ps.lp_objective_value)) / (abs (
- mlp_obj)
- +
- DBL_EPSILON);
-
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Found better integer solution, current gaps: %.3f <= %.3f, %.3f <= %.3f\n",
- mlp->ps.mlp_gap, mlp->pv.mip_gap,
- mlp->ps.lp_mlp_gap, mlp->pv.lp_mip_gap);
-
- if (mlp->ps.mlp_gap <= mlp->pv.mip_gap)
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Current LP/MLP gap of %.3f smaller than tolerated gap of %.3f, terminating search\n",
- mlp->ps.lp_mlp_gap, mlp->pv.lp_mip_gap);
- glp_ios_terminate (tree);
- }
-
- if (mlp->ps.lp_mlp_gap <= mlp->pv.lp_mip_gap)
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Current LP/MLP gap of %.3f smaller than tolerated gap of %.3f, terminating search\n",
- mlp->ps.lp_mlp_gap, mlp->pv.lp_mip_gap);
- glp_ios_terminate (tree);
- }
-
- break;
-
- default:
- break;
- }
- // GNUNET_break (0);
-}
-
-
-/**
- * Solves the MLP problem
- *
- * @param solver the MLP Handle
- * @return #GNUNET_OK if could be solved, #GNUNET_SYSERR on failure
- */
-static int
-GAS_mlp_solve_problem (void *solver)
-{
- struct GAS_MLP_Handle *mlp = solver;
- char *filename;
- int res_lp = 0;
- int mip_res = 0;
- int mip_status = 0;
-
- struct GNUNET_TIME_Absolute start_total;
- struct GNUNET_TIME_Absolute start_cur_op;
- struct GNUNET_TIME_Relative dur_total;
- struct GNUNET_TIME_Relative dur_setup;
- struct GNUNET_TIME_Relative dur_lp;
- struct GNUNET_TIME_Relative dur_mlp;
-
- GNUNET_assert (NULL != solver);
- dur_lp = GNUNET_TIME_UNIT_ZERO;
-
- if (GNUNET_YES == mlp->stat_bulk_lock)
- {
- mlp->stat_bulk_requests++;
- return GNUNET_NO;
- }
- notify (mlp, GAS_OP_SOLVE_START, GAS_STAT_SUCCESS,
- (GNUNET_YES == mlp->stat_mlp_prob_changed) ? GAS_INFO_FULL :
- GAS_INFO_UPDATED);
- start_total = GNUNET_TIME_absolute_get ();
-
- if (0 == GNUNET_CONTAINER_multipeermap_size (mlp->requested_peers))
- {
- notify (mlp, GAS_OP_SOLVE_STOP, GAS_STAT_SUCCESS, GAS_INFO_NONE);
- return GNUNET_OK; /* No pending requests */
- }
- if (0 == GNUNET_CONTAINER_multipeermap_size (mlp->env->addresses))
- {
- notify (mlp, GAS_OP_SOLVE_STOP, GAS_STAT_SUCCESS, GAS_INFO_NONE);
- return GNUNET_OK; /* No addresses available */
- }
-
- if ((GNUNET_NO == mlp->stat_mlp_prob_changed)
- && (GNUNET_NO == mlp->stat_mlp_prob_updated))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "No changes to problem\n");
- notify (mlp, GAS_OP_SOLVE_STOP, GAS_STAT_SUCCESS, GAS_INFO_NONE);
- return GNUNET_OK;
- }
- if (GNUNET_YES == mlp->stat_mlp_prob_changed)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem size changed, rebuilding\n");
- notify (mlp, GAS_OP_SOLVE_SETUP_START, GAS_STAT_SUCCESS, GAS_INFO_FULL);
- mlp_delete_problem (mlp);
- if (GNUNET_SYSERR == mlp_create_problem (mlp))
- {
- notify (mlp, GAS_OP_SOLVE_SETUP_STOP, GAS_STAT_FAIL, GAS_INFO_FULL);
- return GNUNET_SYSERR;
- }
- notify (mlp, GAS_OP_SOLVE_SETUP_STOP, GAS_STAT_SUCCESS, GAS_INFO_FULL);
- if (GNUNET_NO == mlp->opt_dbg_intopt_presolver)
- {
- mlp->control_param_lp.presolve = GLP_YES; /* LP presolver, we need lp solution */
- mlp->control_param_mlp.presolve = GNUNET_NO; /* No presolver, we have LP solution */
- }
- else
- {
- mlp->control_param_lp.presolve = GNUNET_NO; /* LP presolver, we need lp solution */
- mlp->control_param_mlp.presolve = GLP_YES; /* No presolver, we have LP solution */
- dur_lp = GNUNET_TIME_UNIT_ZERO;
- }
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem was updated, resolving\n");
- }
-
- /* Reset solution info */
- mlp->ps.lp_objective_value = 0.0;
- mlp->ps.mlp_gap = 1.0;
- mlp->ps.mlp_objective_value = 0.0;
- mlp->ps.lp_mlp_gap = 0.0;
-
- dur_setup = GNUNET_TIME_absolute_get_duration (start_total);
-
- /* Run LP solver */
- if (GNUNET_NO == mlp->opt_dbg_intopt_presolver)
- {
- notify (mlp, GAS_OP_SOLVE_MLP_LP_START, GAS_STAT_SUCCESS,
- (GNUNET_YES == mlp->stat_mlp_prob_changed) ? GAS_INFO_FULL :
- GAS_INFO_UPDATED);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Running LP solver %s\n",
- (GLP_YES == mlp->control_param_lp.presolve) ? "with presolver" :
- "without presolver");
- start_cur_op = GNUNET_TIME_absolute_get ();
-
- /* Solve LP */
- /* Only for debugging:
- * Always use LP presolver:
- * mlp->control_param_lp.presolve = GLP_YES; */
- res_lp = mlp_solve_lp_problem (mlp);
- if (GNUNET_OK == res_lp)
- {
- mlp->ps.lp_objective_value = glp_get_obj_val (mlp->p.prob);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "LP solution was: %.3f\n",
- mlp->ps.lp_objective_value);
- }
-
- dur_lp = GNUNET_TIME_absolute_get_duration (start_cur_op);
- notify (mlp, GAS_OP_SOLVE_MLP_LP_STOP,
- (GNUNET_OK == res_lp) ? GAS_STAT_SUCCESS : GAS_STAT_FAIL,
- (GNUNET_YES == mlp->stat_mlp_prob_changed) ? GAS_INFO_FULL :
- GAS_INFO_UPDATED);
- }
-
- if (GNUNET_YES == mlp->opt_dbg_intopt_presolver)
- res_lp = GNUNET_OK;
-
- /* Run MLP solver */
- if ((GNUNET_OK == res_lp) || (GNUNET_YES == mlp->opt_dbg_intopt_presolver))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Running MLP solver \n");
- notify (mlp, GAS_OP_SOLVE_MLP_MLP_START, GAS_STAT_SUCCESS,
- (GNUNET_YES == mlp->stat_mlp_prob_changed) ? GAS_INFO_FULL :
- GAS_INFO_UPDATED);
- start_cur_op = GNUNET_TIME_absolute_get ();
-
- /* Solve MIP */
-
- /* Only for debugging, always use LP presolver */
- if (GNUNET_YES == mlp->opt_dbg_intopt_presolver)
- mlp->control_param_mlp.presolve = GNUNET_YES;
-
- mip_res = glp_intopt (mlp->p.prob, &mlp->control_param_mlp);
- switch (mip_res)
- {
- case 0:
- /* Successful */
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Solving MLP problem: %s\n",
- mlp_solve_to_string (mip_res));
- break;
-
- case GLP_ETMLIM: /* Time limit reached */
- case GLP_EMIPGAP: /* MIP gap tolerance limit reached */
- case GLP_ESTOP: /* Solver was instructed to stop*/
- /* Semi-successful */
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Solving MLP problem solution was interupted: %s\n",
- mlp_solve_to_string (mip_res));
- break;
-
- case GLP_EBOUND:
- case GLP_EROOT:
- case GLP_ENOPFS:
- case GLP_ENODFS:
- case GLP_EFAIL:
- default:
- /* Fail */
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Solving MLP problem failed: %s\n",
- mlp_solve_to_string (mip_res));
- break;
- }
-
- /* Analyze problem status */
- mip_status = glp_mip_status (mlp->p.prob);
- switch (mip_status)
- {
- case GLP_OPT: /* solution is optimal */
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "Solution of MLP problem is optimal: %s, %s\n",
- mlp_solve_to_string (mip_res),
- mlp_status_to_string (mip_status));
- mip_res = GNUNET_OK;
- break;
-
- case GLP_FEAS: /* solution is feasible but not proven optimal */
-
- if ((mlp->ps.mlp_gap <= mlp->pv.mip_gap) ||
- (mlp->ps.lp_mlp_gap <= mlp->pv.lp_mip_gap))
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Solution of MLP problem is feasible and solution within gap constraints: %s, %s\n",
- mlp_solve_to_string (mip_res),
- mlp_status_to_string (mip_status));
- mip_res = GNUNET_OK;
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "Solution of MLP problem is feasible but solution not within gap constraints: %s, %s\n",
- mlp_solve_to_string (mip_res),
- mlp_status_to_string (mip_status));
- mip_res = GNUNET_SYSERR;
- }
- break;
-
- case GLP_UNDEF: /* Solution undefined */
- case GLP_NOFEAS: /* No feasible solution */
- default:
- LOG (GNUNET_ERROR_TYPE_ERROR,
- "Solving MLP problem failed: %s %s\n",
- mlp_solve_to_string (mip_res),
- mlp_status_to_string (mip_status));
- mip_res = GNUNET_SYSERR;
- break;
- }
-
- dur_mlp = GNUNET_TIME_absolute_get_duration (start_cur_op);
- dur_total = GNUNET_TIME_absolute_get_duration (start_total);
-
- notify (mlp, GAS_OP_SOLVE_MLP_MLP_STOP,
- (GNUNET_OK == mip_res) ? GAS_STAT_SUCCESS : GAS_STAT_FAIL,
- (GNUNET_YES == mlp->stat_mlp_prob_changed) ? GAS_INFO_FULL :
- GAS_INFO_UPDATED);
- }
- else
- {
- /* Do not execute mip solver since lp solution is invalid */
- dur_mlp = GNUNET_TIME_UNIT_ZERO;
- dur_total = GNUNET_TIME_absolute_get_duration (start_total);
-
- notify (mlp, GAS_OP_SOLVE_MLP_MLP_STOP, GAS_STAT_FAIL,
- (GNUNET_YES == mlp->stat_mlp_prob_changed) ? GAS_INFO_FULL :
- GAS_INFO_UPDATED);
- mip_res = GNUNET_SYSERR;
- }
-
- /* Notify about end */
- notify (mlp, GAS_OP_SOLVE_STOP,
- ((GNUNET_OK == mip_res) && (GNUNET_OK == mip_res)) ?
- GAS_STAT_SUCCESS : GAS_STAT_FAIL,
- (GNUNET_YES == mlp->stat_mlp_prob_changed) ? GAS_INFO_FULL :
- GAS_INFO_UPDATED);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Execution time for %s solve: (total/setup/lp/mlp) : %llu %llu %llu %llu\n",
- (GNUNET_YES == mlp->stat_mlp_prob_changed) ? "full" : "updated",
- (unsigned long long) dur_total.rel_value_us,
- (unsigned long long) dur_setup.rel_value_us,
- (unsigned long long) dur_lp.rel_value_us,
- (unsigned long long) dur_mlp.rel_value_us);
-
- /* Save stats */
- mlp->ps.lp_res = res_lp;
- mlp->ps.mip_res = mip_res;
- mlp->ps.lp_presolv = mlp->control_param_lp.presolve;
- mlp->ps.mip_presolv = mlp->control_param_mlp.presolve;
- mlp->ps.p_cols = glp_get_num_cols (mlp->p.prob);
- mlp->ps.p_rows = glp_get_num_rows (mlp->p.prob);
- mlp->ps.p_elements = mlp->p.num_elements;
-
- /* Propagate result*/
- notify (mlp, GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
- (GNUNET_OK == res_lp) && (GNUNET_OK == mip_res) ? GAS_STAT_SUCCESS :
- GAS_STAT_FAIL,
- GAS_INFO_NONE);
- if ((GNUNET_OK == res_lp) && (GNUNET_OK == mip_res))
- {
- GNUNET_CONTAINER_multipeermap_iterate (mlp->env->addresses,
- &mlp_propagate_results, mlp);
- }
- notify (mlp, GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
- (GNUNET_OK == res_lp) && (GNUNET_OK == mip_res) ? GAS_STAT_SUCCESS :
- GAS_STAT_FAIL,
- GAS_INFO_NONE);
-
- struct GNUNET_TIME_Absolute time = GNUNET_TIME_absolute_get ();
- if ((GNUNET_YES == mlp->opt_dump_problem_all) ||
- (mlp->opt_dump_problem_on_fail && ((GNUNET_OK != res_lp) || (GNUNET_OK !=
- mip_res))))
- {
- /* Write problem to disk */
- switch (mlp->opt_log_format)
- {
- case MLP_CPLEX:
- GNUNET_asprintf (&filename, "problem_p_%u_a%u_%llu.cplex",
- mlp->p.num_peers,
- mlp->p.num_addresses, time.abs_value_us);
- glp_write_lp (mlp->p.prob, NULL, filename);
- break;
-
- case MLP_GLPK:
- GNUNET_asprintf (&filename, "problem_p_%u_a%u_%llu.glpk",
- mlp->p.num_peers,
- mlp->p.num_addresses, time.abs_value_us);
- glp_write_prob (mlp->p.prob, 0, filename);
- break;
-
- case MLP_MPS:
- GNUNET_asprintf (&filename, "problem_p_%u_a%u_%llu.mps", mlp->p.num_peers,
- mlp->p.num_addresses, time.abs_value_us);
- glp_write_mps (mlp->p.prob, GLP_MPS_FILE, NULL, filename);
- break;
-
- default:
- break;
- }
- LOG (GNUNET_ERROR_TYPE_ERROR, "Dumped problem to file: `%s' \n", filename);
- GNUNET_free (filename);
- }
- if ((mlp->opt_dump_solution_all) ||
- (mlp->opt_dump_solution_on_fail && ((GNUNET_OK != res_lp) || (GNUNET_OK !=
- mip_res))))
- {
- /* Write solution to disk */
- GNUNET_asprintf (&filename, "problem_p_%u_a%u_%llu.sol", mlp->p.num_peers,
- mlp->p.num_addresses, time.abs_value_us);
- glp_print_mip (mlp->p.prob, filename);
- LOG (GNUNET_ERROR_TYPE_ERROR, "Dumped solution to file: `%s' \n", filename);
- GNUNET_free (filename);
- }
-
- /* Reset change and update marker */
- mlp->control_param_lp.presolve = GLP_NO;
- mlp->stat_mlp_prob_updated = GNUNET_NO;
- mlp->stat_mlp_prob_changed = GNUNET_NO;
-
- if ((GNUNET_OK == res_lp) && (GNUNET_OK == mip_res))
- return GNUNET_OK;
- else
- return GNUNET_SYSERR;
-}
-
-/**
- * Add a single address to the solve
- *
- * @param solver the solver Handle
- * @param address the address to add
- * @param network network type of this address
- */
-static void
-GAS_mlp_address_add (void *solver,
- struct ATS_Address *address,
- uint32_t network)
-{
- struct GAS_MLP_Handle *mlp = solver;
-
- if (GNUNET_NT_COUNT <= network)
- {
- GNUNET_break (0);
- return;
- }
-
- if (NULL == address->solver_information)
- {
- address->solver_information = GNUNET_new (struct MLP_information);
- }
- else
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _ ("Adding address for peer `%s' multiple times\n"),
- GNUNET_i2s (&address->peer));
-
- /* Is this peer included in the problem? */
- if (NULL ==
- GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers,
- &address->peer))
- {
- /* FIXME: should this be an error? */
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Adding address for peer `%s' without address request\n",
- GNUNET_i2s (&address->peer));
- return;
- }
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Adding address for peer `%s' with address request \n",
- GNUNET_i2s (&address->peer));
- /* Problem size changed: new address for peer with pending request */
- mlp->stat_mlp_prob_changed = GNUNET_YES;
- if (GNUNET_YES == mlp->opt_mlp_auto_solve)
- GAS_mlp_solve_problem (solver);
-}
-
-
-/**
- * Transport properties for this address have changed
- *
- * @param solver solver handle
- * @param address the address
- */
-static void
-GAS_mlp_address_property_changed (void *solver,
- struct ATS_Address *address)
-{
- struct MLP_information *mlpi = address->solver_information;
- struct GAS_MLP_Handle *mlp = solver;
-
- if (NULL == mlp->p.prob)
- return; /* There is no MLP problem to update yet */
-
- if (NULL == mlpi)
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- _ ("Updating address property for peer `%s' %p not added before\n"),
- GNUNET_i2s (&address->peer),
- address);
- GNUNET_break (0);
- return;
- }
- if (NULL ==
- GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers,
- &address->peer))
- {
- /* Peer is not requested, so no need to update problem */
- return;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Updating properties for peer `%s'\n",
- GNUNET_i2s (&address->peer));
-
- if (GNUNET_YES == mlp->opt_dbg_feasibility_only)
- return;
-
- /* Update c7) [r_q[index]][c_b] = f_q * q_averaged[type_index] */
- if ((GNUNET_YES ==
- mlp_create_problem_update_value (&mlp->p,
- mlp->p.r_q[RQ_QUALITY_METRIC_DELAY],
- mlpi->c_b,
- address->norm_delay.norm,
- __LINE__)) ||
- (GNUNET_YES ==
- mlp_create_problem_update_value (&mlp->p,
- mlp->p.r_q[RQ_QUALITY_METRIC_DISTANCE],
- mlpi->c_b,
- address->norm_distance.norm,
- __LINE__)))
- {
- mlp->stat_mlp_prob_updated = GNUNET_YES;
- if (GNUNET_YES == mlp->opt_mlp_auto_solve)
- GAS_mlp_solve_problem (solver);
- }
-}
-
-
-/**
- * Find the active address in the set of addresses of a peer
- * @param cls destination
- * @param key peer id
- * @param value address
- * @return #GNUNET_OK
- */
-static int
-mlp_get_preferred_address_it (void *cls,
- const struct GNUNET_PeerIdentity *key,
- void *value)
-{
- static int counter = 0;
- struct ATS_Address **aa = cls;
- struct ATS_Address *addr = value;
- struct MLP_information *mlpi = addr->solver_information;
-
- if (mlpi == NULL)
- return GNUNET_YES;
-
- /*
- * Debug output
- * GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- * "MLP [%u] Peer `%s' %s length %u session %u active %s mlp active %s\n",
- * counter, GNUNET_i2s (&addr->peer), addr->plugin, addr->addr_len, addr->session_id,
- * (GNUNET_YES == addr->active) ? "active" : "inactive",
- * (GNUNET_YES == mlpi->n) ? "active" : "inactive");
- */
-
- if (GNUNET_YES == mlpi->n)
- {
- (*aa) = addr;
- (*aa)->assigned_bw_in = mlpi->b_in;
- (*aa)->assigned_bw_out = mlpi->b_out;
- return GNUNET_NO;
- }
- counter++;
- return GNUNET_YES;
-}
-
-
-static double
-get_peer_pref_value (struct GAS_MLP_Handle *mlp,
- const struct GNUNET_PeerIdentity *peer)
-{
- double res;
- const double *preferences;
- int c;
-
- preferences = mlp->env->get_preferences (mlp->env->cls, peer);
- res = 0.0;
- for (c = 0; c < GNUNET_ATS_PREFERENCE_END; c++)
- {
- /* fprintf (stderr, "VALUE[%u] %s %.3f \n",
- * c, GNUNET_i2s (&cur->addr->peer), t[c]); */
- res += preferences[c];
- }
-
- res /= GNUNET_ATS_PREFERENCE_END;
- res += 1.0;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Peer preference for peer `%s' == %.2f\n",
- GNUNET_i2s (peer), res);
-
- return res;
-}
-
-
-/**
- * Get the preferred address for a specific peer
- *
- * @param solver the MLP Handle
- * @param peer the peer
- */
-static void
-GAS_mlp_get_preferred_address (void *solver,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct GAS_MLP_Handle *mlp = solver;
- struct ATS_Peer *p;
- struct ATS_Address *res;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Getting preferred address for `%s'\n",
- GNUNET_i2s (peer));
-
- /* Is this peer included in the problem? */
- if (NULL ==
- GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers,
- peer))
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Adding peer `%s' to list of requested_peers with requests\n",
- GNUNET_i2s (peer));
-
- p = GNUNET_new (struct ATS_Peer);
- p->id = (*peer);
- p->f = get_peer_pref_value (mlp, peer);
- GNUNET_CONTAINER_multipeermap_put (mlp->requested_peers,
- peer, p,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
-
- /* Added new peer, we have to rebuild problem before solving */
- mlp->stat_mlp_prob_changed = GNUNET_YES;
-
- if ((GNUNET_YES == mlp->opt_mlp_auto_solve) &&
- (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (
- mlp->env->addresses,
- peer)))
- {
- mlp->exclude_peer = peer;
- GAS_mlp_solve_problem (mlp);
- mlp->exclude_peer = NULL;
- }
- }
- /* Get prefered address */
- res = NULL;
- GNUNET_CONTAINER_multipeermap_get_multiple (mlp->env->addresses, peer,
- &mlp_get_preferred_address_it,
- &res);
- if (NULL != res)
- mlp->env->bandwidth_changed_cb (mlp->env->cls,
- res);
-}
-
-
-/**
- * Deletes a single address in the MLP problem
- *
- * The MLP problem has to be recreated and the problem has to be resolved
- *
- * @param solver the MLP Handle
- * @param address the address to delete
- */
-static void
-GAS_mlp_address_delete (void *solver,
- struct ATS_Address *address)
-{
- struct GAS_MLP_Handle *mlp = solver;
- struct MLP_information *mlpi;
- struct ATS_Address *res;
- int was_active;
-
- mlpi = address->solver_information;
- if (NULL != mlpi)
- {
- /* Remove full address */
- GNUNET_free (mlpi);
- address->solver_information = NULL;
- }
- was_active = address->active;
- address->active = GNUNET_NO;
- address->assigned_bw_in = 0;
- address->assigned_bw_out = 0;
-
- /* Is this peer included in the problem? */
- if (NULL ==
- GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers,
- &address->peer))
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Deleting address for peer `%s' without address request \n",
- GNUNET_i2s (&address->peer));
- return;
- }
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Deleting address for peer `%s' with address request \n",
- GNUNET_i2s (&address->peer));
-
- /* Problem size changed: new address for peer with pending request */
- mlp->stat_mlp_prob_changed = GNUNET_YES;
- if (GNUNET_YES == mlp->opt_mlp_auto_solve)
- {
- GAS_mlp_solve_problem (solver);
- }
- if (GNUNET_YES == was_active)
- {
- GAS_mlp_get_preferred_address (solver, &address->peer);
- res = NULL;
- GNUNET_CONTAINER_multipeermap_get_multiple (mlp->env->addresses,
- &address->peer,
- &mlp_get_preferred_address_it,
- &res);
- if (NULL == res)
- {
- /* No alternative address, disconnecting peer */
- mlp->env->bandwidth_changed_cb (mlp->env->cls, address);
- }
- }
-}
-
-
-/**
- * Start a bulk operation
- *
- * @param solver the solver
- */
-static void
-GAS_mlp_bulk_start (void *solver)
-{
- struct GAS_MLP_Handle *s = solver;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Locking solver for bulk operation ...\n");
- GNUNET_assert (NULL != solver);
- s->stat_bulk_lock++;
-}
-
-
-static void
-GAS_mlp_bulk_stop (void *solver)
-{
- struct GAS_MLP_Handle *s = solver;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Unlocking solver from bulk operation ...\n");
- GNUNET_assert (NULL != solver);
-
- if (s->stat_bulk_lock < 1)
- {
- GNUNET_break (0);
- return;
- }
- s->stat_bulk_lock--;
-
- if (0 < s->stat_bulk_requests)
- {
- GAS_mlp_solve_problem (solver);
- s->stat_bulk_requests = 0;
- }
-}
-
-
-
-/**
- * Stop notifying about address and bandwidth changes for this peer
- *
- * @param solver the MLP handle
- * @param peer the peer
- */
-static void
-GAS_mlp_stop_get_preferred_address (void *solver,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct GAS_MLP_Handle *mlp = solver;
- struct ATS_Peer *p = NULL;
-
- GNUNET_assert (NULL != solver);
- GNUNET_assert (NULL != peer);
- if (NULL != (p = GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers,
- peer)))
- {
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multipeermap_remove (mlp->requested_peers,
- peer, p));
- GNUNET_free (p);
-
- mlp->stat_mlp_prob_changed = GNUNET_YES;
- if (GNUNET_YES == mlp->opt_mlp_auto_solve)
- {
- GAS_mlp_solve_problem (solver);
- }
- }
-}
-
-
-/**
- * Changes the preferences for a peer in the MLP problem
- *
- * @param solver the MLP Handle
- * @param peer the peer
- * @param kind the kind to change the preference
- * @param pref_rel the relative score
- */
-static void
-GAS_mlp_address_change_preference (void *solver,
- const struct GNUNET_PeerIdentity *peer,
- enum GNUNET_ATS_PreferenceKind kind,
- double pref_rel)
-{
- struct GAS_MLP_Handle *mlp = solver;
- struct ATS_Peer *p;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Changing preference for address for peer `%s' to %.2f\n",
- GNUNET_i2s (peer),
- pref_rel);
-
- GNUNET_STATISTICS_update (mlp->env->stats,
- "# LP address preference changes", 1, GNUNET_NO);
- /* Update the constraints with changed preferences */
-
-
-
- /* Update relativity constraint c9 */
- if (NULL == (p = GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers,
- peer)))
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Updating preference for unknown peer `%s'\n",
- GNUNET_i2s (peer));
- return;
- }
-
- if (GNUNET_NO == mlp->opt_dbg_feasibility_only)
- {
- p->f = get_peer_pref_value (mlp, peer);
- mlp_create_problem_update_value (&mlp->p,
- p->r_c9,
- mlp->p.c_r,
- -p->f,
- __LINE__);
-
- /* Problem size changed: new address for peer with pending request */
- mlp->stat_mlp_prob_updated = GNUNET_YES;
- if (GNUNET_YES == mlp->opt_mlp_auto_solve)
- GAS_mlp_solve_problem (solver);
- }
-}
-
-
-/**
- * Get application feedback for a peer
- *
- * @param solver the solver handle
- * @param application the application
- * @param peer the peer to change the preference for
- * @param scope the time interval for this feedback: [now - scope .. now]
- * @param kind the kind to change the preference
- * @param score the score
- */
-static void
-GAS_mlp_address_preference_feedback (void *solver,
- struct GNUNET_SERVICE_Client *application,
- const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_TIME_Relative scope,
- enum GNUNET_ATS_PreferenceKind kind,
- double score)
-{
- struct GAS_PROPORTIONAL_Handle *s = solver;
-
- GNUNET_assert (NULL != solver);
- GNUNET_assert (NULL != peer);
- GNUNET_assert (NULL != s);
-}
-
-
-static int
-mlp_free_peers (void *cls,
- const struct GNUNET_PeerIdentity *key, void *value)
-{
- struct GNUNET_CONTAINER_MultiPeerMap *map = cls;
- struct ATS_Peer *p = value;
-
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multipeermap_remove (map, key, value));
- GNUNET_free (p);
-
- return GNUNET_OK;
-}
-
-
-/**
- * Shutdown the MLP problem solving component
- *
- * @param cls the solver handle
- * @return NULL
- */
-void *
-libgnunet_plugin_ats_mlp_done (void *cls)
-{
- struct GNUNET_ATS_SolverFunctions *sf = cls;
- struct GAS_MLP_Handle *mlp = sf->cls;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Shutting down mlp solver\n");
- mlp_delete_problem (mlp);
- GNUNET_CONTAINER_multipeermap_iterate (mlp->requested_peers,
- &mlp_free_peers,
- mlp->requested_peers);
- GNUNET_CONTAINER_multipeermap_destroy (mlp->requested_peers);
- mlp->requested_peers = NULL;
-
- /* Clean up GLPK environment */
- glp_free_env ();
- GNUNET_free (mlp);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Shutdown down of mlp solver complete\n");
- return NULL;
-}
-
-
-void *
-libgnunet_plugin_ats_mlp_init (void *cls)
-{
- static struct GNUNET_ATS_SolverFunctions sf;
- struct GNUNET_ATS_PluginEnvironment *env = cls;
- struct GAS_MLP_Handle *mlp = GNUNET_new (struct GAS_MLP_Handle);
- float f_tmp;
- unsigned long long tmp;
- unsigned int b_min;
- unsigned int n_min;
- int c;
- char *outputformat;
-
- struct GNUNET_TIME_Relative max_duration;
- long long unsigned int max_iterations;
-
- /* Init GLPK environment */
- int res = glp_init_env ();
-
- switch (res)
- {
- case 0:
- LOG (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n",
- "initialization successful");
- break;
-
- case 1:
- LOG (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n",
- "environment is already initialized");
- break;
-
- case 2:
- LOG (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n",
- "initialization failed (insufficient memory)");
- GNUNET_free (mlp);
- return NULL;
- break;
-
- case 3:
- LOG (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n",
- "initialization failed (unsupported programming model)");
- GNUNET_free (mlp);
- return NULL;
- break;
-
- default:
- break;
- }
-
- mlp->opt_dump_problem_all = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
- "ats",
- "MLP_DUMP_PROBLEM_ALL");
- if (GNUNET_SYSERR == mlp->opt_dump_problem_all)
- mlp->opt_dump_problem_all = GNUNET_NO;
-
- mlp->opt_dump_solution_all = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
- "ats",
- "MLP_DUMP_SOLUTION_ALL");
- if (GNUNET_SYSERR == mlp->opt_dump_solution_all)
- mlp->opt_dump_solution_all = GNUNET_NO;
-
- mlp->opt_dump_problem_on_fail = GNUNET_CONFIGURATION_get_value_yesno (
- env->cfg,
- "ats",
- "MLP_DUMP_PROBLEM_ON_FAIL");
- if (GNUNET_SYSERR == mlp->opt_dump_problem_on_fail)
- mlp->opt_dump_problem_on_fail = GNUNET_NO;
-
- mlp->opt_dump_solution_on_fail = GNUNET_CONFIGURATION_get_value_yesno (
- env->cfg,
- "ats",
- "MLP_DUMP_SOLUTION_ON_FAIL");
- if (GNUNET_SYSERR == mlp->opt_dump_solution_on_fail)
- mlp->opt_dump_solution_on_fail = GNUNET_NO;
-
- mlp->opt_dbg_glpk_verbose = GNUNET_CONFIGURATION_get_value_yesno (env->cfg,
- "ats",
- "MLP_DBG_GLPK_VERBOSE");
- if (GNUNET_SYSERR == mlp->opt_dbg_glpk_verbose)
- mlp->opt_dbg_glpk_verbose = GNUNET_NO;
-
- mlp->opt_dbg_feasibility_only = GNUNET_CONFIGURATION_get_value_yesno (
- env->cfg,
- "ats",
- "MLP_DBG_FEASIBILITY_ONLY");
- if (GNUNET_SYSERR == mlp->opt_dbg_feasibility_only)
- mlp->opt_dbg_feasibility_only = GNUNET_NO;
- if (GNUNET_YES == mlp->opt_dbg_feasibility_only)
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "MLP solver is configured to check feasibility only!\n");
-
- mlp->opt_dbg_autoscale_problem = GNUNET_CONFIGURATION_get_value_yesno (
- env->cfg,
- "ats",
- "MLP_DBG_AUTOSCALE_PROBLEM");
- if (GNUNET_SYSERR == mlp->opt_dbg_autoscale_problem)
- mlp->opt_dbg_autoscale_problem = GNUNET_NO;
- if (GNUNET_YES == mlp->opt_dbg_autoscale_problem)
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "MLP solver is configured automatically scale the problem!\n");
-
- mlp->opt_dbg_intopt_presolver = GNUNET_CONFIGURATION_get_value_yesno (
- env->cfg,
- "ats",
- "MLP_DBG_INTOPT_PRESOLVE");
- if (GNUNET_SYSERR == mlp->opt_dbg_intopt_presolver)
- mlp->opt_dbg_intopt_presolver = GNUNET_NO;
- if (GNUNET_YES == mlp->opt_dbg_intopt_presolver)
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "MLP solver is configured use the mlp presolver\n");
-
- mlp->opt_dbg_optimize_diversity = GNUNET_CONFIGURATION_get_value_yesno (
- env->cfg,
- "ats",
- "MLP_DBG_OPTIMIZE_DIVERSITY");
- if (GNUNET_SYSERR == mlp->opt_dbg_optimize_diversity)
- mlp->opt_dbg_optimize_diversity = GNUNET_YES;
- if (GNUNET_NO == mlp->opt_dbg_optimize_diversity)
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "MLP solver is not optimizing for diversity\n");
-
- mlp->opt_dbg_optimize_relativity = GNUNET_CONFIGURATION_get_value_yesno (
- env->cfg,
- "ats",
- "MLP_DBG_OPTIMIZE_RELATIVITY");
- if (GNUNET_SYSERR == mlp->opt_dbg_optimize_relativity)
- mlp->opt_dbg_optimize_relativity = GNUNET_YES;
- if (GNUNET_NO == mlp->opt_dbg_optimize_relativity)
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "MLP solver is not optimizing for relativity\n");
-
- mlp->opt_dbg_optimize_quality = GNUNET_CONFIGURATION_get_value_yesno (
- env->cfg,
- "ats",
- "MLP_DBG_OPTIMIZE_QUALITY");
- if (GNUNET_SYSERR == mlp->opt_dbg_optimize_quality)
- mlp->opt_dbg_optimize_quality = GNUNET_YES;
- if (GNUNET_NO == mlp->opt_dbg_optimize_quality)
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "MLP solver is not optimizing for quality\n");
-
- mlp->opt_dbg_optimize_utility = GNUNET_CONFIGURATION_get_value_yesno (
- env->cfg,
- "ats",
- "MLP_DBG_OPTIMIZE_UTILITY");
- if (GNUNET_SYSERR == mlp->opt_dbg_optimize_utility)
- mlp->opt_dbg_optimize_utility = GNUNET_YES;
- if (GNUNET_NO == mlp->opt_dbg_optimize_utility)
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "MLP solver is not optimizing for utility\n");
-
- if ((GNUNET_NO == mlp->opt_dbg_optimize_utility) &&
- (GNUNET_NO == mlp->opt_dbg_optimize_quality) &&
- (GNUNET_NO == mlp->opt_dbg_optimize_relativity) &&
- (GNUNET_NO == mlp->opt_dbg_optimize_utility) &&
- (GNUNET_NO == mlp->opt_dbg_feasibility_only))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR,
- _ (
- "MLP solver is not optimizing for anything, changing to feasibility check\n"));
- mlp->opt_dbg_feasibility_only = GNUNET_YES;
- }
-
- if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (env->cfg,
- "ats",
- "MLP_LOG_FORMAT",
- &outputformat))
- mlp->opt_log_format = MLP_CPLEX;
- else
- {
- GNUNET_STRINGS_utf8_toupper (outputformat, outputformat);
- if (0 == strcmp (outputformat, "MPS"))
- {
- mlp->opt_log_format = MLP_MPS;
- }
- else if (0 == strcmp (outputformat, "CPLEX"))
- {
- mlp->opt_log_format = MLP_CPLEX;
- }
- else if (0 == strcmp (outputformat, "GLPK"))
- {
- mlp->opt_log_format = MLP_GLPK;
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "Invalid log format `%s' in configuration, using CPLEX!\n",
- outputformat);
- mlp->opt_log_format = MLP_CPLEX;
- }
- GNUNET_free (outputformat);
- }
-
- mlp->pv.BIG_M = (double) BIG_M_VALUE;
-
- mlp->pv.mip_gap = (double) 0.0;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "MLP_MAX_MIP_GAP",
- &f_tmp))
- {
- if ((f_tmp < 0.0) || (f_tmp > 1.0))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "MIP gap", f_tmp);
- }
- else
- {
- mlp->pv.mip_gap = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s of %.3f\n",
- "MIP gap", f_tmp);
- }
- }
-
- mlp->pv.lp_mip_gap = (double) 0.0;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "MLP_MAX_LP_MIP_GAP",
- &f_tmp))
- {
- if ((f_tmp < 0.0) || (f_tmp > 1.0))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "LP/MIP", f_tmp);
- }
- else
- {
- mlp->pv.lp_mip_gap = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s gap of %.3f\n",
- "LP/MIP", f_tmp);
- }
- }
-
- /* Get timeout for iterations */
- if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (env->cfg, "ats",
- "MLP_MAX_DURATION",
- &max_duration))
- {
- max_duration = MLP_MAX_EXEC_DURATION;
- }
-
- /* Get maximum number of iterations */
- if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats",
- "MLP_MAX_ITERATIONS",
- &max_iterations))
- {
- max_iterations = MLP_MAX_ITERATIONS;
- }
-
- /* Get diversity coefficient from configuration */
- mlp->pv.co_D = MLP_DEFAULT_D;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "MLP_COEFFICIENT_D",
- &f_tmp))
- {
- if ((f_tmp < 0.0))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "MLP_COEFFICIENT_D", f_tmp);
- }
- else
- {
- mlp->pv.co_D = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s gap of %.3f\n",
- "MLP_COEFFICIENT_D", f_tmp);
- }
- }
-
- /* Get relativity coefficient from configuration */
- mlp->pv.co_R = MLP_DEFAULT_R;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "MLP_COEFFICIENT_R",
- &f_tmp))
- {
- if ((f_tmp < 0.0))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "MLP_COEFFICIENT_R", f_tmp);
- }
- else
- {
- mlp->pv.co_R = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s gap of %.3f\n",
- "MLP_COEFFICIENT_R", f_tmp);
- }
- }
-
-
- /* Get utilization coefficient from configuration */
- mlp->pv.co_U = MLP_DEFAULT_U;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "MLP_COEFFICIENT_U",
- &f_tmp))
- {
- if ((f_tmp < 0.0))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "MLP_COEFFICIENT_U", f_tmp);
- }
- else
- {
- mlp->pv.co_U = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s gap of %.3f\n",
- "MLP_COEFFICIENT_U", f_tmp);
- }
- }
-
- /* Get quality metric coefficients from configuration */
- for (c = 0; c < RQ_QUALITY_METRIC_COUNT; c++)
- {
- /* initialize quality coefficients with default value 1.0 */
- mlp->pv.co_Q[c] = MLP_DEFAULT_QUALITY;
- }
-
-
- if (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats",
- "MLP_COEFFICIENT_QUALITY_DELAY",
- &tmp))
- mlp->pv.co_Q[RQ_QUALITY_METRIC_DELAY] = (double) tmp / 100;
- else
- mlp->pv.co_Q[RQ_QUALITY_METRIC_DELAY] = MLP_DEFAULT_QUALITY;
-
- if (GNUNET_OK ==
- GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats",
- "MLP_COEFFICIENT_QUALITY_DISTANCE",
- &tmp))
- mlp->pv.co_Q[RQ_QUALITY_METRIC_DISTANCE] = (double) tmp / 100;
- else
- mlp->pv.co_Q[RQ_QUALITY_METRIC_DISTANCE] = MLP_DEFAULT_QUALITY;
-
- /* Get minimum bandwidth per used address from configuration */
- if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats",
- "MLP_MIN_BANDWIDTH",
- &tmp))
- b_min = tmp;
- else
- {
- b_min = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
- }
-
- /* Get minimum number of connections from configuration */
- if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (env->cfg, "ats",
- "MLP_MIN_CONNECTIONS",
- &tmp))
- n_min = tmp;
- else
- n_min = MLP_DEFAULT_MIN_CONNECTIONS;
-
- /* Init network quotas */
- for (c = 0; c < GNUNET_NT_COUNT; c++)
- {
- mlp->pv.quota_index[c] = c;
- mlp->pv.quota_out[c] = env->out_quota[c];
- mlp->pv.quota_in[c] = env->in_quota[c];
-
- LOG (GNUNET_ERROR_TYPE_INFO,
- "Quota for network `%s' (in/out) %llu/%llu\n",
- GNUNET_NT_to_string (c),
- mlp->pv.quota_out[c],
- mlp->pv.quota_in[c]);
- /* Check if defined quota could make problem unsolvable */
- if ((n_min * b_min) > mlp->pv.quota_out[c])
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- _ (
- "Adjusting inconsistent outbound quota configuration for network `%s', is %llu must be at least %llu\n"),
- GNUNET_NT_to_string (mlp->pv.quota_index[c]),
- mlp->pv.quota_out[c],
- (n_min * b_min));
- mlp->pv.quota_out[c] = (n_min * b_min);
- }
- if ((n_min * b_min) > mlp->pv.quota_in[c])
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- _ (
- "Adjusting inconsistent inbound quota configuration for network `%s', is %llu must be at least %llu\n"),
- GNUNET_NT_to_string (mlp->pv.quota_index[c]),
- mlp->pv.quota_in[c],
- (n_min * b_min));
- mlp->pv.quota_in[c] = (n_min * b_min);
- }
- /* Check if bandwidth is too big to make problem solvable */
- if (mlp->pv.BIG_M < mlp->pv.quota_out[c])
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- _ (
- "Adjusting outbound quota configuration for network `%s'from %llu to %.0f\n"),
- GNUNET_NT_to_string (mlp->pv.quota_index[c]),
- mlp->pv.quota_out[c],
- mlp->pv.BIG_M);
- mlp->pv.quota_out[c] = mlp->pv.BIG_M;
- }
- if (mlp->pv.BIG_M < mlp->pv.quota_in[c])
- {
- LOG (GNUNET_ERROR_TYPE_INFO,
- _ (
- "Adjusting inbound quota configuration for network `%s' from %llu to %.0f\n"),
- GNUNET_NT_to_string (mlp->pv.quota_index[c]),
- mlp->pv.quota_in[c],
- mlp->pv.BIG_M);
- mlp->pv.quota_in[c] = mlp->pv.BIG_M;
- }
- }
- mlp->env = env;
- sf.cls = mlp;
- sf.s_add = &GAS_mlp_address_add;
- sf.s_address_update_property = &GAS_mlp_address_property_changed;
- sf.s_get = &GAS_mlp_get_preferred_address;
- sf.s_get_stop = &GAS_mlp_stop_get_preferred_address;
- sf.s_pref = &GAS_mlp_address_change_preference;
- sf.s_feedback = &GAS_mlp_address_preference_feedback;
- sf.s_del = &GAS_mlp_address_delete;
- sf.s_bulk_start = &GAS_mlp_bulk_start;
- sf.s_bulk_stop = &GAS_mlp_bulk_stop;
-
- /* Setting MLP Input variables */
- mlp->pv.b_min = b_min;
- mlp->pv.n_min = n_min;
- mlp->pv.m_q = RQ_QUALITY_METRIC_COUNT;
- mlp->stat_mlp_prob_changed = GNUNET_NO;
- mlp->stat_mlp_prob_updated = GNUNET_NO;
- mlp->opt_mlp_auto_solve = GNUNET_YES;
- mlp->requested_peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
- mlp->stat_bulk_requests = 0;
- mlp->stat_bulk_lock = 0;
-
- /* Setup GLPK */
- /* Redirect GLPK output to GNUnet logging */
- glp_term_hook (&mlp_term_hook, (void *) mlp);
-
- /* Init LP solving parameters */
- glp_init_smcp (&mlp->control_param_lp);
- mlp->control_param_lp.msg_lev = GLP_MSG_OFF;
- if (GNUNET_YES == mlp->opt_dbg_glpk_verbose)
- mlp->control_param_lp.msg_lev = GLP_MSG_ALL;
-
- mlp->control_param_lp.it_lim = max_iterations;
- mlp->control_param_lp.tm_lim = max_duration.rel_value_us / 1000LL;
-
- /* Init MLP solving parameters */
- glp_init_iocp (&mlp->control_param_mlp);
- /* Setting callback function */
- mlp->control_param_mlp.cb_func = &mlp_branch_and_cut_cb;
- mlp->control_param_mlp.cb_info = mlp;
- mlp->control_param_mlp.msg_lev = GLP_MSG_OFF;
- mlp->control_param_mlp.mip_gap = mlp->pv.mip_gap;
- if (GNUNET_YES == mlp->opt_dbg_glpk_verbose)
- mlp->control_param_mlp.msg_lev = GLP_MSG_ALL;
- mlp->control_param_mlp.tm_lim = max_duration.rel_value_us / 1000LL;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "solver ready\n");
-
- return &sf;
-}
-
-/* end of plugin_ats_mlp.c */
diff --git a/src/ats/plugin_ats_ril.c b/src/ats/plugin_ats_ril.c
deleted file mode 100644
index 7be3cb0a1..000000000
--- a/src/ats/plugin_ats_ril.c
+++ /dev/null
@@ -1,2997 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2011-2014 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-
-/**
- * @file ats/plugin_ats_ril.c
- * @brief ATS reinforcement learning solver
- * @author Fabian Oehlmann
- * @author Matthias Wachs
- */
-#include "platform.h"
-#include <float.h>
-#include <math.h>
-#include "gnunet_ats_plugin.h"
-#include "gnunet-service-ats_addresses.h"
-
-
-
-#define LOG(kind, ...) GNUNET_log_from (kind, "ats-ril", __VA_ARGS__)
-
-#define RIL_MIN_BW (5 * ntohl ( \
- GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT. \
- value__))
-#define RIL_MAX_BW GNUNET_ATS_MaxBandwidth
-
-#define RIL_ACTION_INVALID -1
-#define RIL_INTERVAL_EXPONENT 10
-#define RIL_UTILITY_DELAY_MAX 1000
-
-#define RIL_DEFAULT_STEP_TIME_MIN GNUNET_TIME_relative_multiply ( \
- GNUNET_TIME_UNIT_MILLISECONDS, 200)
-#define RIL_DEFAULT_STEP_TIME_MAX GNUNET_TIME_relative_multiply ( \
- GNUNET_TIME_UNIT_MILLISECONDS, 2000)
-#define RIL_DEFAULT_ALGORITHM RIL_ALGO_SARSA
-#define RIL_DEFAULT_SELECT RIL_SELECT_SOFTMAX
-#define RIL_DEFAULT_WELFARE RIL_WELFARE_NASH
-#define RIL_DEFAULT_DISCOUNT_BETA 0.6
-#define RIL_DEFAULT_DISCOUNT_GAMMA 0.5
-#define RIL_DEFAULT_GRADIENT_STEP_SIZE 0.01
-#define RIL_DEFAULT_TRACE_DECAY 0.5
-#define RIL_DEFAULT_EXPLORE_RATIO 1
-#define RIL_DEFAULT_EXPLORE_DECAY 0.95
-#define RIL_DEFAULT_RBF_DIVISOR 50
-#define RIL_DEFAULT_TEMPERATURE 0.1
-#define RIL_DEFAULT_TEMPERATURE_DECAY 1
-
-#define RIL_INC_DEC_STEP_SIZE 1
-#define RIL_NOP_DECAY 0.5
-
-/**
- * ATS reinforcement learning solver
- *
- * General description
- */
-
-/**
- * The actions, how an agent can manipulate the current assignment. I.e. how the bandwidth can be
- * changed for the currently chosen address. Not depicted in the enum are the actions of switching
- * to a particular address. The action of switching to address with index i is depicted by the
- * number (RIL_ACTION_TYPE_NUM + i).
- */
-enum RIL_Action_Type
-{
- RIL_ACTION_NOTHING = 0,
- RIL_ACTION_BW_IN_DBL = -2, // TODO? Potentially add more actions
- RIL_ACTION_BW_IN_HLV = -3,
- RIL_ACTION_BW_IN_INC = 1,
- RIL_ACTION_BW_IN_DEC = 2,
- RIL_ACTION_BW_OUT_DBL = -4,
- RIL_ACTION_BW_OUT_HLV = -5,
- RIL_ACTION_BW_OUT_INC = 3,
- RIL_ACTION_BW_OUT_DEC = 4,
- RIL_ACTION_TYPE_NUM = 5
-};
-
-enum RIL_Algorithm
-{
- RIL_ALGO_SARSA = 0,
- RIL_ALGO_Q = 1
-};
-
-enum RIL_Select
-{
- RIL_SELECT_SOFTMAX = 0,
- RIL_SELECT_EGREEDY = 1
-};
-
-enum RIL_Welfare
-{
- RIL_WELFARE_NASH,
- RIL_WELFARE_EGALITARIAN
-};
-
-enum RIL_E_Modification
-{
- RIL_E_DECAY,
- RIL_E_ZERO,
- RIL_E_ACCUMULATE,
- RIL_E_REPLACE
-};
-
-/**
- * Global learning parameters
- */
-struct RIL_Learning_Parameters
-{
- /**
- * The TD-algorithm to use
- */
- enum RIL_Algorithm algorithm;
-
- /**
- * Gradient-descent step-size
- */
- double alpha;
-
- /**
- * Learning discount variable in the TD-update for semi-MDPs
- */
- double beta;
-
- /**
- * Learning discount factor in the TD-update for MDPs
- */
- double gamma;
-
- /**
- * Trace-decay factor for eligibility traces
- */
- double lambda;
-
- /**
- * Whether to accumulate or replace eligibility traces
- */
- enum RIL_E_Modification eligibility_trace_mode;
-
- /**
- * Initial softmax action-selection temperature
- */
- double temperature_init;
-
- /**
- * Softmax action-selection temperature
- */
- double temperature;
-
- /**
- * Decay factor of the temperature value
- */
- double temperature_decay;
-
- /**
- * Which measure of social welfare should be used
- */
- enum RIL_Welfare social_welfare;
-
- /**
- * State space divisor
- */
- unsigned long long rbf_divisor;
-
- /**
- * Action selection strategy;
- */
- enum RIL_Select select;
-
- /**
- * Initial exploration ratio value
- */
- double epsilon_init;
-
- /**
- * Ratio, with what probability an agent should explore in the e-greed policy
- */
- double epsilon;
-
- /**
- * Decay factor of the explore ratio
- */
- double epsilon_decay;
-
- /**
- * Minimal interval time between steps in milliseconds
- */
- struct GNUNET_TIME_Relative step_time_min;
-
- /**
- * Maximum interval time between steps in milliseconds
- */
- struct GNUNET_TIME_Relative step_time_max;
-};
-
-/**
- * Wrapper for addresses to store them in agent's linked list
- */
-struct RIL_Address_Wrapped
-{
- /**
- * Next in DLL
- */
- struct RIL_Address_Wrapped *next;
-
- /**
- * Previous in DLL
- */
- struct RIL_Address_Wrapped *prev;
-
- /**
- * The address
- */
- struct ATS_Address *address_naked;
-};
-
-
-struct RIL_Peer_Agent
-{
- /**
- * Next agent in solver's linked list
- */
- struct RIL_Peer_Agent *next;
-
- /**
- * Previous agent in solver's linked list
- */
- struct RIL_Peer_Agent *prev;
-
- /**
- * Environment handle
- */
- struct GAS_RIL_Handle *envi;
-
- /**
- * Peer ID
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * Whether the agent is active or not
- */
- int is_active;
-
- /**
- * Number of performed time-steps
- */
- unsigned long long step_count;
-
- /**
- * Experience matrix W
- */
- double **W;
-
- /**
- * Number of rows of W / Number of state-vector features
- */
- unsigned int m;
-
- /**
- * Number of columns of W / Number of actions
- */
- unsigned int n;
-
- /**
- * Last perceived state feature vector
- */
- double *s_old;
-
- /**
- * Last chosen action
- */
- int a_old;
-
- /**
- * Eligibility traces
- */
- double **E;
-
- /**
- * Whether to reset the eligibility traces to 0 after a Q-exploration step
- */
- int eligibility_reset;
-
- /**
- * Address in use
- */
- struct ATS_Address *address_inuse;
-
- /**
- * Head of addresses DLL
- */
- struct RIL_Address_Wrapped *addresses_head;
-
- /**
- * Tail of addresses DLL
- */
- struct RIL_Address_Wrapped *addresses_tail;
-
- /**
- * Inbound bandwidth assigned by the agent
- */
- uint32_t bw_in;
-
- /**
- * Outbound bandwidth assigned by the agent
- */
- uint32_t bw_out;
-
- /**
- * Flag whether a suggestion has to be issued
- */
- int suggestion_issue;
-
- /**
- * The address which has to be issued
- */
- struct ATS_Address *suggestion_address;
-
- /**
- * The agent's last objective value
- */
- double objective_old;
-
- /**
- * NOP bonus
- */
- double nop_bonus;
-};
-
-struct RIL_Scope
-{
- /**
- * ATS network type
- */
- enum GNUNET_NetworkType type;
-
- /**
- * Total available inbound bandwidth
- */
- uint32_t bw_in_available;
-
- /**
- * Bandwidth inbound assigned in network after last step
- */
- uint32_t bw_in_assigned;
-
- /**
- * Bandwidth inbound actually utilized in the network
- */
- uint32_t bw_in_utilized;
-
- /**
- * Total available outbound bandwidth
- */
- uint32_t bw_out_available;
-
- /**
- * Bandwidth outbound assigned in network after last step
- */
- unsigned long long bw_out_assigned;
-
- /**
- * Bandwidth outbound actually utilized in the network
- */
- unsigned long long bw_out_utilized;
-
- /**
- * Number of active agents in scope
- */
- unsigned int active_agent_count;
-
- /**
- * The social welfare achieved in the scope
- */
- double social_welfare;
-};
-
-/**
- * A handle for the reinforcement learning solver
- */
-struct GAS_RIL_Handle
-{
- /**
- * The solver-plugin environment of the solver-plugin API
- */
- struct GNUNET_ATS_PluginEnvironment *env;
-
- /**
- * Number of performed steps
- */
- unsigned long long step_count;
-
- /**
- * Timestamp for the last time-step
- */
- struct GNUNET_TIME_Absolute step_time_last;
-
- /**
- * Task identifier of the next time-step to be executed
- */
- struct GNUNET_SCHEDULER_Task *step_next_task_id;
-
- /**
- * Variable discount factor, dependent on time between steps
- */
- double global_discount_variable;
-
- /**
- * Integrated variable discount factor, dependent on time between steps
- */
- double global_discount_integrated;
-
- /**
- * Lock for bulk operations
- */
- int bulk_lock;
-
- /**
- * Number of changes during a lock
- */
- int bulk_changes;
-
- /**
- * Learning parameters
- */
- struct RIL_Learning_Parameters parameters;
-
- /**
- * Array of networks with global assignment state
- */
- struct RIL_Scope *network_entries;
-
- /**
- * Networks count
- */
- unsigned int networks_count;
-
- /**
- * List of active peer-agents
- */
- struct RIL_Peer_Agent *agents_head;
- struct RIL_Peer_Agent *agents_tail;
-
- /**
- * Shutdown
- */
- int done;
-
- /**
- * Simulate steps, i.e. schedule steps immediately
- */
- unsigned long long simulate;
-};
-
-/*
- * "Private" functions
- * ---------------------------
- */
-
-/**
- * Estimate the current action-value for state s and action a
- *
- * @param agent agent performing the estimation
- * @param state s
- * @param action a
- * @return estimation value
- */
-static double
-agent_q (struct RIL_Peer_Agent *agent,
- const double *state,
- int action)
-{
- unsigned int i;
- double result = 0.0;
-
- for (i = 0; i < agent->m; i++)
- result += state[i] * agent->W[action][i];
-
- /* prevent crashes if learning diverges */
- if (isnan (result))
- return isnan (result) * UINT32_MAX;
- if (isinf (result))
- return isinf (result) * UINT32_MAX;
- return result;
-}
-
-
-/**
- * Get the index of the address in the agent's list.
- *
- * @param agent agent handle
- * @param address address handle
- * @return the index, starting with zero
- */
-static int
-agent_address_get_index (struct RIL_Peer_Agent *agent, struct
- ATS_Address *address)
-{
- int i;
- struct RIL_Address_Wrapped *cur;
-
- i = -1;
- for (cur = agent->addresses_head; NULL != cur; cur = cur->next)
- {
- i++;
- if (cur->address_naked == address)
- return i;
- }
- return i;
-}
-
-
-/**
- * Gets the wrapped address from the agent's list
- *
- * @param agent agent handle
- * @param address address handle
- * @return wrapped address
- */
-static struct RIL_Address_Wrapped *
-agent_address_get_wrapped (struct RIL_Peer_Agent *agent, struct
- ATS_Address *address)
-{
- struct RIL_Address_Wrapped *cur;
-
- for (cur = agent->addresses_head; NULL != cur; cur = cur->next)
- if (cur->address_naked == address)
- return cur;
- return NULL;
-}
-
-
-static int
-agent_action_is_possible (struct RIL_Peer_Agent *agent, int action)
-{
- int address_index;
-
- switch (action)
- {
- case RIL_ACTION_NOTHING:
- return GNUNET_YES;
- break;
-
- case RIL_ACTION_BW_IN_INC:
- case RIL_ACTION_BW_IN_DBL:
- if (agent->bw_in >= RIL_MAX_BW)
- return GNUNET_NO;
- else
- return GNUNET_YES;
- break;
-
- case RIL_ACTION_BW_IN_DEC:
- case RIL_ACTION_BW_IN_HLV:
- if (agent->bw_in <= 0)
- return GNUNET_NO;
- else
- return GNUNET_YES;
- break;
-
- case RIL_ACTION_BW_OUT_INC:
- case RIL_ACTION_BW_OUT_DBL:
- if (agent->bw_out >= RIL_MAX_BW)
- return GNUNET_NO;
- else
- return GNUNET_YES;
- break;
-
- case RIL_ACTION_BW_OUT_DEC:
- case RIL_ACTION_BW_OUT_HLV:
- if (agent->bw_out <= 0)
- return GNUNET_NO;
- else
- return GNUNET_YES;
- break;
-
- default:
- if ((action >= RIL_ACTION_TYPE_NUM) && (action < agent->n)) // switch address action
- {
- address_index = action - RIL_ACTION_TYPE_NUM;
-
- GNUNET_assert (address_index >= 0);
- GNUNET_assert (
- address_index <= agent_address_get_index (agent,
- agent->addresses_tail->
- address_naked));
-
- if ((agent_address_get_index (agent, agent->address_inuse) ==
- address_index) ||
- agent->address_inuse->active)
- return GNUNET_NO;
- else
- return GNUNET_YES;
- break;
- }
- // error - action does not exist
- GNUNET_assert (GNUNET_NO);
- }
-}
-
-
-/**
- * Gets the action, with the maximal estimated Q-value (i.e. the one currently estimated to bring the
- * most reward in the future)
- *
- * @param agent agent performing the calculation
- * @param state the state from which to take the action
- * @return the action promising most future reward
- */
-static int
-agent_get_action_max (struct RIL_Peer_Agent *agent, double *state)
-{
- int i;
- int max_i = RIL_ACTION_INVALID;
- double cur_q;
- double max_q = -DBL_MAX;
-
- for (i = 0; i < agent->n; i++)
- {
- if (agent_action_is_possible (agent, i))
- {
- cur_q = agent_q (agent, state, i);
- if (cur_q > max_q)
- {
- max_q = cur_q;
- max_i = i;
- }
- }
- }
-
- GNUNET_assert (RIL_ACTION_INVALID != max_i);
-
- return max_i;
-}
-
-/**
- * Chooses a random action from the set of possible ones
- *
- * @param agent the agent performing the action
- * @return the action index
- */
-static int
-agent_get_action_random (struct RIL_Peer_Agent *agent)
-{
- int i;
- int is_possible[agent->n];
- int sum = 0;
- int r;
-
- for (i = 0; i < agent->n; i++)
- {
- if (agent_action_is_possible (agent, i))
- {
- is_possible[i] = GNUNET_YES;
- sum++;
- }
- else
- {
- is_possible[i] = GNUNET_NO;
- }
- }
-
- r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, sum);
-
- sum = -1;
- for (i = 0; i < agent->n; i++)
- {
- if (is_possible[i])
- {
- sum++;
- if (sum == r)
- return i;
- }
- }
-
- GNUNET_assert (GNUNET_NO);
- return RIL_ACTION_INVALID;
-}
-
-
-/**
- * Updates the weights (i.e. coefficients) of the weight vector in matrix W for action a
- *
- * @param agent the agent performing the update
- * @param reward the reward received for the last action
- * @param s_next the new state, the last step got the agent into
- * @param a_prime the new
- */
-static void
-agent_update (struct RIL_Peer_Agent *agent, double reward, double *s_next, int
- a_prime)
-{
- int i;
- int k;
- double delta;
- double **theta = agent->W;
-
- delta = agent->envi->global_discount_integrated * reward; // reward
- delta += agent->envi->global_discount_variable * agent_q (agent, s_next,
- a_prime); // discounted future value
- delta -= agent_q (agent, agent->s_old, agent->a_old); // one step
-
-// LOG(GNUNET_ERROR_TYPE_INFO, "update() Step# %llu Q(s,a): %f a: %f r: %f y: %f Q(s+1,a+1) = %f delta: %f\n",
-// agent->step_count,
-// agent_q (agent, agent->s_old, agent->a_old),
-// agent->envi->parameters.alpha,
-// reward,
-// agent->envi->global_discount_variable,
-// agent_q (agent, s_next, a_prime),
-// delta);
-
- for (k = 0; k < agent->n; k++)
- {
- for (i = 0; i < agent->m; i++)
- {
- // LOG(GNUNET_ERROR_TYPE_INFO, "alpha = %f delta = %f e[%d] = %f\n",
- // agent->envi->parameters.alpha,
- // delta,
- // i,
- // agent->e[i]);
- theta[k][i] += agent->envi->parameters.alpha * delta * agent->E[k][i];
- }
- }
-}
-
-
-/**
- * Changes the eligibility trace vector e in various manners:
- * #RIL_E_ACCUMULATE - adds @a feature to each component as in accumulating eligibility traces
- * #RIL_E_REPLACE - resets each component to @a feature as in replacing traces
- * #RIL_E_DECAY - multiplies e with discount factor and lambda as in the update rule
- * #RIL_E_ZERO - sets e to 0 as in Watkin's Q-learning algorithm when exploring and when initializing
- *
- * @param agent the agent handle
- * @param mod the kind of modification
- * @param feature the feature vector
- * @param action the action to take
- */
-static void
-agent_modify_eligibility (struct RIL_Peer_Agent *agent,
- enum RIL_E_Modification mod,
- double *feature,
- int action)
-{
- int i;
- int k;
-
- for (i = 0; i < agent->m; i++)
- {
- switch (mod)
- {
- case RIL_E_ACCUMULATE:
- agent->E[action][i] += feature[i];
- break;
-
- case RIL_E_REPLACE:
- agent->E[action][i] = agent->E[action][i] > feature[i] ?
- agent->E[action][i] : feature[i];
- break;
-
- case RIL_E_DECAY:
- for (k = 0; k < agent->n; k++)
- {
- agent->E[k][i] *= agent->envi->global_discount_variable
- * agent->envi->parameters.lambda;
- }
- break;
-
- case RIL_E_ZERO:
- for (k = 0; k < agent->n; k++)
- {
- agent->E[k][i] = 0;
- }
- break;
- }
- }
-}
-
-/**
- * Informs the environment about the status of the solver
- *
- * @param solver
- * @param op
- * @param stat
- */
-static void
-ril_inform (struct GAS_RIL_Handle *solver,
- enum GAS_Solver_Operation op,
- enum GAS_Solver_Status stat)
-{
- solver->env->info_cb (solver->env->cls,
- op,
- stat,
- GAS_INFO_NONE);
-}
-
-/**
- * Calculates the maximum bandwidth an agent can assign in a network scope
- *
- * @param net
- */
-static unsigned long long
-ril_get_max_bw (struct RIL_Scope *net)
-{
- return GNUNET_MIN (2 * GNUNET_MAX (net->bw_in_available,
- net->bw_out_available),
- GNUNET_ATS_MaxBandwidth);
-}
-
-/**
- * Changes the active assignment suggestion of the handler and invokes the bw_changed callback to
- * notify ATS of its new decision
- *
- * @param solver solver handle
- * @param agent agent handle
- * @param new_address the address which is to be used
- * @param new_bw_in the new amount of inbound bandwidth set for this address
- * @param new_bw_out the new amount of outbound bandwidth set for this address
- * @param silent disables invocation of the bw_changed callback, if #GNUNET_YES
- */
-static void
-envi_set_active_suggestion (struct GAS_RIL_Handle *solver,
- struct RIL_Peer_Agent *agent,
- struct ATS_Address *new_address,
- unsigned long long new_bw_in,
- unsigned long long new_bw_out,
- int silent)
-{
- int notify = GNUNET_NO;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- " set_active_suggestion() for peer '%s'\n",
- GNUNET_i2s (&agent->peer));
-
- // address change
- if (agent->address_inuse != new_address)
- {
- if (NULL != agent->address_inuse)
- {
- agent->address_inuse->active = GNUNET_NO;
- agent->address_inuse->assigned_bw_in = 0;
- agent->address_inuse->assigned_bw_out = 0;
- }
- if (NULL != new_address)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, " set address active: %s\n",
- agent->is_active ? "yes" : "no");
- new_address->active = agent->is_active;
- new_address->assigned_bw_in = agent->bw_in;
- new_address->assigned_bw_out = agent->bw_out;
- }
- notify |= GNUNET_YES;
- }
-
- if (new_address)
- {
- // activity change
- if (new_address->active != agent->is_active)
- {
- new_address->active = agent->is_active;
- notify |= GNUNET_YES;
- }
-
- // bw change
- if (agent->bw_in != new_bw_in)
- {
- agent->bw_in = new_bw_in;
- new_address->assigned_bw_in = new_bw_in;
- notify |= GNUNET_YES;
- }
- if (agent->bw_out != new_bw_out)
- {
- agent->bw_out = new_bw_out;
- new_address->assigned_bw_out = new_bw_out;
- notify |= GNUNET_YES;
- }
- }
-
- if (notify && agent->is_active && (GNUNET_NO == silent))
- {
- if (new_address)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- " envi_set_active_suggestion() notify\n");
- agent->suggestion_issue = GNUNET_YES;
- agent->suggestion_address = new_address;
- }
- else if (agent->address_inuse)
- {
- /* disconnect case, no new address */
- GNUNET_assert (0 == agent->address_inuse->assigned_bw_in);
- GNUNET_assert (0 == agent->address_inuse->assigned_bw_out);
- agent->bw_in = 0;
- agent->bw_out = 0;
-
- agent->suggestion_issue = GNUNET_YES;
- agent->suggestion_address = agent->address_inuse;
- }
- }
- agent->address_inuse = new_address;
-}
-
-
-/**
- * Allocates a state vector and fills it with the features present
- * @param solver the solver handle
- * @param agent the agent handle
- * @return pointer to the state vector
- */
-static double *
-envi_get_state (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent)
-{
- double *state;
- double y[2];
- double x[2];
- double d[2];
- double sigma;
- double f;
- int m;
- int i;
- int k;
- unsigned long long max_bw;
-
- state = GNUNET_malloc (sizeof(double) * agent->m);
-
- max_bw = ril_get_max_bw ((struct
- RIL_Scope *) agent->address_inuse->
- solver_information);
-
- y[0] = (double) agent->bw_out;
- y[1] = (double) agent->bw_in;
-
- m = agent_address_get_index (agent, agent->address_inuse)
- * (solver->parameters.rbf_divisor + 1) * (solver->parameters.rbf_divisor
- + 1);
- for (i = 0; i <= solver->parameters.rbf_divisor; i++)
- {
- for (k = 0; k <= solver->parameters.rbf_divisor; k++)
- {
- x[0] = (double) i * (double) max_bw
- / (double) solver->parameters.rbf_divisor;
- x[1] = (double) k * (double) max_bw
- / (double) solver->parameters.rbf_divisor;
- d[0] = x[0] - y[0];
- d[1] = x[1] - y[1];
- sigma = (((double) max_bw / ((double) solver->parameters.rbf_divisor
- + 1)) * 0.5);
- f = exp (-((d[0] * d[0] + d[1] * d[1]) / (2 * sigma * sigma)));
- state[m++] = f;
- }
- }
-
- return state;
-}
-
-
-/**
- * Returns the utility value of the connection an agent manages
- *
- * @param agent the agent in question
- * @return the utility value
- */
-static double
-agent_get_utility (struct RIL_Peer_Agent *agent)
-{
- const double *preferences;
- double delay_atsi;
- double delay_norm;
- double pref_match;
-
- preferences = agent->envi->env->get_preferences (agent->envi->env->cls,
- &agent->peer);
-
- delay_atsi = agent->address_inuse->norm_delay.norm;
- delay_norm = RIL_UTILITY_DELAY_MAX * exp (-delay_atsi * 0.00001);
-
- pref_match = preferences[GNUNET_ATS_PREFERENCE_LATENCY] * delay_norm;
- pref_match += preferences[GNUNET_ATS_PREFERENCE_BANDWIDTH]
- * sqrt ((double) (agent->bw_in / RIL_MIN_BW)
- * (double) (agent->bw_out / RIL_MIN_BW));
- return pref_match;
-}
-
-/**
- * Calculates the social welfare within a network scope according to what social
- * welfare measure is set in the configuration.
- *
- * @param solver the solver handle
- * @param scope the network scope in question
- * @return the social welfare value
- */
-static double
-ril_network_get_social_welfare (struct GAS_RIL_Handle *solver, struct
- RIL_Scope *scope)
-{
- struct RIL_Peer_Agent *cur;
- double result;
-
- switch (solver->parameters.social_welfare)
- {
- case RIL_WELFARE_EGALITARIAN:
- result = DBL_MAX;
- for (cur = solver->agents_head; NULL != cur; cur = cur->next)
- {
- if (cur->is_active && cur->address_inuse &&
- (cur->address_inuse->solver_information == scope))
- {
- result = GNUNET_MIN (result, agent_get_utility (cur));
- }
- }
- return result;
-
- case RIL_WELFARE_NASH:
- result = 0;
- for (cur = solver->agents_head; NULL != cur; cur = cur->next)
- {
- if (cur->is_active && cur->address_inuse &&
- (cur->address_inuse->solver_information == scope))
- {
- result *= pow (agent_get_utility (cur), 1.0
- / (double) scope->active_agent_count);
- }
- }
- return result;
- }
- GNUNET_assert (GNUNET_NO);
- return 1;
-}
-
-static double
-envi_get_penalty (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent)
-{
- struct RIL_Scope *net;
- unsigned long long over_max;
- unsigned long long over_in = 0;
- unsigned long long over_out = 0;
-
- net = agent->address_inuse->solver_information;
-
- if (net->bw_in_utilized > net->bw_in_available)
- {
- over_in = net->bw_in_utilized - net->bw_in_available;
- if (RIL_ACTION_BW_IN_INC == agent->a_old)
- {
- /* increase quadratically */
- over_in *= over_in;
- }
- }
- if (net->bw_out_utilized > net->bw_out_available)
- {
- over_out = net->bw_out_utilized - net->bw_out_available;
- if (RIL_ACTION_BW_OUT_INC == agent->a_old)
- {
- /* increase quadratically */
- over_out *= over_out;
- }
- }
- over_max = (over_in + over_out) / (RIL_MIN_BW * RIL_MIN_BW);
-
- return -1.0 * (double) over_max;
-}
-
-/**
- * Gets the reward for the last performed step, which is calculated in equal
- * parts from the local (the peer specific) and the global (for all peers
- * identical) reward.
- *
- * @param solver the solver handle
- * @param agent the agent handle
- * @return the reward
- */
-static double
-envi_get_reward (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent)
-{
- struct RIL_Scope *net;
- double objective;
- double delta;
- double steady;
- double penalty;
- double reward;
-
- net = agent->address_inuse->solver_information;
-
- penalty = envi_get_penalty (solver, agent);
- objective = (agent_get_utility (agent) + net->social_welfare) / 2;
- delta = objective - agent->objective_old;
- agent->objective_old = objective;
-
- if ((delta != 0)&&(penalty == 0))
- {
- agent->nop_bonus = delta * RIL_NOP_DECAY;
- }
- else
- {
- agent->nop_bonus *= RIL_NOP_DECAY;
- }
-
- steady = (RIL_ACTION_NOTHING == agent->a_old) ? agent->nop_bonus : 0;
-
- reward = delta + steady;
- return reward + penalty;
-}
-
-/**
- * Doubles the bandwidth for the active address
- *
- * @param solver solver handle
- * @param agent agent handle
- * @param direction_in if GNUNET_YES, change inbound bandwidth, otherwise the outbound bandwidth
- */
-static void
-envi_action_bw_double (struct GAS_RIL_Handle *solver,
- struct RIL_Peer_Agent *agent,
- int direction_in)
-{
- unsigned long long new_bw;
- unsigned long long max_bw;
-
- max_bw = ril_get_max_bw ((struct
- RIL_Scope *) agent->address_inuse->
- solver_information);
-
- if (direction_in)
- {
- new_bw = agent->bw_in * 2;
- if ((new_bw < agent->bw_in) ||(new_bw > max_bw) )
- new_bw = max_bw;
- envi_set_active_suggestion (solver, agent, agent->address_inuse, new_bw,
- agent->bw_out, GNUNET_NO);
- }
- else
- {
- new_bw = agent->bw_out * 2;
- if ((new_bw < agent->bw_out) ||(new_bw > max_bw) )
- new_bw = max_bw;
- envi_set_active_suggestion (solver, agent, agent->address_inuse,
- agent->bw_in,
- new_bw, GNUNET_NO);
- }
-}
-
-/**
- * Cuts the bandwidth for the active address in half. The least amount of bandwidth suggested, is
- * the minimum bandwidth for a peer, in order to not invoke a disconnect.
- *
- * @param solver solver handle
- * @param agent agent handle
- * @param direction_in if GNUNET_YES, change inbound bandwidth, otherwise change the outbound
- * bandwidth
- */
-static void
-envi_action_bw_halven (struct GAS_RIL_Handle *solver,
- struct RIL_Peer_Agent *agent,
- int direction_in)
-{
- unsigned long long new_bw;
-
- if (direction_in)
- {
- new_bw = agent->bw_in / 2;
- if ((new_bw <= 0) ||(new_bw > agent->bw_in) )
- new_bw = 0;
- envi_set_active_suggestion (solver, agent, agent->address_inuse, new_bw,
- agent->bw_out,
- GNUNET_NO);
- }
- else
- {
- new_bw = agent->bw_out / 2;
- if ((new_bw <= 0) ||(new_bw > agent->bw_out) )
- new_bw = 0;
- envi_set_active_suggestion (solver, agent, agent->address_inuse,
- agent->bw_in, new_bw,
- GNUNET_NO);
- }
-}
-
-/**
- * Increases the bandwidth by 5 times the minimum bandwidth for the active address.
- *
- * @param solver solver handle
- * @param agent agent handle
- * @param direction_in if GNUNET_YES, change inbound bandwidth, otherwise change the outbound
- * bandwidth
- */
-static void
-envi_action_bw_inc (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent,
- int direction_in)
-{
- unsigned long long new_bw;
- unsigned long long max_bw;
-
- max_bw = ril_get_max_bw ((struct
- RIL_Scope *) agent->address_inuse->
- solver_information);
-
- if (direction_in)
- {
- new_bw = agent->bw_in + (RIL_INC_DEC_STEP_SIZE * RIL_MIN_BW);
- if ((new_bw < agent->bw_in) ||(new_bw > max_bw) )
- new_bw = max_bw;
- envi_set_active_suggestion (solver, agent, agent->address_inuse, new_bw,
- agent->bw_out, GNUNET_NO);
- }
- else
- {
- new_bw = agent->bw_out + (RIL_INC_DEC_STEP_SIZE * RIL_MIN_BW);
- if ((new_bw < agent->bw_out) ||(new_bw > max_bw) )
- new_bw = max_bw;
- envi_set_active_suggestion (solver, agent, agent->address_inuse,
- agent->bw_in,
- new_bw, GNUNET_NO);
- }
-}
-
-/**
- * Decreases the bandwidth by 5 times the minimum bandwidth for the active address. The least amount
- * of bandwidth suggested, is the minimum bandwidth for a peer, in order to not invoke a disconnect.
- *
- * @param solver solver handle
- * @param agent agent handle
- * @param direction_in if GNUNET_YES, change inbound bandwidth, otherwise change the outbound
- * bandwidth
- */
-static void
-envi_action_bw_dec (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent,
- int direction_in)
-{
- unsigned long long new_bw;
-
- if (direction_in)
- {
- new_bw = agent->bw_in - (RIL_INC_DEC_STEP_SIZE * RIL_MIN_BW);
- if ((new_bw <= 0) ||(new_bw > agent->bw_in) )
- new_bw = 0;
- envi_set_active_suggestion (solver, agent, agent->address_inuse, new_bw,
- agent->bw_out,
- GNUNET_NO);
- }
- else
- {
- new_bw = agent->bw_out - (RIL_INC_DEC_STEP_SIZE * RIL_MIN_BW);
- if ((new_bw <= 0) ||(new_bw > agent->bw_out) )
- new_bw = 0;
- envi_set_active_suggestion (solver, agent, agent->address_inuse,
- agent->bw_in, new_bw,
- GNUNET_NO);
- }
-}
-
-/**
- * Switches to the address given by its index
- *
- * @param solver solver handle
- * @param agent agent handle
- * @param address_index index of the address as it is saved in the agent's list, starting with zero
- */
-static void
-envi_action_address_switch (struct GAS_RIL_Handle *solver,
- struct RIL_Peer_Agent *agent,
- unsigned int address_index)
-{
- struct RIL_Address_Wrapped *cur;
- int i = 0;
-
- // cur = agent_address_get_wrapped(agent, agent->address_inuse);
-
- for (cur = agent->addresses_head; NULL != cur; cur = cur->next)
- {
- if (i == address_index)
- {
- envi_set_active_suggestion (solver, agent, cur->address_naked,
- agent->bw_in, agent->bw_out,
- GNUNET_NO);
- return;
- }
-
- i++;
- }
-
- // no address with address_index exists, in this case this action should not be callable
- GNUNET_assert (GNUNET_NO);
-}
-
-/**
- * Puts the action into effect by calling the according function
- *
- * @param solver the solver handle
- * @param agent the action handle
- * @param action the action to perform by the solver
- */
-static void
-envi_do_action (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent, int
- action)
-{
- int address_index;
-
- switch (action)
- {
- case RIL_ACTION_NOTHING:
- break;
-
- case RIL_ACTION_BW_IN_DBL:
- envi_action_bw_double (solver, agent, GNUNET_YES);
- break;
-
- case RIL_ACTION_BW_IN_HLV:
- envi_action_bw_halven (solver, agent, GNUNET_YES);
- break;
-
- case RIL_ACTION_BW_IN_INC:
- envi_action_bw_inc (solver, agent, GNUNET_YES);
- break;
-
- case RIL_ACTION_BW_IN_DEC:
- envi_action_bw_dec (solver, agent, GNUNET_YES);
- break;
-
- case RIL_ACTION_BW_OUT_DBL:
- envi_action_bw_double (solver, agent, GNUNET_NO);
- break;
-
- case RIL_ACTION_BW_OUT_HLV:
- envi_action_bw_halven (solver, agent, GNUNET_NO);
- break;
-
- case RIL_ACTION_BW_OUT_INC:
- envi_action_bw_inc (solver, agent, GNUNET_NO);
- break;
-
- case RIL_ACTION_BW_OUT_DEC:
- envi_action_bw_dec (solver, agent, GNUNET_NO);
- break;
-
- default:
- if ((action >= RIL_ACTION_TYPE_NUM) && (action < agent->n)) // switch address action
- {
- address_index = action - RIL_ACTION_TYPE_NUM;
-
- GNUNET_assert (address_index >= 0);
- GNUNET_assert (
- address_index <= agent_address_get_index (agent,
- agent->addresses_tail->
- address_naked));
-
- envi_action_address_switch (solver, agent, address_index);
- break;
- }
- // error - action does not exist
- GNUNET_assert (GNUNET_NO);
- }
-}
-
-/**
- * Selects the next action using the e-greedy strategy. I.e. with a probability
- * of (1-e) the action with the maximum expected return will be chosen
- * (=> exploitation) and with probability (e) a random action will be chosen.
- * In case the Q-learning rule is set, the function also resets the eligibility
- * traces in the exploration case (after Watkin's Q-learning).
- *
- * @param agent the agent selecting an action
- * @param state the current state-feature vector
- * @return the action index
- */
-static int
-agent_select_egreedy (struct RIL_Peer_Agent *agent, double *state)
-{
- int action;
- double r = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
- UINT32_MAX)
- / (double) UINT32_MAX;
-
- if (r < agent->envi->parameters.epsilon) // explore
- {
- action = agent_get_action_random (agent);
- if (RIL_ALGO_Q == agent->envi->parameters.algorithm)
- {
- agent->eligibility_reset = GNUNET_YES;
- }
- agent->envi->parameters.epsilon *= agent->envi->parameters.epsilon_decay;
- return action;
- }
- else // exploit
- {
- action = agent_get_action_max (agent, state);
- return action;
- }
-}
-
-/**
- * Selects the next action with a probability corresponding to its value. The
- * probability is calculated using a Boltzmann distribution with a temperature
- * value. The higher the temperature, the more are the action selection
- * probabilities the same. With a temperature of 0, the selection is greedy,
- * i.e. always the action with the highest value is chosen.
- * @param agent
- * @param state
- * @return
- */
-static int
-agent_select_softmax (struct RIL_Peer_Agent *agent, double *state)
-{
- int i;
- int a_max;
- double eqt[agent->n];
- double p[agent->n];
- double sum = 0;
- double r;
-
- a_max = agent_get_action_max (agent, state);
-
- for (i = 0; i < agent->n; i++)
- {
- if (agent_action_is_possible (agent, i))
- {
- eqt[i] = exp (agent_q (agent, state, i)
- / agent->envi->parameters.temperature);
- if (isinf (eqt[i]))
- eqt[i] = isinf (eqt[i]) * UINT32_MAX;
- sum += eqt[i];
- }
- }
- for (i = 0; i < agent->n; i++)
- {
- if (agent_action_is_possible (agent, i))
- {
- p[i] = eqt[i] / sum;
- }
- else
- {
- p[i] = 0;
- }
- }
- r = (double) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
- UINT32_MAX) / (double) UINT32_MAX;
- sum = 0;
- for (i = 0; i < agent->n; i++)
- {
- if (sum + p[i] > r)
- {
- if (i != a_max)
- {
- if (RIL_ALGO_Q == agent->envi->parameters.algorithm)
- agent->eligibility_reset = GNUNET_YES;
- agent->envi->parameters.temperature *=
- agent->envi->parameters.temperature_decay;
- }
- return i;
- }
- sum += p[i];
- }
- GNUNET_assert (GNUNET_NO);
- return RIL_ACTION_INVALID;
-}
-
-/**
- * Select the next action of an agent either according to the e-greedy strategy
- * or the softmax strategy.
- *
- * @param agent the agent in question
- * @param state the current state-feature vector
- * @return the action index
- */
-static int
-agent_select_action (struct RIL_Peer_Agent *agent, double *state)
-{
- if (agent->envi->parameters.select == RIL_SELECT_EGREEDY)
- {
- return agent_select_egreedy (agent, state);
- }
- else
- {
- return agent_select_softmax (agent, state);
- }
-}
-
-/**
- * Performs one step of the Markov Decision Process. Other than in the literature the step starts
- * after having done the last action a_old. It observes the new state s_next and the reward
- * received. Then the coefficient update is done according to the SARSA or Q-learning method. The
- * next action is put into effect.
- *
- * @param agent the agent performing the step
- */
-static void
-agent_step (struct RIL_Peer_Agent *agent)
-{
- int a_next = RIL_ACTION_INVALID;
- int a_max;
- double *s_next;
- double reward;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, " agent_step() Peer '%s', algorithm %s\n",
- GNUNET_i2s (&agent->peer),
- agent->envi->parameters.algorithm ? "Q" : "SARSA");
-
- s_next = envi_get_state (agent->envi, agent);
- reward = envi_get_reward (agent->envi, agent);
-
- if (agent->eligibility_reset)
- {
- agent_modify_eligibility (agent, RIL_E_ZERO, NULL, -1);
- agent->eligibility_reset = GNUNET_NO;
- }
- else
- {
- agent_modify_eligibility (agent, RIL_E_DECAY, NULL, -1);
- }
- if (RIL_ACTION_INVALID != agent->a_old)
- {
- agent_modify_eligibility (agent,
- agent->envi->parameters.eligibility_trace_mode,
- agent->s_old, agent->a_old);
- }
-
- switch (agent->envi->parameters.algorithm)
- {
- case RIL_ALGO_SARSA:
- a_next = agent_select_action (agent, s_next);
- if (RIL_ACTION_INVALID != agent->a_old)
- {
- // updates weights with selected action (on-policy), if not first step
- agent_update (agent, reward, s_next, a_next);
- }
- break;
-
- case RIL_ALGO_Q:
- a_max = agent_get_action_max (agent, s_next);
- if (RIL_ACTION_INVALID != agent->a_old)
- {
- // updates weights with best action, disregarding actually selected action (off-policy), if not first step
- agent_update (agent, reward, s_next, a_max);
- }
- a_next = agent_select_action (agent, s_next);
- break;
- }
-
- GNUNET_assert (RIL_ACTION_INVALID != a_next);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "step() Step# %llu R: %f IN %llu OUT %llu A: %d\n",
- agent->step_count,
- reward,
- agent->bw_in / 1024,
- agent->bw_out / 1024,
- a_next);
-
- envi_do_action (agent->envi, agent, a_next);
-
- GNUNET_free (agent->s_old);
- agent->s_old = s_next;
- agent->a_old = a_next;
-
- agent->step_count += 1;
-}
-
-/**
- * Prototype of the ril_step() procedure
- *
- * @param solver the solver handle
- */
-static void
-ril_step (struct GAS_RIL_Handle *solver);
-
-
-/**
- * Task for the scheduler, which performs one step and lets the solver know that
- * no further step is scheduled.
- *
- * @param cls the solver handle
- */
-static void
-ril_step_scheduler_task (void *cls)
-{
- struct GAS_RIL_Handle *solver = cls;
-
- solver->step_next_task_id = NULL;
- ril_step (solver);
-}
-
-/**
- * Determines how much of the available bandwidth is assigned. If more is
- * assigned than available it returns 1. The function is used to determine the
- * step size of the adaptive stepping.
- *
- * @param solver the solver handle
- * @return the ratio
- */
-static double
-ril_get_used_resource_ratio (struct GAS_RIL_Handle *solver)
-{
- int i;
- struct RIL_Scope net;
- unsigned long long sum_assigned = 0;
- unsigned long long sum_available = 0;
- double ratio;
-
- for (i = 0; i < solver->networks_count; i++)
- {
- net = solver->network_entries[i];
- if (net.bw_in_assigned > 0) // only consider scopes where an address is actually active
- {
- sum_assigned += net.bw_in_utilized;
- sum_assigned += net.bw_out_utilized;
- sum_available += net.bw_in_available;
- sum_available += net.bw_out_available;
- }
- }
- if (sum_available > 0)
- {
- ratio = ((double) sum_assigned) / ((double) sum_available);
- }
- else
- {
- ratio = 0;
- }
-
- return ratio > 1 ? 1 : ratio; // overutilization is possible, cap at 1
-}
-
-/**
- * Lookup network struct by type
- *
- * @param s the solver handle
- * @param type the network type
- * @return the network struct
- */
-static struct RIL_Scope *
-ril_get_network (struct GAS_RIL_Handle *s, uint32_t type)
-{
- int i;
-
- for (i = 0; i < s->networks_count; i++)
- {
- if (s->network_entries[i].type == type)
- {
- return &s->network_entries[i];
- }
- }
- return NULL;
-}
-
-/**
- * Determines whether more connections are allocated in a network scope, than
- * they would theoretically fit. This is used as a heuristic to determine,
- * whether a new connection can be allocated or not.
- *
- * @param solver the solver handle
- * @param network the network scope in question
- * @return GNUNET_YES if there are theoretically enough resources left
- */
-static int
-ril_network_is_not_full (struct GAS_RIL_Handle *solver, enum GNUNET_NetworkType
- network)
-{
- struct RIL_Scope *net;
- struct RIL_Peer_Agent *agent;
- unsigned long long address_count = 0;
-
- for (agent = solver->agents_head; NULL != agent; agent = agent->next)
- {
- if (agent->address_inuse && agent->is_active)
- {
- net = agent->address_inuse->solver_information;
- if (net->type == network)
- {
- address_count++;
- }
- }
- }
-
- net = ril_get_network (solver, network);
- return (net->bw_in_available > RIL_MIN_BW * address_count) &&
- (net->bw_out_available > RIL_MIN_BW * address_count);
-}
-
-/**
- * Unblocks an agent for which a connection request is there, that could not
- * be satisfied. Iterates over the addresses of the agent, if one of its
- * addresses can now be allocated in its scope the agent is unblocked,
- * otherwise it remains unchanged.
- *
- * @param solver the solver handle
- * @param agent the agent in question
- * @param silent
- */
-static void
-ril_try_unblock_agent (struct GAS_RIL_Handle *solver, struct
- RIL_Peer_Agent *agent, int silent)
-{
- struct RIL_Address_Wrapped *addr_wrap;
- struct RIL_Scope *net;
- unsigned long long start_in;
- unsigned long long start_out;
-
- for (addr_wrap = agent->addresses_head; NULL != addr_wrap; addr_wrap =
- addr_wrap->next)
- {
- net = addr_wrap->address_naked->solver_information;
- if (ril_network_is_not_full (solver, net->type))
- {
- if (NULL == agent->address_inuse)
- {
- start_in = net->bw_in_available < net->bw_in_utilized ?
- (net->bw_in_available - net->bw_in_utilized) / 2 :
- RIL_MIN_BW;
- start_out = net->bw_out_available < net->bw_out_utilized ?
- (net->bw_out_available - net->bw_out_utilized) / 2 :
- RIL_MIN_BW;
- envi_set_active_suggestion (solver, agent, addr_wrap->address_naked,
- start_in, start_out, silent);
- }
- return;
- }
- }
- agent->address_inuse = NULL;
-}
-
-/**
- * Determines how much the reward needs to be discounted depending on the amount
- * of time, which has passed since the last time-step.
- *
- * @param solver the solver handle
- */
-static void
-ril_calculate_discount (struct GAS_RIL_Handle *solver)
-{
- struct GNUNET_TIME_Absolute time_now;
- struct GNUNET_TIME_Relative time_delta;
- double tau;
-
- // MDP case only for debugging purposes
- if (solver->simulate)
- {
- solver->global_discount_variable = solver->parameters.gamma;
- solver->global_discount_integrated = 1;
- return;
- }
-
- // semi-MDP case
-
- // calculate tau, i.e. how many real valued time units have passed, one time unit is one minimum time step
- time_now = GNUNET_TIME_absolute_get ();
- time_delta = GNUNET_TIME_absolute_get_difference (solver->step_time_last,
- time_now);
- solver->step_time_last = time_now;
- tau = (double) time_delta.rel_value_us
- / (double) solver->parameters.step_time_min.rel_value_us;
-
- // calculate reward discounts (once per step for all agents)
- solver->global_discount_variable = pow (M_E, ((-1.0)
- * ((double) solver->parameters.
- beta) * tau));
- solver->global_discount_integrated = (1.0 - solver->global_discount_variable)
- / (double) solver->parameters.beta;
-}
-
-/**
- * Count the number of active agents/connections in a network scope
- *
- * @param solver the solver handle
- * @param scope the network scope in question
- * @return the number of allocated connections
- */
-static int
-ril_network_count_active_agents (struct GAS_RIL_Handle *solver, struct
- RIL_Scope *scope)
-{
- int c = 0;
- struct RIL_Peer_Agent *cur_agent;
-
- for (cur_agent = solver->agents_head; NULL != cur_agent; cur_agent =
- cur_agent->next)
- {
- if (cur_agent->is_active && cur_agent->address_inuse &&
- (cur_agent->address_inuse->solver_information == scope))
- {
- c++;
- }
- }
- return c;
-}
-
-/**
- * Calculates how much bandwidth is assigned in sum in a network scope, either
- * in the inbound or in the outbound direction.
- *
- * @param solver the solver handle
- * @param type the type of the network scope in question
- * @param direction_in GNUNET_YES if the inbound direction should be summed up,
- * otherwise the outbound direction will be summed up
- * @return the sum of the assigned bandwidths
- */
-static unsigned long long
-ril_network_get_assigned (struct GAS_RIL_Handle *solver, enum GNUNET_NetworkType
- type, int direction_in)
-{
- struct RIL_Peer_Agent *cur;
- struct RIL_Scope *net;
- unsigned long long sum = 0;
-
- for (cur = solver->agents_head; NULL != cur; cur = cur->next)
- {
- if (cur->is_active && cur->address_inuse)
- {
- net = cur->address_inuse->solver_information;
- if (net->type == type)
- {
- if (direction_in)
- sum += cur->bw_in;
- else
- sum += cur->bw_out;
- }
- }
- }
-
- return sum;
-}
-
-/**
- * Calculates how much bandwidth is actually utilized in sum in a network scope,
- * either in the inbound or in the outbound direction.
- *
- * @param solver the solver handle
- * @param type the type of the network scope in question
- * @param direction_in GNUNET_YES if the inbound direction should be summed up,
- * otherwise the outbound direction will be summed up
- * @return the sum of the utilized bandwidths (in bytes/second)
- */
-static unsigned long long
-ril_network_get_utilized (struct GAS_RIL_Handle *solver, enum GNUNET_NetworkType
- type, int direction_in)
-{
- struct RIL_Peer_Agent *cur;
- struct RIL_Scope *net;
- unsigned long long sum = 0;
-
- for (cur = solver->agents_head; NULL != cur; cur = cur->next)
- {
- if (cur->is_active && cur->address_inuse)
- {
- net = cur->address_inuse->solver_information;
- if (net->type == type)
- {
- if (direction_in)
- sum += cur->address_inuse->norm_utilization_in.norm;
- else
- sum += cur->address_inuse->norm_utilization_out.norm;
- }
- }
- }
-
- return sum;
-}
-
-/**
- * Retrieves the state of the network scope, so that its attributes are up-to-
- * date.
- *
- * @param solver the solver handle
- */
-static void
-ril_networks_update_state (struct GAS_RIL_Handle *solver)
-{
- int c;
- struct RIL_Scope *net;
-
- for (c = 0; c < solver->networks_count; c++)
- {
- net = &solver->network_entries[c];
- net->bw_in_assigned = ril_network_get_assigned (solver, net->type,
- GNUNET_YES);
- net->bw_in_utilized = ril_network_get_utilized (solver, net->type,
- GNUNET_YES);
- net->bw_out_assigned = ril_network_get_assigned (solver, net->type,
- GNUNET_NO);
- net->bw_out_utilized = ril_network_get_utilized (solver, net->type,
- GNUNET_NO);
- net->active_agent_count = ril_network_count_active_agents (solver, net);
- net->social_welfare = ril_network_get_social_welfare (solver, net);
- }
-}
-
-/**
- * Schedules the next global step in an adaptive way. The more resources are
- * left, the earlier the next step is scheduled. This serves the reactivity of
- * the solver to changed inputs.
- *
- * @param solver the solver handle
- */
-static void
-ril_step_schedule_next (struct GAS_RIL_Handle *solver)
-{
- double used_ratio;
- double factor;
- double y;
- double offset;
- struct GNUNET_TIME_Relative time_next;
-
- used_ratio = ril_get_used_resource_ratio (solver);
-
- GNUNET_assert (
- solver->parameters.step_time_min.rel_value_us
- <= solver->parameters.step_time_max.rel_value_us);
-
- factor = (double) GNUNET_TIME_relative_subtract (
- solver->parameters.step_time_max,
- solver->parameters.
- step_time_min).rel_value_us;
- offset = (double) solver->parameters.step_time_min.rel_value_us;
- y = factor * pow (used_ratio, RIL_INTERVAL_EXPONENT) + offset;
-
- GNUNET_assert (y <= (double) solver->parameters.step_time_max.rel_value_us);
- GNUNET_assert (y >= (double) solver->parameters.step_time_min.rel_value_us);
-
- time_next = GNUNET_TIME_relative_saturating_multiply (
- GNUNET_TIME_UNIT_MICROSECONDS, (unsigned long long) y);
-
-// LOG (GNUNET_ERROR_TYPE_INFO, "ratio: %f, factor: %f, offset: %f, y: %f\n",
-// used_ratio,
-// factor,
-// offset,
-// y);
-
- if (solver->simulate)
- {
- time_next = GNUNET_TIME_UNIT_ZERO;
- }
-
- if ((NULL == solver->step_next_task_id) && (GNUNET_NO == solver->done))
- {
- solver->step_next_task_id = GNUNET_SCHEDULER_add_delayed (time_next,
- &
- ril_step_scheduler_task,
- solver);
- }
-}
-
-/**
- * Triggers one step per agent
- *
- * @param solver
- */
-static void
-ril_step (struct GAS_RIL_Handle *solver)
-{
- struct RIL_Peer_Agent *cur;
-
- if (GNUNET_YES == solver->bulk_lock)
- {
- solver->bulk_changes++;
- return;
- }
-
- ril_inform (solver, GAS_OP_SOLVE_START, GAS_STAT_SUCCESS);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, " RIL step number %d\n", solver->step_count);
-
- if (0 == solver->step_count)
- {
- solver->step_time_last = GNUNET_TIME_absolute_get ();
- }
-
- ril_calculate_discount (solver);
- ril_networks_update_state (solver);
-
- // trigger one step per active, unblocked agent
- for (cur = solver->agents_head; NULL != cur; cur = cur->next)
- {
- if (cur->is_active)
- {
- if (NULL == cur->address_inuse)
- {
- ril_try_unblock_agent (solver, cur, GNUNET_NO);
- }
- if (cur->address_inuse)
- {
- agent_step (cur);
- }
- }
- }
-
- ril_networks_update_state (solver);
-
- solver->step_count++;
- ril_step_schedule_next (solver);
-
- ril_inform (solver, GAS_OP_SOLVE_STOP, GAS_STAT_SUCCESS);
-
- ril_inform (solver, GAS_OP_SOLVE_UPDATE_NOTIFICATION_START, GAS_STAT_SUCCESS);
- for (cur = solver->agents_head; NULL != cur; cur = cur->next)
- {
- if (cur->suggestion_issue)
- {
- solver->env->bandwidth_changed_cb (solver->env->cls,
- cur->suggestion_address);
- cur->suggestion_issue = GNUNET_NO;
- }
- }
- ril_inform (solver, GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP, GAS_STAT_SUCCESS);
-}
-
-/**
- * Initializes the matrix W of parameter vectors theta with small random numbers.
- *
- * @param agent The respective agent
- */
-static void
-agent_w_init (struct RIL_Peer_Agent *agent)
-{
- int i;
- int k;
-
- for (i = 0; i < agent->n; i++)
- {
- for (k = 0; k < agent->m; k++)
- {
- agent->W[i][k] = agent->envi->parameters.alpha * (1.0 - 2.0
- * ((double)
- GNUNET_CRYPTO_random_u32 (
- GNUNET_CRYPTO_QUALITY_WEAK,
- UINT32_MAX)
- / (double) UINT32_MAX));
- }
- }
-}
-
-/**
- * Initialize an agent without addresses and its knowledge base
- *
- * @param s ril solver
- * @param peer the one in question
- * @return handle to the new agent
- */
-static struct RIL_Peer_Agent *
-agent_init (void *s, const struct GNUNET_PeerIdentity *peer)
-{
- int i;
- struct GAS_RIL_Handle *solver = s;
- struct RIL_Peer_Agent *agent = GNUNET_new (struct RIL_Peer_Agent);
-
- agent->envi = solver;
- agent->peer = *peer;
- agent->step_count = 0;
- agent->is_active = GNUNET_NO;
- agent->bw_in = RIL_MIN_BW;
- agent->bw_out = RIL_MIN_BW;
- agent->suggestion_issue = GNUNET_NO;
- agent->n = RIL_ACTION_TYPE_NUM;
- agent->m = 0;
- agent->W = (double **) GNUNET_malloc (sizeof(double *) * agent->n);
- agent->E = (double **) GNUNET_malloc (sizeof(double *) * agent->n);
- for (i = 0; i < agent->n; i++)
- {
- agent->W[i] = (double *) GNUNET_malloc (sizeof(double) * agent->m);
- agent->E[i] = (double *) GNUNET_malloc (sizeof(double) * agent->m);
- }
- agent_w_init (agent);
- agent->eligibility_reset = GNUNET_NO;
- agent->a_old = RIL_ACTION_INVALID;
- agent->s_old = GNUNET_malloc (sizeof(double) * agent->m);
- agent->address_inuse = NULL;
- agent->objective_old = 0;
- agent->nop_bonus = 0;
-
- return agent;
-}
-
-/**
- * Deallocate agent
- *
- * @param solver the solver handle
- * @param agent the agent to retire
- */
-static void
-agent_die (struct GAS_RIL_Handle *solver, struct RIL_Peer_Agent *agent)
-{
- int i;
-
- for (i = 0; i < agent->n; i++)
- {
- GNUNET_free_non_null (agent->W[i]);
- GNUNET_free_non_null (agent->E[i]);
- }
- GNUNET_free_non_null (agent->W);
- GNUNET_free_non_null (agent->E);
- GNUNET_free_non_null (agent->s_old);
- GNUNET_free (agent);
-}
-
-/**
- * Returns the agent for a peer
- *
- * @param solver the solver handle
- * @param peer the identity of the peer
- * @param create whether or not to create an agent, if none is allocated yet
- * @return the agent
- */
-static struct RIL_Peer_Agent *
-ril_get_agent (struct GAS_RIL_Handle *solver, const struct
- GNUNET_PeerIdentity *peer, int create)
-{
- struct RIL_Peer_Agent *cur;
-
- for (cur = solver->agents_head; NULL != cur; cur = cur->next)
- {
- if (0 == GNUNET_memcmp (peer, &cur->peer))
- {
- return cur;
- }
- }
-
- if (create)
- {
- cur = agent_init (solver, peer);
- GNUNET_CONTAINER_DLL_insert_tail (solver->agents_head, solver->agents_tail,
- cur);
- return cur;
- }
- return NULL;
-}
-
-/**
- * Determine whether at least the minimum bandwidth is set for the network. Otherwise the network is
- * considered inactive and not used. Addresses in an inactive network are ignored.
- *
- * @param solver solver handle
- * @param network the network type
- * @return whether or not the network is considered active
- */
-static int
-ril_network_is_active (struct GAS_RIL_Handle *solver, enum GNUNET_NetworkType
- network)
-{
- struct RIL_Scope *net;
-
- net = ril_get_network (solver, network);
- return net->bw_out_available >= RIL_MIN_BW;
-}
-
-/**
- * Cuts a slice out of a vector of elements. This is used to decrease the size of the matrix storing
- * the reward function approximation. It copies the memory, which is not cut, to the new vector,
- * frees the memory of the old vector, and redirects the pointer to the new one.
- *
- * @param old pointer to the pointer to the first element of the vector
- * @param element_size byte size of the vector elements
- * @param hole_start the first element to cut out
- * @param hole_length the number of elements to cut out
- * @param old_length the length of the old vector
- */
-static void
-ril_cut_from_vector (void **old,
- size_t element_size,
- unsigned int hole_start,
- unsigned int hole_length,
- unsigned int old_length)
-{
- char *tmpptr;
- char *oldptr = (char *) *old;
- size_t size;
- unsigned int bytes_before;
- unsigned int bytes_hole;
- unsigned int bytes_after;
-
- GNUNET_assert (old_length >= hole_length);
- GNUNET_assert (old_length >= (hole_start + hole_length));
-
- size = element_size * (old_length - hole_length);
-
- bytes_before = element_size * hole_start;
- bytes_hole = element_size * hole_length;
- bytes_after = element_size * (old_length - hole_start - hole_length);
-
- if (0 == size)
- {
- tmpptr = NULL;
- }
- else
- {
- tmpptr = GNUNET_malloc (size);
- GNUNET_memcpy (tmpptr, oldptr, bytes_before);
- GNUNET_memcpy (tmpptr + bytes_before, oldptr + (bytes_before + bytes_hole),
- bytes_after);
- }
- if (NULL != *old)
- {
- GNUNET_free (*old);
- }
- *old = (void *) tmpptr;
-}
-
-/*
- * Solver API functions
- * ---------------------------
- */
-
-/**
- * Change relative preference for quality in solver
- *
- * @param solver the solver handle
- * @param peer the peer to change the preference for
- * @param kind the kind to change the preference
- * @param pref_rel the normalized preference value for this kind over all clients
- */
-static void
-GAS_ril_address_change_preference (void *solver,
- const struct GNUNET_PeerIdentity *peer,
- enum GNUNET_ATS_PreferenceKind kind,
- double pref_rel)
-{
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_address_change_preference() Preference '%s' for peer '%s' changed to %.2f \n",
- GNUNET_ATS_print_preference_type (kind), GNUNET_i2s (peer), pref_rel);
-
- struct GAS_RIL_Handle *s = solver;
-
- s->parameters.temperature = s->parameters.temperature_init;
- s->parameters.epsilon = s->parameters.epsilon_init;
- ril_step (s);
-}
-
-
-/**
- * Add a new address for a peer to the solver
- *
- * The address is already contained in the addresses hashmap!
- *
- * @param solver the solver Handle
- * @param address the address to add
- * @param network network type of this address
- */
-static void
-GAS_ril_address_add (void *solver,
- struct ATS_Address *address,
- uint32_t network)
-{
- struct GAS_RIL_Handle *s = solver;
- struct RIL_Peer_Agent *agent;
- struct RIL_Address_Wrapped *address_wrapped;
- struct RIL_Scope *net;
- unsigned int m_new;
- unsigned int m_old;
- unsigned int n_new;
- unsigned int n_old;
- int i;
- unsigned int zero;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_address_add()\n");
-
- net = ril_get_network (s, network);
- address->solver_information = net;
-
- if (! ril_network_is_active (s, network))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_address_add() Did not add %s address %s for peer '%s', network does not have enough bandwidth\n",
- address->plugin, address->addr, GNUNET_i2s (&address->peer));
- return;
- }
-
- s->parameters.temperature = s->parameters.temperature_init;
- s->parameters.epsilon = s->parameters.epsilon_init;
-
- agent = ril_get_agent (s, &address->peer, GNUNET_YES);
-
- // add address
- address_wrapped = GNUNET_new (struct RIL_Address_Wrapped);
- address_wrapped->address_naked = address;
- GNUNET_CONTAINER_DLL_insert_tail (agent->addresses_head,
- agent->addresses_tail, address_wrapped);
-
- // increase size of W
- m_new = agent->m + ((s->parameters.rbf_divisor + 1)
- * (s->parameters.rbf_divisor + 1));
- m_old = agent->m;
- n_new = agent->n + 1;
- n_old = agent->n;
-
- GNUNET_array_grow (agent->W, agent->n, n_new);
- agent->n = n_old;
- GNUNET_array_grow (agent->E, agent->n, n_new);
- for (i = 0; i < n_new; i++)
- {
- if (i < n_old)
- {
- agent->m = m_old;
- GNUNET_array_grow (agent->W[i], agent->m, m_new);
- agent->m = m_old;
- GNUNET_array_grow (agent->E[i], agent->m, m_new);
- }
- else
- {
- zero = 0;
- GNUNET_array_grow (agent->W[i], zero, m_new);
- zero = 0;
- GNUNET_array_grow (agent->E[i], zero, m_new);
- }
- }
-
- // increase size of old state vector
- agent->m = m_old;
- GNUNET_array_grow (agent->s_old, agent->m, m_new);
-
- ril_try_unblock_agent (s, agent, GNUNET_NO);
-
- ril_step (s);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_address_add() Added %s %s address %s for peer '%s'\n",
- address->active ? "active" : "inactive", address->plugin, address->addr,
- GNUNET_i2s (&address->peer));
-}
-
-/**
- * Delete an address in the solver
- *
- * The address is not contained in the address hashmap anymore!
- *
- * @param solver the solver handle
- * @param address the address to remove
- */
-static void
-GAS_ril_address_delete (void *solver,
- struct ATS_Address *address)
-{
- struct GAS_RIL_Handle *s = solver;
- struct RIL_Peer_Agent *agent;
- struct RIL_Address_Wrapped *address_wrapped;
- int address_index;
- unsigned int m_new;
- unsigned int n_new;
- int i;
- struct RIL_Scope *net;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_address_delete() Delete %s %s address %s for peer '%s'\n",
- address->active ? "active" : "inactive",
- address->plugin,
- address->addr,
- GNUNET_i2s (&address->peer));
-
- agent = ril_get_agent (s, &address->peer, GNUNET_NO);
- if (NULL == agent)
- {
- net = address->solver_information;
- GNUNET_assert (! ril_network_is_active (s, net->type));
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "No agent allocated for peer yet, since address was in inactive network\n");
- return;
- }
-
- s->parameters.temperature = s->parameters.temperature_init;
- s->parameters.epsilon = s->parameters.epsilon_init;
-
- address_index = agent_address_get_index (agent, address);
- address_wrapped = agent_address_get_wrapped (agent, address);
-
- if (NULL == address_wrapped)
- {
- net = address->solver_information;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Address not considered by agent, address was in inactive network\n");
- return;
- }
- GNUNET_CONTAINER_DLL_remove (agent->addresses_head,
- agent->addresses_tail,
- address_wrapped);
- GNUNET_free (address_wrapped);
-
- // decrease W
- m_new = agent->m - ((s->parameters.rbf_divisor + 1)
- * (s->parameters.rbf_divisor + 1));
- n_new = agent->n - 1;
-
- for (i = 0; i < agent->n; i++)
- {
- ril_cut_from_vector ((void **) &agent->W[i], sizeof(double),
- address_index * ((s->parameters.rbf_divisor + 1)
- * (s->parameters.rbf_divisor + 1)),
- ((s->parameters.rbf_divisor + 1)
- * (s->parameters.rbf_divisor + 1)), agent->m);
- ril_cut_from_vector ((void **) &agent->E[i], sizeof(double),
- address_index * ((s->parameters.rbf_divisor + 1)
- * (s->parameters.rbf_divisor + 1)),
- ((s->parameters.rbf_divisor + 1)
- * (s->parameters.rbf_divisor + 1)), agent->m);
- }
- GNUNET_free_non_null (agent->W[RIL_ACTION_TYPE_NUM + address_index]);
- GNUNET_free_non_null (agent->E[RIL_ACTION_TYPE_NUM + address_index]);
- ril_cut_from_vector ((void **) &agent->W, sizeof(double *),
- RIL_ACTION_TYPE_NUM + address_index,
- 1, agent->n);
- ril_cut_from_vector ((void **) &agent->E, sizeof(double *),
- RIL_ACTION_TYPE_NUM + address_index,
- 1, agent->n);
- // correct last action
- if (agent->a_old > (RIL_ACTION_TYPE_NUM + address_index))
- {
- agent->a_old -= 1;
- }
- else if (agent->a_old == (RIL_ACTION_TYPE_NUM + address_index))
- {
- agent->a_old = RIL_ACTION_INVALID;
- }
- // decrease old state vector
- ril_cut_from_vector ((void **) &agent->s_old, sizeof(double),
- address_index * ((s->parameters.rbf_divisor + 1)
- * (s->parameters.rbf_divisor + 1)),
- ((s->parameters.rbf_divisor + 1)
- * (s->parameters.rbf_divisor + 1)), agent->m);
- agent->m = m_new;
- agent->n = n_new;
-
- if (agent->address_inuse == address)
- {
- if (NULL != agent->addresses_head) // if peer has an address left, use it
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Active address died, suggesting alternative!\n");
- envi_set_active_suggestion (s,
- agent,
- agent->addresses_head->address_naked,
- agent->bw_in,
- agent->bw_out,
- GNUNET_YES);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Active address died, suggesting disconnect!\n");
- envi_set_active_suggestion (s, agent, NULL, 0, 0, GNUNET_NO);
- }
- }
- ril_step (solver);
- if (agent->suggestion_address == address)
- {
- agent->suggestion_issue = GNUNET_NO;
- agent->suggestion_address = NULL;
- }
- GNUNET_assert (agent->address_inuse != address);
-}
-
-
-/**
- * Update the properties of an address in the solver
- *
- * @param solver solver handle
- * @param address the address
- */
-static void
-GAS_ril_address_property_changed (void *solver,
- struct ATS_Address *address)
-{
- struct GAS_RIL_Handle *s = solver;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Properties for peer '%s' address changed\n",
- GNUNET_i2s (&address->peer));
- s->parameters.temperature = s->parameters.temperature_init;
- s->parameters.epsilon = s->parameters.epsilon_init;
- ril_step (s);
-}
-
-
-/**
- * Give feedback about the current assignment
- *
- * @param solver the solver handle
- * @param application the application
- * @param peer the peer to change the preference for
- * @param scope the time interval for this feedback: [now - scope .. now]
- * @param kind the kind to change the preference
- * @param score the score
- */
-static void
-GAS_ril_address_preference_feedback (void *solver,
- struct GNUNET_SERVICE_Client *application,
- const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_TIME_Relative scope,
- enum GNUNET_ATS_PreferenceKind kind,
- double score)
-{
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_address_preference_feedback() Peer '%s' got a feedback of %+.3f from application %s for "
- "preference %s for %d seconds\n",
- GNUNET_i2s (peer),
- "UNKNOWN",
- GNUNET_ATS_print_preference_type (kind),
- scope.rel_value_us / 1000000);
-}
-
-
-/**
- * Start a bulk operation
- *
- * @param solver the solver
- */
-static void
-GAS_ril_bulk_start (void *solver)
-{
- struct GAS_RIL_Handle *s = solver;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_bulk_start() lock: %d\n", s->bulk_lock + 1);
-
- s->bulk_lock++;
-}
-
-
-/**
- * Bulk operation done
- *
- * @param solver the solver handle
- */
-static void
-GAS_ril_bulk_stop (void *solver)
-{
- struct GAS_RIL_Handle *s = solver;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_bulk_stop() lock: %d\n",
- s->bulk_lock - 1);
-
- if (s->bulk_lock < 1)
- {
- GNUNET_break (0);
- return;
- }
- s->bulk_lock--;
-
- if (0 < s->bulk_changes)
- {
- ril_step (solver);
- s->bulk_changes = 0;
- }
-}
-
-
-/**
- * Tell solver to notify ATS if the address to use changes for a specific
- * peer using the bandwidth changed callback
- *
- * The solver must only notify about changes for peers with pending address
- * requests!
- *
- * @param solver the solver handle
- * @param peer the identity of the peer
- */
-static void
-GAS_ril_get_preferred_address (void *solver,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct GAS_RIL_Handle *s = solver;
- struct RIL_Peer_Agent *agent;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "API_get_preferred_address()\n");
-
- agent = ril_get_agent (s, peer, GNUNET_YES);
-
- agent->is_active = GNUNET_YES;
- envi_set_active_suggestion (solver, agent, agent->address_inuse, agent->bw_in,
- agent->bw_out, GNUNET_YES);
-
- ril_try_unblock_agent (solver, agent, GNUNET_YES);
-
- if (agent->address_inuse)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_get_preferred_address() Activated agent for peer '%s' with %s address %s\n",
- GNUNET_i2s (peer), agent->address_inuse->plugin,
- agent->address_inuse->addr);
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_get_preferred_address() Activated agent for peer '%s', but no address available\n",
- GNUNET_i2s (peer));
- s->parameters.temperature = s->parameters.temperature_init;
- s->parameters.epsilon = s->parameters.epsilon_init;
- }
- if (NULL != agent->address_inuse)
- s->env->bandwidth_changed_cb (s->env->cls,
- agent->address_inuse);
-}
-
-
-/**
- * Tell solver stop notifying ATS about changes for this peers
- *
- * The solver must only notify about changes for peers with pending address
- * requests!
- *
- * @param solver the solver handle
- * @param peer the peer
- */
-static void
-GAS_ril_stop_get_preferred_address (void *solver,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct GAS_RIL_Handle *s = solver;
- struct RIL_Peer_Agent *agent;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_stop_get_preferred_address()");
-
- agent = ril_get_agent (s, peer, GNUNET_NO);
-
- if (NULL == agent)
- {
- GNUNET_break (0);
- return;
- }
- if (GNUNET_NO == agent->is_active)
- {
- GNUNET_break (0);
- return;
- }
-
- s->parameters.temperature = s->parameters.temperature_init;
- s->parameters.epsilon = s->parameters.epsilon_init;
-
- agent->is_active = GNUNET_NO;
-
- envi_set_active_suggestion (s, agent, agent->address_inuse, agent->bw_in,
- agent->bw_out,
- GNUNET_YES);
-
- ril_step (s);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_stop_get_preferred_address() Paused agent for peer '%s'\n",
- GNUNET_i2s (peer));
-}
-
-
-/**
- * Entry point for the plugin
- *
- * @param cls pointer to the 'struct GNUNET_ATS_PluginEnvironment'
- */
-void *
-libgnunet_plugin_ats_ril_init (void *cls)
-{
- static struct GNUNET_ATS_SolverFunctions sf;
- struct GNUNET_ATS_PluginEnvironment *env = cls;
- struct GAS_RIL_Handle *solver = GNUNET_new (struct GAS_RIL_Handle);
- struct RIL_Scope *cur;
- int c;
- char *string;
- float f_tmp;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "API_init() Initializing RIL solver\n");
-
- GNUNET_assert (NULL != env);
- GNUNET_assert (NULL != env->cfg);
- GNUNET_assert (NULL != env->stats);
- GNUNET_assert (NULL != env->bandwidth_changed_cb);
- GNUNET_assert (NULL != env->get_preferences);
-
- if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (env->cfg, "ats",
- "RIL_RBF_DIVISOR",
- &solver->parameters.
- rbf_divisor))
- {
- solver->parameters.rbf_divisor = RIL_DEFAULT_RBF_DIVISOR;
- }
-
- if (GNUNET_OK
- != GNUNET_CONFIGURATION_get_value_time (env->cfg, "ats",
- "RIL_STEP_TIME_MIN",
- &solver->parameters.step_time_min))
- {
- solver->parameters.step_time_min = RIL_DEFAULT_STEP_TIME_MIN;
- }
-
- if (GNUNET_OK
- != GNUNET_CONFIGURATION_get_value_time (env->cfg, "ats",
- "RIL_STEP_TIME_MAX",
- &solver->parameters.step_time_max))
- {
- solver->parameters.step_time_max = RIL_DEFAULT_STEP_TIME_MAX;
- }
-
- if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (env->cfg, "ats",
- "RIL_ALGORITHM",
- &string))
- {
- GNUNET_STRINGS_utf8_toupper (string, string);
- if (0 == strcmp (string, "SARSA"))
- {
- solver->parameters.algorithm = RIL_ALGO_SARSA;
- }
- if (0 == strcmp (string, "Q-LEARNING"))
- {
- solver->parameters.algorithm = RIL_ALGO_Q;
- }
-
- GNUNET_free (string);
- }
- else
- {
- solver->parameters.algorithm = RIL_DEFAULT_ALGORITHM;
- }
-
- if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (env->cfg, "ats",
- "RIL_SELECT",
- &string))
- {
- solver->parameters.select = ! strcmp (string, "EGREEDY") ?
- RIL_SELECT_EGREEDY : RIL_SELECT_SOFTMAX;
- GNUNET_free (string);
- }
- else
- {
- solver->parameters.select = RIL_DEFAULT_SELECT;
- }
-
-
- solver->parameters.beta = RIL_DEFAULT_DISCOUNT_BETA;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "RIL_DISCOUNT_BETA",
- &f_tmp))
- {
- if (f_tmp < 0.0)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "RIL_DISCOUNT_BETA", f_tmp);
- }
- else
- {
- solver->parameters.beta = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s of %.3f\n",
- "RIL_DISCOUNT_BETA", f_tmp);
- }
- }
-
- solver->parameters.gamma = RIL_DEFAULT_DISCOUNT_GAMMA;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "RIL_DISCOUNT_GAMMA",
- &f_tmp))
- {
- if ((f_tmp < 0.0) || (f_tmp > 1.0))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "RIL_DISCOUNT_GAMMA", f_tmp);
- }
- else
- {
- solver->parameters.gamma = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s of %.3f\n",
- "RIL_DISCOUNT_GAMMA", f_tmp);
- }
- }
-
- solver->parameters.alpha = RIL_DEFAULT_GRADIENT_STEP_SIZE;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "RIL_GRADIENT_STEP_SIZE",
- &f_tmp))
- {
- if ((f_tmp < 0.0) || (f_tmp > 1.0))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "RIL_GRADIENT_STEP_SIZE", f_tmp);
- }
- else
- {
- solver->parameters.alpha = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s of %.3f\n",
- "RIL_GRADIENT_STEP_SIZE", f_tmp);
- }
- }
-
- solver->parameters.lambda = RIL_DEFAULT_TRACE_DECAY;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "RIL_TRACE_DECAY",
- &f_tmp))
- {
- if ((f_tmp < 0.0) || (f_tmp > 1.0))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "RIL_TRACE_DECAY", f_tmp);
- }
- else
- {
- solver->parameters.lambda = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s of %.3f\n",
- "RIL_TRACE_DECAY", f_tmp);
- }
- }
-
- solver->parameters.epsilon_init = RIL_DEFAULT_EXPLORE_RATIO;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "RIL_EXPLORE_RATIO",
- &f_tmp))
- {
- if ((f_tmp < 0.0) || (f_tmp > 1.0))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "RIL_EXPLORE_RATIO", f_tmp);
- }
- else
- {
- solver->parameters.epsilon_init = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s of %.3f\n",
- "RIL_EXPLORE_RATIO", f_tmp);
- }
- }
-
- solver->parameters.epsilon_decay = RIL_DEFAULT_EXPLORE_DECAY;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "RIL_EXPLORE_DECAY",
- &f_tmp))
- {
- if ((f_tmp < 0.0) || (f_tmp > 1.0))
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "RIL_EXPLORE_DECAY", f_tmp);
- }
- else
- {
- solver->parameters.epsilon_decay = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s of %.3f\n",
- "RIL_EXPLORE_DECAY", f_tmp);
- }
- }
-
- solver->parameters.temperature_init = RIL_DEFAULT_TEMPERATURE;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "RIL_TEMPERATURE",
- &f_tmp))
- {
- if (f_tmp <= 0.0)
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "RIL_TEMPERATURE", f_tmp);
- }
- else
- {
- solver->parameters.temperature_init = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s of %.3f\n",
- "RIL_TEMPERATURE", f_tmp);
- }
- }
-
- solver->parameters.temperature_decay = RIL_DEFAULT_TEMPERATURE_DECAY;
- if (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_float (env->cfg, "ats",
- "RIL_TEMPERATURE_DECAY",
- &f_tmp))
- {
- if ((f_tmp <= 0.0) ||(solver->parameters.temperature_decay > 1) )
- {
- LOG (GNUNET_ERROR_TYPE_ERROR, _ ("Invalid %s configuration %f \n"),
- "RIL_TEMPERATURE_DECAY", f_tmp);
- }
- else
- {
- solver->parameters.temperature_decay = f_tmp;
- LOG (GNUNET_ERROR_TYPE_INFO, "Using %s of %.3f\n",
- "RIL_TEMPERATURE_DECAY", f_tmp);
- }
- }
-
- if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (env->cfg, "ats",
- "RIL_SIMULATE",
- &solver->simulate))
- {
- solver->simulate = GNUNET_NO;
- }
-
- if (GNUNET_YES == GNUNET_CONFIGURATION_get_value_yesno (env->cfg, "ats",
- "RIL_REPLACE_TRACES"))
- {
- solver->parameters.eligibility_trace_mode = RIL_E_REPLACE;
- }
- else
- {
- solver->parameters.eligibility_trace_mode = RIL_E_ACCUMULATE;
- }
-
- if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (env->cfg, "ats",
- "RIL_SOCIAL_WELFARE",
- &string))
- {
- solver->parameters.social_welfare = ! strcmp (string, "NASH") ?
- RIL_WELFARE_NASH :
- RIL_WELFARE_EGALITARIAN;
- GNUNET_free (string);
- }
- else
- {
- solver->parameters.social_welfare = RIL_DEFAULT_WELFARE;
- }
-
- solver->env = env;
- sf.cls = solver;
- sf.s_add = &GAS_ril_address_add;
- sf.s_address_update_property = &GAS_ril_address_property_changed;
- sf.s_get = &GAS_ril_get_preferred_address;
- sf.s_get_stop = &GAS_ril_stop_get_preferred_address;
- sf.s_pref = &GAS_ril_address_change_preference;
- sf.s_feedback = &GAS_ril_address_preference_feedback;
- sf.s_del = &GAS_ril_address_delete;
- sf.s_bulk_start = &GAS_ril_bulk_start;
- sf.s_bulk_stop = &GAS_ril_bulk_stop;
-
- solver->networks_count = env->network_count;
- solver->network_entries = GNUNET_malloc (env->network_count * sizeof(struct
- RIL_Scope));
- solver->step_count = 0;
- solver->done = GNUNET_NO;
-
- for (c = 0; c < env->network_count; c++)
- {
- cur = &solver->network_entries[c];
- cur->type = c;
- cur->bw_in_available = env->in_quota[c];
- cur->bw_out_available = env->out_quota[c];
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "init() Quotas for %s network: IN %llu - OUT %llu\n",
- GNUNET_NT_to_string (cur->type),
- cur->bw_in_available / 1024,
- cur->bw_out_available / 1024);
- }
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "init() Parameters:\n");
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "init() Algorithm = %s, alpha = %f, beta = %f, lambda = %f\n",
- solver->parameters.algorithm ? "Q" : "SARSA",
- solver->parameters.alpha,
- solver->parameters.beta,
- solver->parameters.lambda);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "init() exploration_ratio = %f, temperature = %f, ActionSelection = %s\n",
- solver->parameters.epsilon,
- solver->parameters.temperature,
- solver->parameters.select ? "EGREEDY" : "SOFTMAX");
- LOG (GNUNET_ERROR_TYPE_DEBUG, "init() RBF_DIVISOR = %llu\n",
- solver->parameters.rbf_divisor);
-
- return &sf;
-}
-
-
-/**
- * Exit point for the plugin
- *
- * @param cls the solver handle
- */
-void *
-libgnunet_plugin_ats_ril_done (void *cls)
-{
- struct GNUNET_ATS_SolverFunctions *sf = cls;
- struct GAS_RIL_Handle *s = sf->cls;
- struct RIL_Peer_Agent *cur_agent;
- struct RIL_Peer_Agent *next_agent;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "API_done() Shutting down RIL solver\n");
-
- s->done = GNUNET_YES;
-
- cur_agent = s->agents_head;
- while (NULL != cur_agent)
- {
- next_agent = cur_agent->next;
- GNUNET_CONTAINER_DLL_remove (s->agents_head, s->agents_tail, cur_agent);
- agent_die (s, cur_agent);
- cur_agent = next_agent;
- }
-
- if (NULL != s->step_next_task_id)
- {
- GNUNET_SCHEDULER_cancel (s->step_next_task_id);
- }
- GNUNET_free (s->network_entries);
- GNUNET_free (s);
-
- return NULL;
-}
-
-
-/* end of plugin_ats_ril.c */
diff --git a/src/ats/test_ats2_lib.c b/src/ats/test_ats2_lib.c
deleted file mode 100644
index f2a8eb1ea..000000000
--- a/src/ats/test_ats2_lib.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2010-2015 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-/**
- * @file ats/test_ats2_lib.c
- * @brief test ATS library with a generic interpreter for running ATS tests
- * @author Julius B√ľnger
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_ats_application_service.h"
-#include "gnunet_ats_transport_service.h"
-#include "gnunet_testing_lib.h"
-
-/**
- * @brief Indicates the success of the whole test
- */
-static int ret;
-
-/**
- * @brief The time available until the test shuts down
- */
-static struct GNUNET_TIME_Relative timeout;
-
-/**
- * @brief ATS Application Handle
- *
- * Handle to the application-side of ATS.
- */
-static struct GNUNET_ATS_ApplicationHandle *ah;
-
-/**
- * @brief ATS Transport Handle
- *
- * Handle to the transport-side of ATS.
- */
-static struct GNUNET_ATS_TransportHandle *th;
-
-/**
- * @brief Another (dummy) peer.
- *
- * Used as the peer ATS shall allocate bandwidth to.
- */
-static struct GNUNET_PeerIdentity other_peer;
-
-/**
- * @brief Handle to the session record
- */
-static struct GNUNET_ATS_SessionRecord *sr;
-
-
-/**
- * @brief Called whenever allocation changed
- *
- * Implements #GNUNET_ATS_AllocationCallback
- *
- * @param cls
- * @param session
- * @param bandwidth_out
- * @param bandwidth_in
- *
- * @return
- */
-static void
-allocation_cb (void *cls,
- struct GNUNET_ATS_Session *session,
- struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
- struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "allocation_cb() called\n");
-}
-
-
-/**
- * @brief Called whenever suggestion is made
- *
- * Implements #GNUNET_ATS_SuggestionCallback
- *
- * @param cls
- * @param pid
- * @param address
- */
-static void
-suggestion_cb (void *cls,
- const struct GNUNET_PeerIdentity *pid,
- const char *address)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "suggestion_cb() called\n");
- ret = 0;
-}
-
-
-/**
- * @brief Initialise both 'sides' of ATS
- *
- * Initialises the application and transportation side of ATS.
- */
-static void
-init_both (const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- ah = GNUNET_ATS_application_init (cfg);
- GNUNET_assert (NULL != ah);
- th = GNUNET_ATS_transport_init (cfg,
- &allocation_cb,
- NULL,
- &suggestion_cb,
- NULL);
- GNUNET_assert (NULL != ah);
-}
-
-
-/**
- * @brief Disconnect both 'sides' of ATS
- */
-static void
-finish_both (void)
-{
- GNUNET_ATS_application_done (ah);
- ah = NULL;
- GNUNET_ATS_transport_done (th);
- th = NULL;
-}
-
-
-/**
- * @brief Provide information about the start of an imaginary connection
- */
-static void
-provide_info_start (void)
-{
- struct GNUNET_ATS_Properties prop = {
- .delay = GNUNET_TIME_UNIT_FOREVER_REL,
- .goodput_out = 1048576,
- .goodput_in = 1048576,
- .utilization_out = 0,
- .utilization_in = 0,
- .distance = 0,
- .mtu = UINT32_MAX,
- .nt = GNUNET_NT_UNSPECIFIED,
- .cc = GNUNET_TRANSPORT_CC_UNKNOWN,
- };
-
- sr = GNUNET_ATS_session_add (th,
- &other_peer,
- "test-address",
- NULL,
- &prop);
- GNUNET_assert (NULL != sr);
-}
-
-
-/**
- * @brief Provide information about the end of an imaginary connection
- */
-static void
-provide_info_end (void)
-{
- GNUNET_ATS_session_del (sr);
-}
-
-
-/**
- * @brief Inform ATS about the need of a connection towards a peer
- */
-static void
-get_suggestion (void)
-{
- struct GNUNET_ATS_ApplicationSuggestHandle *ash;
-
- ash = GNUNET_ATS_application_suggest (ah,
- &other_peer,
- GNUNET_MQ_PREFERENCE_NONE,
- GNUNET_BANDWIDTH_VALUE_MAX);
- GNUNET_assert (NULL != ash);
-}
-
-
-static void
-on_shutdown (void *cls)
-{
- provide_info_end ();
- finish_both ();
- GNUNET_SCHEDULER_shutdown ();
-}
-
-
-/**
- * Function run once the ATS service has been started.
- *
- * @param cls NULL
- * @param cfg configuration for the testcase
- * @param peer handle to the peer
- */
-static void
-run (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_TESTING_Peer *peer)
-{
- init_both (cfg);
- provide_info_start ();
- get_suggestion ();
- (void) GNUNET_SCHEDULER_add_delayed (timeout,
- &on_shutdown,
- NULL);
-}
-
-
-/**
- * @brief Starts the gnunet-testing peer
- *
- * @param argc
- * @param argv[]
- *
- * @return
- */
-int
-main (int argc,
- char *argv[])
-{
- ret = 1;
- memset (&other_peer, 0, sizeof(struct GNUNET_PeerIdentity));
- timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
- 2);
- if (0 != GNUNET_TESTING_peer_run ("test-ats2-lib",
- "test_ats2_lib.conf",
- &run, NULL))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Running the testing peer failed.\n");
- return 1;
- }
- if (0 != ret)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Global status indicates unsuccessful testrun - probably allocation_cb was not called.\n");
- ret = 77; // SKIP test, test not yet right!
- }
- return ret;
-}
-
-
-
-/* end of test_ats2_lib.c */
diff --git a/src/ats/test_ats2_lib.conf b/src/ats/test_ats2_lib.conf
deleted file mode 100644
index e24f5ea68..000000000
--- a/src/ats/test_ats2_lib.conf
+++ /dev/null
@@ -1,13 +0,0 @@
-@INLINE@ ../../contrib/conf/gnunet/no_forcestart.conf
-@INLINE@ ../../contrib/conf/gnunet/no_autostart_above_core.conf
-
-[ats]
-BINARY = gnunet-service-ats-new
-
-[core]
-START_ON_DEMAND = NO
-IMMEDIATE_START = NO
-
-[transport]
-START_ON_DEMAND = NO
-IMMEDIATE_START = NO
diff --git a/src/ats/test_ats2_lib.h b/src/ats/test_ats2_lib.h
deleted file mode 100644
index 090abc20d..000000000
--- a/src/ats/test_ats2_lib.h
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2010-2015 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-/**
- * @file ats/test_ats_lib.h
- * @brief test ATS library with a generic interpreter for running ATS tests
- * @author Christian Grothoff
- */
-#ifndef TEST_ATS_LIB_H
-#define TEST_ATS_LIB_H
-
-#include "gnunet_util_lib.h"
-#include "gnunet_ats_application_service.h"
-#include "gnunet_ats_transport_service.h"
-#include "gnunet_testing_lib.h"
-
-
-///**
-// * Commands for the interpreter.
-// */
-// enum CommandCode
-// {
-// /**
-// * End the test (passing).
-// */
-// CMD_END_PASS = 0,
-//
-// /**
-// * Call #GNUNET_ATS_address_add().
-// */
-// CMD_ADD_ADDRESS,
-//
-// /**
-// * Call #GNUNET_ATS_address_del().
-// */
-// CMD_DEL_ADDRESS,
-//
-// /**
-// * Wait for ATS to suggest address.
-// */
-// CMD_AWAIT_ADDRESS_SUGGESTION,
-//
-// /**
-// * Wait for ATS to suggest disconnect.
-// */
-// CMD_AWAIT_DISCONNECT_SUGGESTION,
-//
-// /**
-// * Ask ATS to connect to a peer, using
-// * #GNUNET_ATS_connectivity_suggest().
-// */
-// CMD_REQUEST_CONNECTION_START,
-//
-// /**
-// * Tell ATS we no longer need a connection to a peer, using
-// * #GNUNET_ATS_connectivity_suggest_cancel().
-// */
-// CMD_REQUEST_CONNECTION_STOP,
-//
-// /**
-// * Wait for certain address information to be provided.
-// */
-// CMD_AWAIT_ADDRESS_INFORMATION,
-//
-// /**
-// * Update properties of an address, using
-// * #GNUNET_ATS_address_update().
-// */
-// CMD_UPDATE_ADDRESS,
-//
-// /**
-// * Add session to an address, using
-// * #GNUNET_ATS_address_add_session().
-// */
-// CMD_ADD_SESSION,
-//
-// /**
-// * Remove session from an address, using
-// * #GNUNET_ATS_address_del_session().
-// */
-// CMD_DEL_SESSION,
-//
-// /**
-// * Change performance preferences for a peer, testing
-// * #GNUNET_ATS_performance_change_preference().
-// */
-// CMD_CHANGE_PREFERENCE,
-//
-// /**
-// * Provide allocation quality feedback, testing
-// * #GNUNET_ATS_performance_give_feedback().
-// */
-// CMD_PROVIDE_FEEDBACK,
-//
-// /**
-// * Obtain list of all addresses, testing
-// * #GNUNET_ATS_performance_list_addresses().
-// */
-// CMD_LIST_ADDRESSES,
-//
-// /**
-// * Reserve bandwidth, testing
-// * #GNUNET_ATS_reserve_bandwidth().
-// */
-// CMD_RESERVE_BANDWIDTH,
-//
-// /**
-// * Wait for a bit.
-// */
-// CMD_SLEEP
-//
-// };
-//
-//
-///**
-// * Details for the #CMD_ADD_ADDRESS command.
-// */
-// struct CommandAddAddress
-// {
-// /**
-// * Number of the peer (used to generate PID).
-// */
-// unsigned int pid;
-//
-// /**
-// * Number of the address (used to generate binary address).
-// */
-// unsigned int addr_num;
-//
-// /**
-// * Session to supply, 0 for NULL.
-// */
-// unsigned int session;
-//
-// /**
-// * Flags to set for the address.
-// */
-// enum GNUNET_HELLO_AddressInfo addr_flags;
-//
-// /**
-// * Performance properties to supply.
-// */
-// struct GNUNET_ATS_Properties properties;
-//
-// /**
-// * Expect the operation to fail (duplicate).
-// */
-// int expect_fail;
-//
-// /**
-// * Here the result of the add address operation will be stored.
-// */
-// struct GNUNET_ATS_AddressRecord *ar;
-// };
-//
-//
-///**
-// * Details for the #CMD_DEL_ADDRESS command.
-// */
-// struct CommandDelAddress
-// {
-// /**
-// * Label of the corresponding #CMD_ADD_ADDRESS that
-// * we are now to remove.
-// */
-// const char *add_label;
-// };
-//
-//
-///**
-// * Details for the #CMD_AWAIT_ADDRESS_SUGGESTION command.
-// */
-// struct CommandAwaitAddressSuggestion
-// {
-// /**
-// * For which peer do we expect a suggestion?
-// */
-// unsigned int pid;
-//
-// /**
-// * If we expect the address suggested to match a particular
-// * addition, specify the label of the add operation here. Otherwise
-// * use NULL for "any" available address.
-// */
-// const char *add_label;
-//
-// };
-//
-//
-///**
-// * Details for the #CMD_AWAIT_DISCONNECT_SUGGESTION command.
-// */
-// struct CommandAwaitDisconnectSuggestion
-// {
-// /**
-// * For which peer do we expect the disconnect?
-// */
-// unsigned int pid;
-//
-// };
-//
-//
-///**
-// * Details for the #CMD_REQUEST_CONNECTION_START command.
-// */
-// struct CommandRequestConnectionStart
-// {
-// /**
-// * Identity of the peer we would like to connect to.
-// */
-// unsigned int pid;
-//
-// /**
-// * Location where we store the handle returned from
-// * #GNUNET_ATS_connectivity_suggest().
-// */
-// struct GNUNET_ATS_ConnectivitySuggestHandle *csh;
-// };
-//
-//
-///**
-// * Details for the #CMD_REQUEST_CONNECTION_STOP command.
-// */
-// struct CommandRequestConnectionStop
-// {
-// /**
-// * Label of the corresponding #CMD_REQUEST_CONNECTION_START that
-// * we are now stopping.
-// */
-// const char *connect_label;
-// };
-//
-//
-///**
-// * Details for the #CMD_AWAIT_ADDRESS_INFORMATION command.
-// */
-// struct CommandAwaitAddressInformation
-// {
-// /**
-// * For which address do we expect information?
-// * The address is identified by the respective
-// * label of the corresponding add operation.
-// */
-// const char *add_label;
-//
-// /**
-// * Label of a possible update operation that may
-// * have modified the properties. NULL to use
-// * the properties from the @e add_label.
-// */
-// const char *update_label;
-//
-// };
-//
-//
-///**
-// * Details for the #CMD_UPDATE_ADDRESS command.
-// */
-// struct CommandUpdateAddress
-// {
-// /**
-// * Label of the addresses's add operation.
-// */
-// const char *add_label;
-//
-// /**
-// * Performance properties to supply.
-// */
-// struct GNUNET_ATS_Properties properties;
-//
-// };
-//
-//
-///**
-// * Details for the #CMD_ADD_SESSION command.
-// */
-// struct CommandAddSession
-// {
-// /**
-// * Label of the addresses's add operation.
-// */
-// const char *add_label;
-//
-// /**
-// * Session to supply.
-// */
-// unsigned int session;
-//
-// };
-//
-//
-///**
-// * Details for the #CMD_DEL_SESSION command.
-// */
-// struct CommandDelSession
-// {
-// /**
-// * Label of the addresses's add operation.
-// */
-// const char *add_session_label;
-//
-// };
-//
-//
-///**
-// * Details for the #CMD_CHANGE_PREFERENCE command.
-// */
-// struct CommandChangePreference
-// {
-// /**
-// * Identity of the peer we have a preference change towards.
-// */
-// unsigned int pid;
-//
-// /* FIXME: preference details! */
-//
-// };
-//
-//
-///**
-// * Details for the #CMD_PROVIDE_FEEDBACK command.
-// */
-// struct CommandProvideFeedback
-// {
-// /**
-// * Identity of the peer we have a feedback for.
-// */
-// unsigned int pid;
-//
-// /**
-// * Over which timeframe does the feedback apply?
-// */
-// struct GNUNET_TIME_Relative scope;
-//
-// /* FIXME: feedback details! */
-// };
-//
-//
-///**
-// * Details for the #CMD_LIST_ADDRESSES command.
-// */
-// struct CommandListAddresses
-// {
-// /**
-// * Identity of the peer we want a list for.
-// */
-// unsigned int pid;
-//
-// /**
-// * All addresses or just active?
-// */
-// int all;
-//
-// /**
-// * Minimum number of addresses the callback may report.
-// */
-// unsigned int min_calls;
-//
-// /**
-// * Maximum number of addresses the callback may report.
-// */
-// unsigned int max_calls;
-//
-// /**
-// * Minimum number of active addresses the callback may report.
-// */
-// unsigned int min_active_calls;
-//
-// /**
-// * Maximum number of active addresses the callback may report.
-// */
-// unsigned int max_active_calls;
-//
-// /**
-// * Number of calls the command invoked the callback with
-// * an address marked as active. (Set by command).
-// */
-// unsigned int active_calls;
-//
-// /**
-// * Number of calls the command invoked the callback with
-// * any address marked as available to ATS. (Set by command).
-// */
-// unsigned int calls;
-//
-// /**
-// * Location where we store the return value from
-// * #GNUNET_ATS_performance_list_addresses().
-// */
-// struct GNUNET_ATS_AddressListHandle *alh;
-//
-// };
-//
-//
-///**
-// * Details for the #CMD_RESERVE_BANDWIDTH command.
-// */
-// struct CommandReserveBandwidth
-// {
-// /**
-// * For which peer do we reserve bandwidth?
-// */
-// unsigned int pid;
-//
-// /**
-// * How much should we try to reserve?
-// */
-// int32_t amount;
-//
-// /**
-// * Should we expect this to work or fail?
-// * #GNUNET_YES: must work
-// * #GNUNET_NO: may work or fail
-// * #GNUNET_SYSERR: must fail
-// */
-// int expected_result;
-//
-// /**
-// * Location where we store the return value from
-// * #GNUNET_ATS_reserve_bandwidth().
-// */
-// struct GNUNET_ATS_ReservationContext *rc;
-//
-// };
-//
-//
-///**
-// * Details for the #CMD_SLEEP command.
-// */
-// struct CommandSleep
-// {
-// /**
-// * How long should we wait before running the next command?
-// */
-// struct GNUNET_TIME_Relative delay;
-// };
-//
-//
-///**
-// * A command for the test case interpreter.
-// */
-// struct Command
-// {
-// /**
-// * Command code to run.
-// */
-// enum CommandCode code;
-//
-// /**
-// * Commands can be given a label so we can reference them later.
-// */
-// const char *label;
-//
-// /**
-// * Additional arguments to commands, if any.
-// */
-// union {
-//
-// struct CommandAddAddress add_address;
-//
-// struct CommandDelAddress del_address;
-//
-// struct CommandAwaitAddressSuggestion await_address_suggestion;
-//
-// struct CommandAwaitDisconnectSuggestion await_disconnect_suggestion;
-//
-// struct CommandRequestConnectionStart request_connection_start;
-//
-// struct CommandRequestConnectionStop request_connection_stop;
-//
-// struct CommandAwaitAddressInformation await_address_information;
-//
-// struct CommandUpdateAddress update_address;
-//
-// struct CommandAddSession add_session;
-//
-// struct CommandDelSession del_session;
-//
-// struct CommandChangePreference change_preference;
-//
-// struct CommandProvideFeedback provide_feedback;
-//
-// struct CommandListAddresses list_addresses;
-//
-// struct CommandReserveBandwidth reserve_bandwidth;
-//
-// struct CommandSleep sleep;
-//
-// } details;
-//
-// };
-
-
-/**
- * Run ATS test.
- *
- * @param argc length of @a argv
- * @param argv command line
- * @param cmds commands to run with the interpreter
- * @param timeout how long is the test allowed to take?
- * @return 0 on success
- */
-int
-TEST_ATS_run (int argc,
- char *argv[],
- struct Command *cmds,
- struct GNUNET_TIME_Relative timeout);
-
-#endif
diff --git a/src/ats/test_ats_api_mlp.conf b/src/ats/test_ats_api_mlp.conf
deleted file mode 100644
index d5f05a3c4..000000000
--- a/src/ats/test_ats_api_mlp.conf
+++ /dev/null
@@ -1,45 +0,0 @@
-@INLINE@ ../../contrib/conf/gnunet/no_forcestart.conf
-
-[PATHS]
-GNUNET_TEST_HOME = $GNUNET_TMP/test-ats-mlp/
-
-[ats]
-# Enable MLP mode (default: NO)
-MODE = mlp
-# Network specific inbound/outbound quotas
-# UNSPECIFIED
-UNSPECIFIED_QUOTA_IN = unlimited
-UNSPECIFIED_QUOTA_OUT = unlimited
-# LOOPBACK
-LOOPBACK_QUOTA_IN = unlimited
-LOOPBACK_QUOTA_OUT = unlimited
-# LAN
-LAN_QUOTA_IN = unlimited
-LAN_QUOTA_OUT = unlimited
-# WAN
-WAN_QUOTA_IN = 64 KiB
-WAN_QUOTA_OUT = 64 KiB
-# WLAN
-WLAN_QUOTA_IN = 4096
-WLAN_QUOTA_OUT = 4096
-
-# MLP specific settings
-ATS_MIN_INTERVAL = 15000
-ATS_EXEC_INTERVAL = 30000
-
-# MLP defaults
-# MLP_MAX_DURATION = 3 s
-# MLP_MAX_ITERATIONS = 1024
-# MLP_COEFFICIENT_D = 1.0
-# MLP_COEFFICIENT_U = 1.0
-# MLP_COEFFICIENT_R = 1.0
-# MLP_MIN_BANDWIDTH = 1024
-# MLP_MIN_CONNECTIONS = 4
-
-# MLP Debugging settings
-DUMP_MLP = NO
-DUMP_SOLUTION = NO
-DUMP_OVERWRITE = NO
-DUMP_MIN_PEERS = 0
-DUMP_MIN_ADDRS = 0
-DUMP_OVERWRITE = NO
diff --git a/src/ats/test_ats_api_ril.conf b/src/ats/test_ats_api_ril.conf
deleted file mode 100644
index 5f5fb006b..000000000
--- a/src/ats/test_ats_api_ril.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-@INLINE@ ../../contrib/conf/gnunet/no_forcestart.conf
-
-[PATHS]
-GNUNET_TEST_HOME = $GNUNET_TMP/test-ats-ril/
-
-[ats]
-# Enable RIL mode (default: NO)
-MODE = ril
-# Network specific inbound/outbound quotas
-# UNSPECIFIED
-UNSPECIFIED_QUOTA_IN = unlimited
-UNSPECIFIED_QUOTA_OUT = unlimited
-# LOOPBACK
-LOOPBACK_QUOTA_IN = unlimited
-LOOPBACK_QUOTA_OUT = unlimited
-# LAN
-LAN_QUOTA_IN = unlimited
-LAN_QUOTA_OUT = unlimited
-# WAN
-WAN_QUOTA_IN = 64 KiB
-WAN_QUOTA_OUT = 64 KiB
-# WLAN
-WLAN_QUOTA_IN = 4096
-WLAN_QUOTA_OUT = 4096
diff --git a/src/ats/test_ats_solver_delayed_mlp.conf b/src/ats/test_ats_solver_delayed_mlp.conf
deleted file mode 100644
index 632755570..000000000
--- a/src/ats/test_ats_solver_delayed_mlp.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-@INLINE@ test_ats_solver_default.conf
-
-[ats]
-PREFIX = ./test_delay -t 10 --
-MODE = mlp
-# UNSPECIFIED
-UNSPECIFIED_QUOTA_IN = 64 KiB
-UNSPECIFIED_QUOTA_OUT = 64 KiB
-# LOOPBACK
-LOOPBACK_QUOTA_IN = unlimited
-LOOPBACK_QUOTA_OUT = unlimited
-# LAN
-LAN_QUOTA_IN = unlimited
-LAN_QUOTA_OUT = unlimited
-# WAN
-WAN_QUOTA_IN = 64 KiB
-WAN_QUOTA_OUT = 64 KiB
-# WLAN
-WLAN_QUOTA_IN = 512
-WLAN_QUOTA_OUT = 512
diff --git a/src/ats/test_ats_solver_delayed_ril.conf b/src/ats/test_ats_solver_delayed_ril.conf
deleted file mode 100644
index a43fffa4c..000000000
--- a/src/ats/test_ats_solver_delayed_ril.conf
+++ /dev/null
@@ -1,31 +0,0 @@
-@INLINE@ test_ats_solver_default.conf
-
-[ats]
-PREFIX = ./test_delay -t 10 --
-MODE = ril
-# UNSPECIFIED
-UNSPECIFIED_QUOTA_IN = 64 KiB
-UNSPECIFIED_QUOTA_OUT = 64 KiB
-# LOOPBACK
-LOOPBACK_QUOTA_IN = unlimited
-LOOPBACK_QUOTA_OUT = unlimited
-# LAN
-LAN_QUOTA_IN = unlimited
-LAN_QUOTA_OUT = unlimited
-# WAN
-WAN_QUOTA_IN = 64 KiB
-WAN_QUOTA_OUT = 64 KiB
-# WLAN
-WLAN_QUOTA_IN = 512
-WLAN_QUOTA_OUT = 512
-
-# Reinforcement Learning Parameters
-RIL_STEP_TIME_MIN = 500 ms
-RIL_STEP_TIME_MAX = 1000 ms
-
-RIL_ALGORITHM = Q
-RIL_DISCOUNT_BETA = 0.7
-RIL_GRADIENT_STEP_SIZE = 0.3
-RIL_TRACE_DECAY = 0.2
-RIL_EXPLORE_RATIO = 0.1
-RIL_GLOBAL_REWARD_SHARE = 1
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index d5c097341..9e0813425 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -29,7 +29,6 @@ gnunetinclude_HEADERS = \
gnunet_ats_application_service.h \
gnunet_ats_transport_service.h \
gnunet_ats_plugin.h \
- gnunet_ats_plugin_new.h \
gnunet_bandwidth_lib.h \
gnunet_bio_lib.h \
gnunet_block_lib.h \
diff --git a/src/include/gnunet_ats_plugin_new.h b/src/include/gnunet_ats_plugin_new.h
deleted file mode 100644
index b371321fa..000000000
--- a/src/include/gnunet_ats_plugin_new.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- This file is part of GNUnet
- Copyright (C) 2009-2015, 2018 GNUnet e.V.
-
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- 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
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- SPDX-License-Identifier: AGPL3.0-or-later
- */
-
-/**
- * @author Christian Grothoff
- *
- * @file
- * API for the ATS solvers.
- *
- * @defgroup ats-plugin ATS service plugin API
- * Plugin API for the ATS service.
- *
- * Specifies the struct that is given to the plugin's entry method and the other
- * struct that must be returned. Note that the destructors of ATS plugins will
- * be given the value returned by the constructor and is expected to return a
- * NULL pointer.
- *
- * @{
- */
-#ifndef PLUGIN_ATS_H
-#define PLUGIN_ATS_H
-
-#include "gnunet_util_lib.h"
-#include "gnunet_ats_application_service.h"
-#include "gnunet_ats_transport_service.h"
-#include "gnunet_statistics_service.h"
-
-
-/**
- * Preference being expressed by an application client.
- */
-struct GNUNET_ATS_Preference
-{
- /**
- * Peer to get address suggestions for.
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * How much bandwidth in bytes/second does the application expect?
- */
- struct GNUNET_BANDWIDTH_Value32NBO bw;
-
- /**
- * What type of performance preference does the client have?
- */
- enum GNUNET_MQ_PreferenceKind pk;
-};
-
-
-/**
- * Opaque representation of a session the plugin can allocate bandwidth for.
- */
-struct GNUNET_ATS_Session;
-
-/**
- * Plugin-relevant information about a session.
- */
-struct GNUNET_ATS_SessionData
-{
- /**
- * Peer the session is with.
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * ATS performance characteristics for a session.
- */
- struct GNUNET_ATS_Properties prop;
-
- /**
- * Handle to the session that has the given properties.
- */
- struct GNUNET_ATS_Session *session;
-
- /**
- * Is the session inbound only?
- */
- int inbound_only;
-};
-
-/**
- * Internal representation of a preference by the plugin.
- * (If desired, plugin may just use NULL.)
- */
-struct GNUNET_ATS_PreferenceHandle;
-
-/**
- * Internal representation of a session by the plugin.
- * (If desired, plugin may just use NULL.)
- */
-struct GNUNET_ATS_SessionHandle;
-
-
-/**
- * Solver functions.
- *
- * Each solver is required to set up and return an instance
- * of this struct during initialization.
- */
-struct GNUNET_ATS_SolverFunctions
-{
- /**
- * Closure to pass to all solver functions in this struct.
- */
- void *cls;
-
- /**
- * The plugin should begin to respect a new preference.
- *
- * @param cls the closure
- * @param pref the preference to add
- * @return plugin's internal representation, or NULL
- */
- struct GNUNET_ATS_PreferenceHandle *
- (*preference_add)(void *cls,
- const struct GNUNET_ATS_Preference *pref);
-
- /**
- * The plugin should end respecting a preference.
- *
- * @param cls the closure
- * @param ph whatever @e preference_add returned
- * @param pref the preference to delete
- * @return plugin's internal representation, or NULL
- */
- void
- (*preference_del)(void *cls,
- struct GNUNET_ATS_PreferenceHandle *ph,
- const struct GNUNET_ATS_Preference *pref);
-
- /**
- * Transport established a new session with performance
- * characteristics given in @a data.
- *
- * @param cls closure
- * @param data performance characteristics of @a sh
- * @param address address information (for debugging)
- * @return handle by which the plugin will identify this session
- */
- struct GNUNET_ATS_SessionHandle *
- (*session_add)(void *cls,
- const struct GNUNET_ATS_SessionData *data,
- const char *address);
-
- /**
- * @a data changed for a given @a sh, solver should consider
- * the updated performance characteristics.
- *
- * @param cls closure
- * @param sh session this is about
- * @param data performance characteristics of @a sh
- */
- void
- (*session_update)(void *cls,
- struct GNUNET_ATS_SessionHandle *sh,
- const struct GNUNET_ATS_SessionData *data);
-
- /**
- * A session went away. Solver should update accordingly.
- *
- * @param cls closure
- * @param sh session this is about
- * @param data (last) performance characteristics of @a sh
- */
- void
- (*session_del)(void *cls,
- struct GNUNET_ATS_SessionHandle *sh,
- const struct GNUNET_ATS_SessionData *data);
-};
-
-
-/**
- * The ATS plugin will pass a pointer to a struct
- * of this type as to the initialization function
- * of the ATS plugins.
- */
-struct GNUNET_ATS_PluginEnvironment
-{
- /**
- * Configuration handle to be used by the solver
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- /**
- * Statistics handle to be used by the solver
- */
- struct GNUNET_STATISTICS_Handle *stats;
-
- /**
- * Closure to pass to all callbacks in this struct.
- */
- void *cls;
-
- /**
- * Suggest to the transport that it should try establishing
- * a connection using the given address.
- *
- * @param cls closure, NULL
- * @param pid peer this is about
- * @param address address the transport should try
- */
- void
- (*suggest_cb) (void *cls,
- const struct GNUNET_PeerIdentity *pid,
- const char *address);
-
- /**
- * Tell the transport that it should allocate the given
- * bandwidth to the specified session.
- *
- * @param cls closure, NULL
- * @param session session this is about
- * @param peer peer this is about
- * @param bw_in suggested bandwidth for receiving
- * @param bw_out suggested bandwidth for transmission
- */
- void
- (*allocate_cb) (void *cls,
- struct GNUNET_ATS_Session *session,
- const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_BANDWIDTH_Value32NBO bw_in,
- struct GNUNET_BANDWIDTH_Value32NBO bw_out);
-};
-
-
-
-#endif
-
-/** @} */ /* end of group */