aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-05 12:52:20 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-05 12:52:20 +0000
commitc55971f17dc99f9833af48e078c8f681be771cb7 (patch)
tree544fd671b67903506419c98d463d086a696e25a1 /src
parent15dd8e6cc1199d611d804853e134882bf13b234a (diff)
downloadgnunet-c55971f17dc99f9833af48e078c8f681be771cb7.tar.gz
gnunet-c55971f17dc99f9833af48e078c8f681be771cb7.zip
big ATS refactoring, no serious semantic changes should stem from this
Diffstat (limited to 'src')
-rw-r--r--src/ats/Makefile.am41
-rw-r--r--src/ats/gnunet-ats-solver-eval.c110
-rw-r--r--src/ats/gnunet-service-ats.c23
-rw-r--r--src/ats/gnunet-service-ats_addresses.c1166
-rw-r--r--src/ats/gnunet-service-ats_addresses.h140
-rw-r--r--src/ats/gnunet-service-ats_connectivity.c148
-rw-r--r--src/ats/gnunet-service-ats_connectivity.h35
-rw-r--r--src/ats/gnunet-service-ats_normalization.c730
-rw-r--r--src/ats/gnunet-service-ats_normalization.h48
-rw-r--r--src/ats/gnunet-service-ats_performance.c108
-rw-r--r--src/ats/gnunet-service-ats_plugins.c661
-rw-r--r--src/ats/gnunet-service-ats_plugins.h163
-rw-r--r--src/ats/gnunet-service-ats_preferences.c1004
-rw-r--r--src/ats/gnunet-service-ats_preferences.h101
-rw-r--r--src/ats/gnunet-service-ats_scheduling.c5
-rw-r--r--src/ats/gnunet-service-ats_scheduling.h26
-rw-r--r--src/ats/perf_ats_solver.c20
-rw-r--r--src/ats/plugin_ats_mlp.c127
-rw-r--r--src/ats/plugin_ats_proportional.c154
-rw-r--r--src/ats/plugin_ats_ril.c70
-rw-r--r--src/include/gnunet_ats_plugin.h38
-rw-r--r--src/include/gnunet_ats_service.h16
22 files changed, 2348 insertions, 2586 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am
index 282af25c0..123c868ed 100644
--- a/src/ats/Makefile.am
+++ b/src/ats/Makefile.am
@@ -43,6 +43,12 @@ plugin_LTLIBRARIES = \
43 43
44gnunet_ats_solver_eval_SOURCES = \ 44gnunet_ats_solver_eval_SOURCES = \
45 gnunet-ats-solver-eval.c gnunet-ats-solver-eval.h \ 45 gnunet-ats-solver-eval.c gnunet-ats-solver-eval.h \
46 gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \
47 gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \
48 gnunet-service-ats_performance.c gnunet-service-ats_performance.h \
49 gnunet-service-ats_preferences.c gnunet-service-ats_preferences.h \
50 gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h \
51 gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \
46 gnunet-service-ats_normalization.c 52 gnunet-service-ats_normalization.c
47gnunet_ats_solver_eval_LDADD = \ 53gnunet_ats_solver_eval_LDADD = \
48 $(top_builddir)/src/util/libgnunetutil.la \ 54 $(top_builddir)/src/util/libgnunetutil.la \
@@ -101,9 +107,11 @@ libexec_PROGRAMS = \
101gnunet_service_ats_SOURCES = \ 107gnunet_service_ats_SOURCES = \
102 gnunet-service-ats.c gnunet-service-ats.h\ 108 gnunet-service-ats.c gnunet-service-ats.h\
103 gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \ 109 gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \
110 gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \
104 gnunet-service-ats_connectivity.c gnunet-service-ats_connectivity.h \ 111 gnunet-service-ats_connectivity.c gnunet-service-ats_connectivity.h \
105 gnunet-service-ats_normalization.c gnunet-service-ats_normalization.h \ 112 gnunet-service-ats_normalization.c gnunet-service-ats_normalization.h \
106 gnunet-service-ats_performance.c gnunet-service-ats_performance.h \ 113 gnunet-service-ats_performance.c gnunet-service-ats_performance.h \
114 gnunet-service-ats_preferences.c gnunet-service-ats_preferences.h \
107 gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \ 115 gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \
108 gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h 116 gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h
109gnunet_service_ats_LDADD = \ 117gnunet_service_ats_LDADD = \
@@ -516,7 +524,16 @@ test_ats_solver_alternative_after_delete_address_ril_LDADD = \
516# libgnunetats.la 524# libgnunetats.la
517 525
518perf_ats_solver_mlp_SOURCES = \ 526perf_ats_solver_mlp_SOURCES = \
519 perf_ats_solver.c test_ats_api_common.c gnunet-service-ats_normalization.c 527 perf_ats_solver.c \
528 test_ats_api_common.c \
529 gnunet-service-ats_normalization.c \
530 gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \
531 gnunet-service-ats_performance.c gnunet-service-ats_performance.h \
532 gnunet-service-ats_preferences.c gnunet-service-ats_preferences.h \
533 gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \
534 gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \
535 gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h
536
520perf_ats_solver_mlp_LDADD = \ 537perf_ats_solver_mlp_LDADD = \
521 $(GN_LIBGLPK) \ 538 $(GN_LIBGLPK) \
522 $(top_builddir)/src/util/libgnunetutil.la \ 539 $(top_builddir)/src/util/libgnunetutil.la \
@@ -524,7 +541,16 @@ perf_ats_solver_mlp_LDADD = \
524 libgnunetats.la 541 libgnunetats.la
525 542
526perf_ats_solver_proportional_SOURCES = \ 543perf_ats_solver_proportional_SOURCES = \
527 perf_ats_solver.c test_ats_api_common.c gnunet-service-ats_normalization.c 544 perf_ats_solver.c \
545 test_ats_api_common.c \
546 gnunet-service-ats_normalization.c \
547 gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \
548 gnunet-service-ats_preferences.c gnunet-service-ats_preferences.h \
549 gnunet-service-ats_performance.c gnunet-service-ats_performance.h \
550 gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \
551 gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \
552 gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h
553
528perf_ats_solver_proportional_LDADD = \ 554perf_ats_solver_proportional_LDADD = \
529 $(GN_LIBGLPK) \ 555 $(GN_LIBGLPK) \
530 $(top_builddir)/src/util/libgnunetutil.la \ 556 $(top_builddir)/src/util/libgnunetutil.la \
@@ -532,7 +558,16 @@ perf_ats_solver_proportional_LDADD = \
532 libgnunetats.la 558 libgnunetats.la
533 559
534perf_ats_solver_ril_SOURCES = \ 560perf_ats_solver_ril_SOURCES = \
535 perf_ats_solver.c test_ats_api_common.c gnunet-service-ats_normalization.c 561 perf_ats_solver.c \
562 test_ats_api_common.c \
563 gnunet-service-ats_normalization.c \
564 gnunet-service-ats_addresses.c gnunet-service-ats_addresses.h \
565 gnunet-service-ats_preferences.c gnunet-service-ats_preferences.h \
566 gnunet-service-ats_performance.c gnunet-service-ats_performance.h \
567 gnunet-service-ats_scheduling.c gnunet-service-ats_scheduling.h \
568 gnunet-service-ats_plugins.c gnunet-service-ats_plugins.h \
569 gnunet-service-ats_reservations.c gnunet-service-ats_reservations.h
570
536perf_ats_solver_ril_LDADD = \ 571perf_ats_solver_ril_LDADD = \
537 $(GN_LIBGLPK) \ 572 $(GN_LIBGLPK) \
538 $(top_builddir)/src/util/libgnunetutil.la \ 573 $(top_builddir)/src/util/libgnunetutil.la \
diff --git a/src/ats/gnunet-ats-solver-eval.c b/src/ats/gnunet-ats-solver-eval.c
index 58fe03e25..6bf640f21 100644
--- a/src/ats/gnunet-ats-solver-eval.c
+++ b/src/ats/gnunet-ats-solver-eval.c
@@ -26,9 +26,17 @@
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet-ats-solver-eval.h" 28#include "gnunet-ats-solver-eval.h"
29#include "gnunet-service-ats_normalization.h"
30#include "gnunet-service-ats_preferences.h"
29 31
30#define BIG_M_STRING "unlimited" 32#define BIG_M_STRING "unlimited"
31 33
34/**
35 * Handle for statistics.
36 */
37struct GNUNET_STATISTICS_Handle *GSA_stats;
38
39
32static struct Experiment *e; 40static struct Experiment *e;
33 41
34static struct LoggingHandle *l; 42static struct LoggingHandle *l;
@@ -36,6 +44,7 @@ static struct LoggingHandle *l;
36static struct SolverHandle *sh; 44static struct SolverHandle *sh;
37 45
38static struct TestPeer *peer_head; 46static struct TestPeer *peer_head;
47
39static struct TestPeer *peer_tail; 48static struct TestPeer *peer_tail;
40 49
41static double default_properties[GNUNET_ATS_PropertyCount]; 50static double default_properties[GNUNET_ATS_PropertyCount];
@@ -670,8 +679,7 @@ set_prop_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
670 pg->ats_property, prop_value, prop_value); 679 pg->ats_property, prop_value, prop_value);
671 } 680 }
672 else 681 else
673 GAS_normalization_normalize_property (sh->addresses, 682 GAS_normalization_normalize_property (pg->test_address->ats_addr, &atsi, 1);
674 pg->test_address->ats_addr, &atsi, 1);
675 sh->env.sf.s_bulk_stop (sh->solver); 683 sh->env.sf.s_bulk_stop (sh->solver);
676 684
677 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency, 685 pg->set_task = GNUNET_SCHEDULER_add_delayed (pg->frequency,
@@ -3040,7 +3048,8 @@ get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
3040 return p->pref_abs; 3048 return p->pref_abs;
3041 } 3049 }
3042 else 3050 else
3043 return GAS_normalization_get_preferences_by_peer (id); 3051 return GAS_normalization_get_preferences_by_peer (NULL,
3052 id);
3044} 3053}
3045 3054
3046 3055
@@ -3058,96 +3067,8 @@ get_property_cb (void *cls, const struct ATS_Address *address)
3058 a = find_address_by_ats_address (p, address); 3067 a = find_address_by_ats_address (p, address);
3059 return a->prop_abs; 3068 return a->prop_abs;
3060 } 3069 }
3061 return GAS_normalization_get_properties ((struct ATS_Address *) address); 3070 return GAS_normalization_get_properties (NULL,
3062} 3071 address);
3063
3064
3065static void
3066set_updated_property ( struct ATS_Address *address, uint32_t type, double prop_rel)
3067{
3068 struct TestPeer *p;
3069 struct TestAddress *a;
3070
3071 if (NULL == (p = find_peer_by_pid (&address->peer)))
3072 {
3073 GNUNET_break (0);
3074 return;
3075 }
3076
3077 if (NULL == (a = find_address_by_ats_address (p, address)))
3078 {
3079 GNUNET_break (0);
3080 return;
3081 }
3082 a->prop_norm[type] = prop_rel;
3083 sh->env.sf.s_address_update_property (sh->solver, address, type, a->prop_abs [type], prop_rel);
3084}
3085
3086
3087static void
3088normalized_property_changed_cb (void *cls, struct ATS_Address *address,
3089 uint32_t type, double prop_rel)
3090{
3091 struct TestPeer *p;
3092 struct PreferenceGenerator *pg;
3093 struct GNUNET_TIME_Relative duration;
3094 uint32_t delta;
3095
3096 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
3097 "Normalized property %s for peer `%s' changed to %.3f \n",
3098 GNUNET_ATS_print_property_type (type), GNUNET_i2s (&address->peer),
3099 prop_rel);
3100
3101 if (NULL != (p = find_peer_by_pid (&address->peer)))
3102 {
3103 for (pg = pref_gen_head; NULL != pg; pg = pg->next)
3104 {
3105 if (pg->peer == p->id)
3106 {
3107 duration = GNUNET_TIME_absolute_get_duration(pg->feedback_last_delay_update);
3108 delta = duration.rel_value_us * pg->last_delay_value;
3109 pg->feedback_delay_acc += delta;
3110
3111 pg->last_delay_value = prop_rel;
3112 pg->feedback_last_bw_update = GNUNET_TIME_absolute_get();
3113 }
3114 }
3115
3116 }
3117
3118 set_updated_property (address, type, prop_rel);
3119}
3120
3121static void
3122set_updated_preference (const struct GNUNET_PeerIdentity *peer,
3123 enum GNUNET_ATS_PreferenceKind kind,
3124 double pref_rel)
3125{
3126 struct TestPeer *p;
3127
3128 if (NULL == (p = find_peer_by_pid (peer)))
3129 {
3130 GNUNET_break (0);
3131 return;
3132 }
3133
3134 p->pref_norm[kind] = pref_rel;
3135 sh->env.sf.s_pref (sh->solver, peer, kind, pref_rel);
3136}
3137
3138
3139static void
3140normalized_preference_changed_cb (void *cls,
3141 const struct GNUNET_PeerIdentity *peer,
3142 enum GNUNET_ATS_PreferenceKind kind,
3143 double pref_rel)
3144{
3145 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
3146 "Normalized preference %s for peer `%s' changed to %.3f \n",
3147 GNUNET_ATS_print_preference_type (kind), GNUNET_i2s (peer),
3148 pref_rel);
3149
3150 set_updated_preference(peer, kind, pref_rel);
3151} 3072}
3152 3073
3153 3074
@@ -3196,8 +3117,7 @@ GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
3196 3117
3197 3118
3198 /* start normalization */ 3119 /* start normalization */
3199 GAS_normalization_start (&normalized_preference_changed_cb, NULL, 3120 GAS_normalization_start ();
3200 &normalized_property_changed_cb, NULL );
3201 3121
3202 /* load quotas */ 3122 /* load quotas */
3203 if (GNUNET_ATS_NetworkTypeCount != GNUNET_ATS_solvers_load_quotas (e->cfg, 3123 if (GNUNET_ATS_NetworkTypeCount != GNUNET_ATS_solvers_load_quotas (e->cfg,
diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c
index 944db77f6..d54d09a33 100644
--- a/src/ats/gnunet-service-ats.c
+++ b/src/ats/gnunet-service-ats.c
@@ -17,7 +17,6 @@
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20
21/** 20/**
22 * @file ats/gnunet-service-ats.c 21 * @file ats/gnunet-service-ats.c
23 * @brief ats service 22 * @brief ats service
@@ -29,9 +28,12 @@
29#include "gnunet-service-ats.h" 28#include "gnunet-service-ats.h"
30#include "gnunet-service-ats_addresses.h" 29#include "gnunet-service-ats_addresses.h"
31#include "gnunet-service-ats_connectivity.h" 30#include "gnunet-service-ats_connectivity.h"
31#include "gnunet-service-ats_normalization.h"
32#include "gnunet-service-ats_performance.h" 32#include "gnunet-service-ats_performance.h"
33#include "gnunet-service-ats_preferences.h"
33#include "gnunet-service-ats_scheduling.h" 34#include "gnunet-service-ats_scheduling.h"
34#include "gnunet-service-ats_reservations.h" 35#include "gnunet-service-ats_reservations.h"
36#include "gnunet-service-ats_plugins.h"
35#include "ats.h" 37#include "ats.h"
36 38
37/** 39/**
@@ -108,6 +110,9 @@ client_disconnect_handler (void *cls,
108 return; 110 return;
109 GAS_scheduling_remove_client (client); 111 GAS_scheduling_remove_client (client);
110 GAS_performance_remove_client (client); 112 GAS_performance_remove_client (client);
113 GAS_connectivity_remove_client (client);
114 GAS_normalization_preference_client_disconnect (client);
115 GAS_addresses_preference_client_disconnect (client);
111} 116}
112 117
113 118
@@ -121,9 +126,13 @@ static void
121cleanup_task (void *cls, 126cleanup_task (void *cls,
122 const struct GNUNET_SCHEDULER_TaskContext *tc) 127 const struct GNUNET_SCHEDULER_TaskContext *tc)
123{ 128{
129 GAS_plugins_done ();
124 GAS_addresses_done (); 130 GAS_addresses_done ();
131 GAS_normalization_stop ();
125 GAS_scheduling_done (); 132 GAS_scheduling_done ();
133 GAS_connectivity_done ();
126 GAS_performance_done (); 134 GAS_performance_done ();
135 GAS_preference_done ();
127 GAS_reservations_done (); 136 GAS_reservations_done ();
128 GNUNET_SERVER_disconnect_notify_cancel (GSA_server, 137 GNUNET_SERVER_disconnect_notify_cancel (GSA_server,
129 &client_disconnect_handler, 138 &client_disconnect_handler,
@@ -180,10 +189,14 @@ run (void *cls,
180 GSA_server = server; 189 GSA_server = server;
181 GSA_stats = GNUNET_STATISTICS_create ("ats", cfg); 190 GSA_stats = GNUNET_STATISTICS_create ("ats", cfg);
182 GAS_reservations_init (); 191 GAS_reservations_init ();
192 GAS_normalization_start ();
193 GAS_addresses_init ();
183 if (GNUNET_OK != 194 if (GNUNET_OK !=
184 GAS_addresses_init (cfg, GSA_stats)) 195 GAS_plugins_init (cfg))
185 { 196 {
186 GNUNET_break (0); 197 GNUNET_break (0);
198 GAS_addresses_done ();
199 GAS_normalization_stop ();
187 GAS_reservations_done (); 200 GAS_reservations_done ();
188 if (NULL != GSA_stats) 201 if (NULL != GSA_stats)
189 { 202 {
@@ -196,10 +209,12 @@ run (void *cls,
196 GAS_scheduling_init (server); 209 GAS_scheduling_init (server);
197 210
198 GNUNET_SERVER_disconnect_notify (server, 211 GNUNET_SERVER_disconnect_notify (server,
199 &client_disconnect_handler, NULL); 212 &client_disconnect_handler,
213 NULL);
200 GNUNET_SERVER_add_handlers (server, handlers); 214 GNUNET_SERVER_add_handlers (server, handlers);
201 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 215 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
202 &cleanup_task, NULL); 216 &cleanup_task,
217 NULL);
203} 218}
204 219
205 220
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c
index 1d2c9d3e5..9ef6a3838 100644
--- a/src/ats/gnunet-service-ats_addresses.c
+++ b/src/ats/gnunet-service-ats_addresses.c
@@ -26,11 +26,11 @@
26 */ 26 */
27#include "platform.h" 27#include "platform.h"
28#include "gnunet_ats_service.h" 28#include "gnunet_ats_service.h"
29#include "gnunet_ats_plugin.h"
30#include "gnunet-service-ats.h" 29#include "gnunet-service-ats.h"
31#include "gnunet-service-ats_addresses.h" 30#include "gnunet-service-ats_addresses.h"
32#include "gnunet-service-ats_normalization.h" 31#include "gnunet-service-ats_normalization.h"
33#include "gnunet-service-ats_performance.h" 32#include "gnunet-service-ats_performance.h"
33#include "gnunet-service-ats_plugins.h"
34#include "gnunet-service-ats_scheduling.h" 34#include "gnunet-service-ats_scheduling.h"
35#include "gnunet-service-ats_reservations.h" 35#include "gnunet-service-ats_reservations.h"
36 36
@@ -216,110 +216,13 @@
216 */ 216 */
217 217
218 218
219/**
220 * Pending Address suggestion requests
221 */
222struct GAS_Addresses_Suggestion_Requests
223{
224 /**
225 * Next in DLL
226 */
227 struct GAS_Addresses_Suggestion_Requests *next;
228
229 /**
230 * Previous in DLL
231 */
232 struct GAS_Addresses_Suggestion_Requests *prev;
233
234 /**
235 * Peer ID
236 */
237 struct GNUNET_PeerIdentity id;
238};
239
240/**
241 * Pending Address suggestion requests
242 */
243struct GAS_Addresses_Preference_Clients
244{
245 /**
246 * Next in DLL
247 */
248 struct GAS_Addresses_Preference_Clients *next;
249
250 /**
251 * Previous in DLL
252 */
253 struct GAS_Addresses_Preference_Clients *prev;
254
255 /**
256 * Peer ID
257 */
258 void *client;
259};
260 219
261 220
262/** 221/**
263 *
264 */
265static struct GNUNET_STATISTICS_Handle *stats;
266
267/**
268 * A multihashmap to store all addresses 222 * A multihashmap to store all addresses
269 */ 223 */
270static struct GNUNET_CONTAINER_MultiPeerMap *addresses; 224struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses;
271 225
272/**
273 * Is ATS addresses running
274 */
275static int running;
276
277/**
278 * Preferences clients
279 */
280static int pref_clients;
281
282/**
283 * Configured ATS solver
284 */
285static int ats_mode;
286
287/**
288 * Solver handle
289 */
290static void *solver;
291
292/**
293 * Address suggestion requests DLL head.
294 * FIXME: This must become a Multipeermap! O(n) operations
295 * galore instead of O(1)!!!
296 */
297static struct GAS_Addresses_Suggestion_Requests *pending_requests_head;
298
299/**
300 * Address suggestion requests DLL tail
301 */
302static struct GAS_Addresses_Suggestion_Requests *pending_requests_tail;
303
304/**
305 * Preference requests DLL head
306 */
307static struct GAS_Addresses_Preference_Clients *preference_clients_head;
308
309/**
310 * Preference requests DLL head
311 */
312static struct GAS_Addresses_Preference_Clients *preference_clients_tail;
313
314/**
315 * Solver functions
316 */
317static struct GNUNET_ATS_PluginEnvironment env;
318
319/**
320 * Solver plugin name as string
321 */
322static char *plugin;
323 226
324/** 227/**
325 * Value we pass for zero bandwidth. 228 * Value we pass for zero bandwidth.
@@ -613,7 +516,7 @@ find_equivalent_address (const struct GNUNET_PeerIdentity *peer,
613 cac.exact_address = NULL; 516 cac.exact_address = NULL;
614 cac.base_address = NULL; 517 cac.base_address = NULL;
615 cac.search = addr; 518 cac.search = addr;
616 GNUNET_CONTAINER_multipeermap_get_multiple (addresses, 519 GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses,
617 peer, 520 peer,
618 &compare_address_it, &cac); 521 &compare_address_it, &cac);
619 522
@@ -681,7 +584,7 @@ find_exact_address (const struct GNUNET_PeerIdentity *peer,
681 584
682 fac.exact_address = NULL; 585 fac.exact_address = NULL;
683 fac.session_id = session_id; 586 fac.session_id = session_id;
684 GNUNET_CONTAINER_multipeermap_get_multiple (addresses, 587 GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses,
685 peer, 588 peer,
686 &find_address_cb, &fac); 589 &find_address_cb, &fac);
687 return fac.exact_address; 590 return fac.exact_address;
@@ -689,38 +592,6 @@ find_exact_address (const struct GNUNET_PeerIdentity *peer,
689 592
690 593
691/** 594/**
692 * Function allowing the solver to obtain normalized preference
693 * values from solver
694 *
695 * @param cls unused
696 * @param id the peer to return the normalized properties for
697 * @return array of double values with |GNUNET_ATS_PreferenceCount| elements
698 */
699const double *
700get_preferences_cb (void *cls,
701 const struct GNUNET_PeerIdentity *id)
702{
703 return GAS_normalization_get_preferences_by_peer (id);
704}
705
706
707/**
708 * Function allowing the solver to obtain normalized property
709 * values for an address from solver
710 *
711 * @param cls unused
712 * @param address the address
713 * @return array of double values with |GNUNET_ATS_QualityPropertiesCount| elements
714 */
715const double *
716get_property_cb (void *cls,
717 const struct ATS_Address *address)
718{
719 return GAS_normalization_get_properties (address);
720}
721
722
723/**
724 * Extract an ATS performance info from an address 595 * Extract an ATS performance info from an address
725 * 596 *
726 * @param address the address 597 * @param address the address
@@ -772,18 +643,11 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
772 struct GNUNET_ATS_Information *atsi_delta; 643 struct GNUNET_ATS_Information *atsi_delta;
773 uint32_t atsi_delta_count; 644 uint32_t atsi_delta_count;
774 uint32_t addr_net; 645 uint32_t addr_net;
775 uint32_t previous_session;
776 int c1;
777 646
778 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 647 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
779 "Received `%s' for peer `%s'\n", 648 "Received `%s' for peer `%s'\n",
780 "ADDRESS ADD", 649 "ADDRESS ADD",
781 GNUNET_i2s (peer)); 650 GNUNET_i2s (peer));
782 if (GNUNET_NO == running)
783 {
784 GNUNET_break (0);
785 return;
786 }
787 new_address = create_address (peer, 651 new_address = create_address (peer,
788 plugin_name, 652 plugin_name,
789 plugin_addr, 653 plugin_addr,
@@ -802,127 +666,51 @@ GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
802 666
803 /* Get existing address or address with session == 0 */ 667 /* Get existing address or address with session == 0 */
804 existing_address = find_equivalent_address (peer, new_address); 668 existing_address = find_equivalent_address (peer, new_address);
805 if (NULL == existing_address) 669 if (NULL != existing_address)
806 { 670 {
807 /* Add a new address */ 671 GNUNET_break (0);
808 new_address->t_added = GNUNET_TIME_absolute_get(); 672 GNUNET_free(new_address->plugin);
809 new_address->t_last_activity = GNUNET_TIME_absolute_get(); 673 GNUNET_free_non_null(new_address->atsi);
810 GNUNET_assert(GNUNET_OK == 674 GNUNET_free(new_address);
811 GNUNET_CONTAINER_multipeermap_put (addresses,
812 peer,
813 new_address,
814 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
815
816 GNUNET_STATISTICS_set (stats,
817 "# addresses",
818 GNUNET_CONTAINER_multipeermap_size (addresses),
819 GNUNET_NO);
820
821 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
822 "Adding new address %p for peer `%s', length %u, session id %u, %s\n",
823 new_address,
824 GNUNET_i2s (peer),
825 plugin_addr_len,
826 session_id,
827 GNUNET_ATS_print_network_type (addr_net));
828
829 /* Tell solver about new address */
830 env.sf.s_add (solver, new_address, addr_net);
831
832 env.sf.s_bulk_start (solver);
833 GAS_normalization_normalize_property (addresses,
834 new_address,
835 atsi,
836 atsi_count);
837 env.sf.s_bulk_stop (solver);
838
839 /* Notify performance clients about new address */
840 GAS_performance_notify_all_clients (&new_address->peer, new_address->plugin,
841 new_address->addr, new_address->addr_len, new_address->active,
842 new_address->atsi, new_address->atsi_count,
843 GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_out),
844 GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_in));
845 return;
846 }
847
848 /* FIXME: this case should probably not be allowed... */
849 /* We have an existing address we can use, clean up new */
850 GNUNET_free(new_address->plugin);
851 GNUNET_free_non_null(new_address->atsi);
852 GNUNET_free(new_address);
853 new_address = NULL;
854
855 if (0 != existing_address->session_id)
856 {
857 /* Should not happen */
858 GNUNET_break(0);
859 return; 675 return;
860 } 676 }
861 677 /* Add a new address */
862 addr_net = get_performance_info (existing_address, GNUNET_ATS_NETWORK_TYPE); 678 new_address->t_added = GNUNET_TIME_absolute_get();
863 if (GNUNET_ATS_VALUE_UNDEFINED == addr_net) 679 new_address->t_last_activity = GNUNET_TIME_absolute_get();
864 addr_net = GNUNET_ATS_NET_UNSPECIFIED; 680 GNUNET_assert(GNUNET_OK ==
865 681 GNUNET_CONTAINER_multipeermap_put (GSA_addresses,
866 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 682 peer,
867 "Found existing address for peer `%s' %p with new session %u in network %s\n", 683 new_address,
868 GNUNET_i2s (peer), existing_address, session_id, 684 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
869 GNUNET_ATS_print_network_type (addr_net)); 685
870 /* We have an address without an session, update this address */ 686 GNUNET_STATISTICS_set (GSA_stats,
871 existing_address->t_added = GNUNET_TIME_absolute_get(); 687 "# addresses",
872 existing_address->t_last_activity = GNUNET_TIME_absolute_get(); 688 GNUNET_CONTAINER_multipeermap_size (GSA_addresses),
873 atsi_delta = NULL; 689 GNUNET_NO);
874 atsi_delta_count = 0; 690
875 if (GNUNET_YES 691 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
876 == disassemble_ats_information (existing_address, atsi, atsi_count, 692 "Adding new address %p for peer `%s', length %u, session id %u, %s\n",
877 &atsi_delta, &atsi_delta_count)) 693 new_address,
878 { 694 GNUNET_i2s (peer),
879 /* Notify performance clients about properties */ 695 plugin_addr_len,
880 GAS_performance_notify_all_clients (&existing_address->peer, 696 session_id,
881 existing_address->plugin, existing_address->addr, 697 GNUNET_ATS_print_network_type (addr_net));
882 existing_address->addr_len, existing_address->active, 698
883 existing_address->atsi, existing_address->atsi_count, 699 /* Tell solver about new address */
884 GNUNET_BANDWIDTH_value_init (existing_address->assigned_bw_out), 700 GAS_plugin_new_address (new_address,
885 GNUNET_BANDWIDTH_value_init (existing_address->assigned_bw_in)); 701 addr_net,
886 702 atsi,
887 for (c1 = 0; c1 < atsi_delta_count; c1++) 703 atsi_count);
888 { 704 /* Notify performance clients about new address */
889 if ((GNUNET_ATS_NETWORK_TYPE == ntohl (atsi_delta[c1].type)) 705 GAS_performance_notify_all_clients (&new_address->peer,
890 && (addr_net != ntohl (atsi_delta[c1].value))) 706 new_address->plugin,
891 { 707 new_address->addr,
892 /* Network type changed */ 708 new_address->addr_len,
893 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 709 new_address->active,
894 "Address for peer `%s' %p changed from network %s to %s\n", 710 new_address->atsi,
895 GNUNET_i2s (peer), existing_address, 711 new_address->atsi_count,
896 GNUNET_ATS_print_network_type (addr_net), 712 GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_out),
897 GNUNET_ATS_print_network_type (ntohl (atsi_delta[c1].value))); 713 GNUNET_BANDWIDTH_value_init (new_address->assigned_bw_in));
898 env.sf.s_address_update_network (solver, existing_address,
899 ntohl (atsi_delta[c1].value),
900 get_performance_info (existing_address, GNUNET_ATS_NETWORK_TYPE));
901 addr_net = get_performance_info (existing_address,
902 GNUNET_ATS_NETWORK_TYPE);
903 }
904 }
905 /* Notify solver about update with atsi information and session */
906 env.sf.s_bulk_start (solver);
907 GAS_normalization_normalize_property (addresses, existing_address,
908 atsi, atsi_count);
909 env.sf.s_bulk_stop (solver);
910 }
911 GNUNET_free_non_null(atsi_delta);
912
913 /* Notify solver about new session */
914 if (existing_address->session_id == session_id)
915 return; /* possible, can both be 0 since address is revalidated */
916
917 previous_session = existing_address->session_id;
918 existing_address->session_id = session_id;
919 env.sf.s_address_update_session (solver, existing_address,
920 previous_session, session_id);
921
922 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
923 "Updated existing address for peer `%s' %p length %u with new session %u in network %s\n",
924 GNUNET_i2s (peer), existing_address, existing_address->addr_len,
925 session_id, GNUNET_ATS_print_network_type (addr_net));
926} 714}
927 715
928 716
@@ -943,12 +731,6 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
943 struct ATS_Address *aa; 731 struct ATS_Address *aa;
944 struct GNUNET_ATS_Information *atsi_delta; 732 struct GNUNET_ATS_Information *atsi_delta;
945 uint32_t atsi_delta_count; 733 uint32_t atsi_delta_count;
946 uint32_t prev_session;
947 int c1;
948
949 if (GNUNET_NO == running)
950 return;
951 GNUNET_assert (NULL != addresses);
952 734
953 /* Get existing address */ 735 /* Get existing address */
954 aa = find_exact_address (peer, 736 aa = find_exact_address (peer,
@@ -963,7 +745,6 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
963 GNUNET_break (0); 745 GNUNET_break (0);
964 return; 746 return;
965 } 747 }
966
967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 748 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
968 "Received `%s' for peer `%s' address \n", 749 "Received `%s' for peer `%s' address \n",
969 "ADDRESS UPDATE", 750 "ADDRESS UPDATE",
@@ -972,17 +753,6 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
972 753
973 /* Update address */ 754 /* Update address */
974 aa->t_last_activity = GNUNET_TIME_absolute_get(); 755 aa->t_last_activity = GNUNET_TIME_absolute_get();
975 if (session_id != aa->session_id)
976 {
977 /* Session changed */
978 prev_session = aa->session_id;
979 aa->session_id = session_id;
980 env.sf.s_address_update_session (solver,
981 aa,
982 prev_session,
983 aa->session_id);
984 }
985
986 atsi_delta = NULL; 756 atsi_delta = NULL;
987 atsi_delta_count = 0; 757 atsi_delta_count = 0;
988 if (GNUNET_YES == 758 if (GNUNET_YES ==
@@ -991,30 +761,20 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
991 &atsi_delta, 761 &atsi_delta,
992 &atsi_delta_count)) 762 &atsi_delta_count))
993 { 763 {
994 /* ATS properties changed */
995 for (c1 = 0; c1 < atsi_delta_count; c1++)
996 {
997 if (GNUNET_ATS_NETWORK_TYPE == ntohl (atsi_delta[c1].type))
998 {
999 /* Network type changed */
1000 env.sf.s_address_update_network (solver, aa,
1001 ntohl (atsi_delta[c1].value),
1002 get_performance_info (aa, GNUNET_ATS_NETWORK_TYPE));
1003 }
1004 }
1005
1006 /* Notify performance clients about updated address */ 764 /* Notify performance clients about updated address */
1007 GAS_performance_notify_all_clients (&aa->peer, aa->plugin, aa->addr, 765 GAS_performance_notify_all_clients (&aa->peer,
1008 aa->addr_len, aa->active, aa->atsi, aa->atsi_count, 766 aa->plugin,
1009 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out), 767 aa->addr,
1010 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in)); 768 aa->addr_len,
1011 769 aa->active,
1012 env.sf.s_bulk_start (solver); 770 aa->atsi,
1013 GAS_normalization_normalize_property (addresses, 771 aa->atsi_count,
1014 aa, 772 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out),
1015 atsi, 773 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in));
1016 atsi_count); 774
1017 env.sf.s_bulk_stop (solver); 775 GAS_plugin_update_address (aa,
776 atsi,
777 atsi_count);
1018 } 778 }
1019 GNUNET_free_non_null (atsi_delta); 779 GNUNET_free_non_null (atsi_delta);
1020} 780}
@@ -1032,9 +792,6 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
1032{ 792{
1033 struct ATS_Address *ea; 793 struct ATS_Address *ea;
1034 794
1035 if (GNUNET_NO == running)
1036 return;
1037
1038 /* Get existing address */ 795 /* Get existing address */
1039 ea = find_exact_address (peer, 796 ea = find_exact_address (peer,
1040 session_id); 797 session_id);
@@ -1054,11 +811,10 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
1054 GNUNET_i2s (peer), 811 GNUNET_i2s (peer),
1055 ea, 812 ea,
1056 session_id); 813 session_id);
1057 GNUNET_CONTAINER_multipeermap_remove (addresses, 814 GNUNET_CONTAINER_multipeermap_remove (GSA_addresses,
1058 peer, 815 peer,
1059 ea); 816 ea);
1060 817 GAS_plugin_delete_address (ea);
1061 env.sf.s_del (solver, ea, GNUNET_NO);
1062 GAS_performance_notify_all_clients (peer, 818 GAS_performance_notify_all_clients (peer,
1063 ea->plugin, 819 ea->plugin,
1064 ea->addr, 820 ea->addr,
@@ -1068,607 +824,14 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
1068 zero_bw, 824 zero_bw,
1069 zero_bw); 825 zero_bw);
1070 free_address (ea); 826 free_address (ea);
1071 GNUNET_STATISTICS_set (stats, 827 GNUNET_STATISTICS_set (GSA_stats,
1072 "# addresses", 828 "# addresses",
1073 GNUNET_CONTAINER_multipeermap_size (addresses), 829 GNUNET_CONTAINER_multipeermap_size (GSA_addresses),
1074 GNUNET_NO); 830 GNUNET_NO);
1075} 831}
1076 832
1077 833
1078/**
1079 * Cancel address suggestions for a peer
1080 *
1081 * @param peer the peer id
1082 */
1083void
1084GAS_addresses_request_address_cancel (const struct GNUNET_PeerIdentity *peer)
1085{
1086 struct GAS_Addresses_Suggestion_Requests *cur = pending_requests_head;
1087
1088 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1089 "Received request: `%s' for peer %s\n",
1090 "request_address_cancel",
1091 GNUNET_i2s (peer));
1092
1093 while (NULL != cur)
1094 {
1095 if (0 == memcmp (peer, &cur->id, sizeof(cur->id)))
1096 break; /* found */
1097 cur = cur->next;
1098 }
1099
1100 if (NULL == cur)
1101 {
1102 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1103 "No address requests pending for peer `%s', cannot remove!\n",
1104 GNUNET_i2s (peer));
1105 return;
1106 }
1107 env.sf.s_get_stop (solver, peer);
1108 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1109 "Removed request pending for peer `%s\n",
1110 GNUNET_i2s (peer));
1111 GNUNET_CONTAINER_DLL_remove (pending_requests_head,
1112 pending_requests_tail,
1113 cur);
1114 GNUNET_free(cur);
1115}
1116
1117
1118/**
1119 * Request address suggestions for a peer
1120 *
1121 * @param peer the peer id
1122 */
1123void
1124GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer)
1125{
1126 struct GAS_Addresses_Suggestion_Requests *cur = pending_requests_head;
1127 struct ATS_Address *aa;
1128
1129 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1130 "Received `%s' for peer `%s'\n",
1131 "REQUEST ADDRESS",
1132 GNUNET_i2s (peer));
1133
1134 if (GNUNET_NO == running)
1135 return;
1136 while (NULL != cur)
1137 {
1138 if (0 == memcmp (peer, &cur->id, sizeof(cur->id)))
1139 break; /* already suggesting */
1140 cur = cur->next;
1141 }
1142 if (NULL == cur)
1143 {
1144 cur = GNUNET_new (struct GAS_Addresses_Suggestion_Requests);
1145 cur->id = *peer;
1146 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1147 "Adding new address suggestion request for `%s'\n",
1148 GNUNET_i2s (peer));
1149 GNUNET_CONTAINER_DLL_insert (pending_requests_head,
1150 pending_requests_tail,
1151 cur);
1152 }
1153
1154 /* Get prefered address from solver */
1155 aa = (struct ATS_Address *) env.sf.s_get (solver, peer);
1156 if (NULL == aa)
1157 {
1158 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Cannot suggest address for peer `%s'\n",
1159 GNUNET_i2s (peer));
1160 return;
1161 }
1162
1163 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Suggesting address %p for peer `%s'\n",
1164 aa, GNUNET_i2s (peer));
1165
1166 GAS_scheduling_transmit_address_suggestion (peer,
1167 aa->session_id,
1168 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out),
1169 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in));
1170
1171 aa->block_interval = GNUNET_TIME_relative_add (aa->block_interval,
1172 ATS_BLOCKING_DELTA);
1173 aa->blocked_until = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
1174 aa->block_interval);
1175
1176 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1177 "Address %p ready for suggestion, block interval now %llu \n", aa,
1178 aa->block_interval);
1179}
1180
1181
1182/**
1183 * Solver information callback
1184 *
1185 * @param cls the closure
1186 * @param op the operation
1187 * @param status operation status
1188 * @param add additional information
1189 */
1190static void
1191solver_info_cb (void *cls,
1192 enum GAS_Solver_Operation op,
1193 enum GAS_Solver_Status status,
1194 enum GAS_Solver_Additional_Information add)
1195{
1196 char *add_info;
1197
1198 switch (add) {
1199 case GAS_INFO_NONE:
1200 add_info = "GAS_INFO_NONE";
1201 break;
1202 case GAS_INFO_FULL:
1203 add_info = "GAS_INFO_MLP_FULL";
1204 break;
1205 case GAS_INFO_UPDATED:
1206 add_info = "GAS_INFO_MLP_UPDATED";
1207 break;
1208 case GAS_INFO_PROP_ALL:
1209 add_info = "GAS_INFO_PROP_ALL";
1210 break;
1211 case GAS_INFO_PROP_SINGLE:
1212 add_info = "GAS_INFO_PROP_SINGLE";
1213 break;
1214 default:
1215 add_info = "INVALID";
1216 break;
1217 }
1218 switch (op)
1219 {
1220 case GAS_OP_SOLVE_START:
1221 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1222 "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
1223 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL", add_info);
1224 return;
1225 case GAS_OP_SOLVE_STOP:
1226 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1227 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
1228 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL", add_info);
1229 return;
1230
1231 case GAS_OP_SOLVE_SETUP_START:
1232 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1233 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
1234 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
1235 return;
1236
1237 case GAS_OP_SOLVE_SETUP_STOP:
1238 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1239 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
1240 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
1241 return;
1242
1243 case GAS_OP_SOLVE_MLP_LP_START:
1244 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1245 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
1246 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
1247 return;
1248 case GAS_OP_SOLVE_MLP_LP_STOP:
1249 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1250 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
1251 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
1252 return;
1253
1254 case GAS_OP_SOLVE_MLP_MLP_START:
1255 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1256 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
1257 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
1258 return;
1259 case GAS_OP_SOLVE_MLP_MLP_STOP:
1260 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1261 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
1262 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
1263 return;
1264 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
1265 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1266 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
1267 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
1268 return;
1269 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
1270 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1271 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
1272 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
1273 return;
1274 default:
1275 break;
1276 }
1277}
1278
1279
1280/**
1281 * The preference changed for a peer
1282 *
1283 * @param cls NULL
1284 * @param peer the peer
1285 * @param kind the ATS kind
1286 * @param pref_rel the new relative preference value
1287 */
1288static void
1289normalized_preference_changed_cb (void *cls,
1290 const struct GNUNET_PeerIdentity *peer,
1291 enum GNUNET_ATS_PreferenceKind kind,
1292 double pref_rel)
1293{
1294 /* Tell solver about update */
1295 env.sf.s_pref (solver, peer, kind, pref_rel);
1296}
1297
1298
1299/**
1300 * The relative value for a property changed
1301 *
1302 * @param cls NULL
1303 * @param address the peer
1304 * @param type the ATS type
1305 * @param prop_rel the new relative preference value
1306 */
1307static void
1308normalized_property_changed_cb (void *cls,
1309 struct ATS_Address *address,
1310 uint32_t type,
1311 double prop_rel)
1312{
1313 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1314 "Normalized property %s for peer `%s' changed to %.3f \n",
1315 GNUNET_ATS_print_property_type (type),
1316 GNUNET_i2s (&address->peer),
1317 prop_rel);
1318 env.sf.s_address_update_property (solver,
1319 address,
1320 type,
1321 0,
1322 prop_rel);
1323}
1324
1325
1326static struct GAS_Addresses_Preference_Clients *
1327find_preference_client (void *client)
1328{
1329 struct GAS_Addresses_Preference_Clients *cur;
1330 834
1331 for (cur = preference_clients_head; NULL != cur; cur = cur->next)
1332 if (cur->client == client)
1333 return cur;
1334 return NULL;
1335}
1336
1337
1338/**
1339 * A performance client disconnected
1340 *
1341 * @param client the client
1342 */
1343void
1344GAS_addresses_preference_client_disconnect (void *client)
1345{
1346 struct GAS_Addresses_Preference_Clients *pc;
1347
1348 if (NULL != (pc = find_preference_client (client)))
1349 {
1350 GNUNET_CONTAINER_DLL_remove (preference_clients_head,
1351 preference_clients_tail,
1352 pc);
1353 GNUNET_free (pc);
1354 GNUNET_assert (pref_clients > 0);
1355 pref_clients --;
1356 GNUNET_STATISTICS_set (stats,
1357 "# active performance clients",
1358 pref_clients,
1359 GNUNET_NO);
1360 }
1361 GAS_normalization_preference_client_disconnect (client);
1362}
1363
1364
1365/**
1366 * Change the preference for a peer
1367 *
1368 * @param client the client sending this request
1369 * @param peer the peer id
1370 * @param kind the preference kind to change
1371 * @param score_abs the new preference score
1372 */
1373void
1374GAS_addresses_preference_change (void *client,
1375 const struct GNUNET_PeerIdentity *peer,
1376 enum GNUNET_ATS_PreferenceKind kind,
1377 float score_abs)
1378{
1379 struct GAS_Addresses_Preference_Clients *pc;
1380
1381 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1382 "Received `%s' for peer `%s' for client %p\n", "CHANGE PREFERENCE",
1383 GNUNET_i2s (peer), client);
1384
1385 if (GNUNET_NO == running)
1386 return;
1387
1388 if (GNUNET_NO ==
1389 GNUNET_CONTAINER_multipeermap_contains (addresses,
1390 peer))
1391 {
1392 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1393 "Received `%s' for unknown peer `%s' from client %p\n",
1394 "CHANGE PREFERENCE", GNUNET_i2s (peer), client);
1395 return;
1396 }
1397
1398 if (NULL == find_preference_client (client))
1399 {
1400 pc = GNUNET_new (struct GAS_Addresses_Preference_Clients);
1401 pc->client = client;
1402 GNUNET_CONTAINER_DLL_insert (preference_clients_head,
1403 preference_clients_tail,
1404 pc);
1405 pref_clients ++;
1406 GNUNET_STATISTICS_set (stats,
1407 "# active performance clients",
1408 pref_clients,
1409 GNUNET_NO);
1410 }
1411
1412 env.sf.s_bulk_start (solver);
1413 /* Tell normalization about change, normalization will call callback if preference changed */
1414 GAS_normalization_normalize_preference (client, peer, kind, score_abs);
1415 env.sf.s_bulk_stop (solver);
1416}
1417
1418
1419/**
1420 * Change the preference for a peer
1421 *
1422 * @param application the client sending this request
1423 * @param peer the peer id
1424 * @param scope the time interval for this feedback: [now - scope .. now]
1425 * @param kind the preference kind to change
1426 * @param score_abs the new preference score
1427 */
1428void
1429GAS_addresses_preference_feedback (void *application,
1430 const struct GNUNET_PeerIdentity *peer,
1431 const struct GNUNET_TIME_Relative scope,
1432 enum GNUNET_ATS_PreferenceKind kind,
1433 float score_abs)
1434{
1435 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1436 "Received `%s' for peer `%s' for client %p\n",
1437 "PREFERENCE FEEDBACK",
1438 GNUNET_i2s (peer),
1439 application);
1440
1441 if (GNUNET_NO == running)
1442 return;
1443
1444 if (GNUNET_NO ==
1445 GNUNET_CONTAINER_multipeermap_contains (addresses,
1446 peer))
1447 {
1448 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1449 "Received `%s' for unknown peer `%s' from client %p\n",
1450 "PREFERENCE FEEDBACK", GNUNET_i2s (peer), application);
1451 return;
1452 }
1453
1454 env.sf.s_feedback (solver, application, peer, scope, kind,
1455 score_abs);
1456}
1457
1458
1459/**
1460 * Load quotas for networks from configuration
1461 *
1462 * @param cfg configuration handle
1463 * @param out_dest where to write outbound quotas
1464 * @param in_dest where to write inbound quotas
1465 * @param dest_length length of inbound and outbound arrays
1466 * @return number of networks loaded
1467 */
1468static unsigned int
1469load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
1470 unsigned long long *out_dest, unsigned long long *in_dest, int dest_length)
1471{
1472 char * entry_in = NULL;
1473 char * entry_out = NULL;
1474 char * quota_out_str;
1475 char * quota_in_str;
1476 int c;
1477 int res;
1478
1479 for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
1480 {
1481 in_dest[c] = 0;
1482 out_dest[c] = 0;
1483 GNUNET_asprintf (&entry_out,
1484 "%s_QUOTA_OUT",
1485 GNUNET_ATS_print_network_type (c));
1486 GNUNET_asprintf (&entry_in,
1487 "%s_QUOTA_IN",
1488 GNUNET_ATS_print_network_type (c));
1489
1490 /* quota out */
1491 if (GNUNET_OK
1492 == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", entry_out,
1493 &quota_out_str))
1494 {
1495 res = GNUNET_NO;
1496 if (0 == strcmp (quota_out_str, GNUNET_ATS_MaxBandwidthString))
1497 {
1498 out_dest[c] = GNUNET_ATS_MaxBandwidth;
1499 res = GNUNET_YES;
1500 }
1501 if ((GNUNET_NO == res)
1502 && (GNUNET_OK
1503 == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str,
1504 &out_dest[c])))
1505 res = GNUNET_YES;
1506 if ((GNUNET_NO == res)
1507 && (GNUNET_OK
1508 == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out,
1509 &out_dest[c])))
1510 res = GNUNET_YES;
1511
1512 if (GNUNET_NO == res)
1513 {
1514 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1515 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
1516 GNUNET_ATS_print_network_type (c),
1517 quota_out_str,
1518 GNUNET_ATS_DefaultBandwidth);
1519 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
1520 }
1521 else
1522 {
1523 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1524 _("Outbound quota configure for network `%s' is %llu\n"),
1525 GNUNET_ATS_print_network_type (c),
1526 out_dest[c]);
1527 }
1528 GNUNET_free(quota_out_str);
1529 }
1530 else
1531 {
1532 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1533 _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
1534 GNUNET_ATS_print_network_type (c),
1535 GNUNET_ATS_DefaultBandwidth);
1536 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
1537 }
1538
1539 /* quota in */
1540 if (GNUNET_OK
1541 == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", entry_in,
1542 &quota_in_str))
1543 {
1544 res = GNUNET_NO;
1545 if (0 == strcmp (quota_in_str, GNUNET_ATS_MaxBandwidthString))
1546 {
1547 in_dest[c] = GNUNET_ATS_MaxBandwidth;
1548 res = GNUNET_YES;
1549 }
1550 if ((GNUNET_NO == res)
1551 && (GNUNET_OK
1552 == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
1553 res = GNUNET_YES;
1554 if ((GNUNET_NO == res)
1555 && (GNUNET_OK
1556 == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in,
1557 &in_dest[c])))
1558 res = GNUNET_YES;
1559
1560 if (GNUNET_NO == res)
1561 {
1562 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1563 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
1564 GNUNET_ATS_print_network_type (c),
1565 quota_in_str,
1566 GNUNET_ATS_DefaultBandwidth);
1567 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
1568 }
1569 else
1570 {
1571 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1572 _("Inbound quota configured for network `%s' is %llu\n"),
1573 GNUNET_ATS_print_network_type (c),
1574 in_dest[c]);
1575 }
1576 GNUNET_free(quota_in_str);
1577 }
1578 else
1579 {
1580 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1581 _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
1582 GNUNET_ATS_print_network_type (c),
1583 GNUNET_ATS_DefaultBandwidth);
1584 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
1585 }
1586 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1587 "Loaded quota for network `%s' (in/out): %llu %llu\n",
1588 GNUNET_ATS_print_network_type (c),
1589 in_dest[c],
1590 out_dest[c]);
1591 GNUNET_free(entry_out);
1592 GNUNET_free(entry_in);
1593 }
1594 return GNUNET_ATS_NetworkTypeCount;
1595}
1596
1597
1598/**
1599 * Callback for solver to notify about assignment changes
1600 *
1601 * @param cls NULL
1602 * @param address the address with changes
1603 */
1604static void
1605bandwidth_changed_cb (void *cls, struct ATS_Address *address)
1606{
1607 struct GAS_Addresses_Suggestion_Requests *cur;
1608 uint32_t diff_out;
1609 uint32_t diff_in;
1610
1611 GNUNET_assert(address != NULL);
1612 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1613 "Bandwidth assignment changed for peer %s \n",
1614 GNUNET_i2s (&address->peer));
1615
1616 /* Notify performance clients about changes to address */
1617 GAS_performance_notify_all_clients (&address->peer, address->plugin,
1618 address->addr, address->addr_len, address->active, address->atsi,
1619 address->atsi_count,
1620 GNUNET_BANDWIDTH_value_init (address->assigned_bw_out),
1621 GNUNET_BANDWIDTH_value_init (address->assigned_bw_in));
1622
1623 for (cur = pending_requests_head;NULL != cur; cur = cur->next)
1624 if (0 == memcmp (&address->peer,
1625 &cur->id,
1626 sizeof(cur->id)))
1627 break; /* we have an address request pending*/
1628 if (NULL == cur)
1629 {
1630 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1631 "Nobody is interested in peer `%s' :(\n",
1632 GNUNET_i2s (&address->peer));
1633 return;
1634 }
1635
1636 if ((0 == address->assigned_bw_in) && (0 == address->assigned_bw_out))
1637 {
1638 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1639 "Telling transport to disconnect peer `%s'\n",
1640 GNUNET_i2s (&address->peer));
1641
1642 /* Notify scheduling clients about suggestion */
1643 GAS_scheduling_transmit_address_suggestion (&address->peer,
1644 address->session_id,
1645 zero_bw,
1646 zero_bw);
1647 return;
1648 }
1649
1650 /* Do bandwidth stability check */
1651 diff_out = abs (address->assigned_bw_out - address->last_notified_bw_out);
1652 diff_in = abs (address->assigned_bw_in - address->last_notified_bw_in);
1653
1654 if ( (diff_out < htonl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) &&
1655 (diff_in < htonl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) )
1656 return;
1657
1658 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1659 "Sending bandwidth update for peer `%s': %u %u\n",
1660 GNUNET_i2s (&address->peer), address->assigned_bw_out,
1661 address->assigned_bw_out);
1662
1663 /* *Notify scheduling clients about suggestion */
1664 GAS_scheduling_transmit_address_suggestion (&address->peer,
1665 address->session_id,
1666 GNUNET_BANDWIDTH_value_init (address->assigned_bw_out),
1667 GNUNET_BANDWIDTH_value_init (address->assigned_bw_in));
1668
1669 address->last_notified_bw_out = address->assigned_bw_out;
1670 address->last_notified_bw_in = address->assigned_bw_in;
1671}
1672 835
1673 836
1674/** 837/**
@@ -1676,146 +839,16 @@ bandwidth_changed_cb (void *cls, struct ATS_Address *address)
1676 * known and current performance information. It has a solver component 839 * known and current performance information. It has a solver component
1677 * responsible for the resource allocation. It tells the solver about changes 840 * responsible for the resource allocation. It tells the solver about changes
1678 * and receives updates when the solver changes the resource allocation. 841 * and receives updates when the solver changes the resource allocation.
1679 *
1680 * @param cfg configuration to use
1681 * @param stats_ the statistics handle to use
1682 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load
1683 * solver plugin)
1684 */ 842 */
1685int 843void
1686GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, 844GAS_addresses_init ()
1687 struct GNUNET_STATISTICS_Handle *stats_)
1688{ 845{
1689 unsigned long long quotas_in[GNUNET_ATS_NetworkTypeCount];
1690 unsigned long long quotas_out[GNUNET_ATS_NetworkTypeCount];
1691 char *mode_str;
1692 char *plugin_short;
1693 int c;
1694
1695 running = GNUNET_NO;
1696 stats = stats_;
1697 /* Initialize the addresses database */ 846 /* Initialize the addresses database */
1698 addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO); 847 GSA_addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
1699 pref_clients = 0; 848 GNUNET_STATISTICS_set (GSA_stats,
1700
1701 /* Figure out configured solution method */
1702 if (GNUNET_SYSERR ==
1703 GNUNET_CONFIGURATION_get_value_string (cfg, "ats", "MODE", &mode_str))
1704 {
1705 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1706 "No resource assignment method configured, using proportional approach\n");
1707 ats_mode = MODE_PROPORTIONAL;
1708 }
1709 else
1710 {
1711 for (c = 0; c < strlen (mode_str); c++)
1712 mode_str[c] = toupper (mode_str[c]);
1713 if (0 == strcmp (mode_str, "PROPORTIONAL"))
1714 ats_mode = MODE_PROPORTIONAL;
1715 else if (0 == strcmp (mode_str, "MLP"))
1716 {
1717 ats_mode = MODE_MLP;
1718#if !HAVE_LIBGLPK
1719 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1720 "Assignment method `%s' configured, but GLPK is not available, please install \n",
1721 mode_str);
1722 ats_mode = MODE_PROPORTIONAL;
1723#endif
1724 }
1725 else if (0 == strcmp (mode_str, "RIL"))
1726 ats_mode = MODE_RIL;
1727 else
1728 {
1729 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1730 "Invalid resource assignment method `%s' configured, using proportional approach\n",
1731 mode_str);
1732 ats_mode = MODE_PROPORTIONAL;
1733 }
1734 GNUNET_free(mode_str);
1735 }
1736
1737 load_quotas (cfg, quotas_out, quotas_in, GNUNET_ATS_NetworkTypeCount);
1738 env.info_cb = &solver_info_cb;
1739 env.info_cb_cls = NULL;
1740 env.bandwidth_changed_cb = &bandwidth_changed_cb;
1741 env.bw_changed_cb_cls = NULL;
1742 env.get_preferences = &get_preferences_cb;
1743 env.get_preference_cls = NULL;
1744 env.get_property = &get_property_cb;
1745 env.get_property_cls = NULL;
1746 env.cfg = cfg;
1747 env.stats = stats;
1748 env.addresses = addresses;
1749
1750 env.network_count = GNUNET_ATS_NetworkTypeCount;
1751 int networks[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
1752 for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
1753 {
1754 env.networks[c] = networks[c];
1755 env.out_quota[c] = quotas_out[c];
1756 env.in_quota[c] = quotas_in[c];
1757 }
1758
1759 switch (ats_mode) {
1760 case MODE_PROPORTIONAL:
1761 plugin_short = "proportional";
1762 break;
1763 case MODE_MLP:
1764 plugin_short = "mlp";
1765 break;
1766 case MODE_RIL:
1767 plugin_short = "ril";
1768 break;
1769 default:
1770 plugin_short = NULL;
1771 break;
1772 }
1773 GNUNET_asprintf (&plugin,
1774 "libgnunet_plugin_ats_%s",
1775 plugin_short);
1776 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1777 "Initializing solver `%s '`%s'\n",
1778 plugin_short,
1779 plugin);
1780 if (NULL == (solver = GNUNET_PLUGIN_load (plugin, &env)))
1781 {
1782 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1783 _("Failed to initialize solver `%s'!\n"),
1784 plugin);
1785 return GNUNET_SYSERR;
1786 }
1787
1788 GNUNET_assert (NULL != env.sf.s_add);
1789 GNUNET_assert (NULL != env.sf.s_address_update_property);
1790 GNUNET_assert (NULL != env.sf.s_address_update_session);
1791 GNUNET_assert (NULL != env.sf.s_address_update_network);
1792 GNUNET_assert (NULL != env.sf.s_get);
1793 GNUNET_assert (NULL != env.sf.s_get_stop);
1794 GNUNET_assert (NULL != env.sf.s_pref);
1795 GNUNET_assert (NULL != env.sf.s_feedback);
1796 GNUNET_assert (NULL != env.sf.s_del);
1797 GNUNET_assert (NULL != env.sf.s_bulk_start);
1798 GNUNET_assert (NULL != env.sf.s_bulk_stop);
1799
1800
1801 GAS_normalization_start (&normalized_preference_changed_cb, NULL,
1802 &normalized_property_changed_cb, NULL);
1803
1804 if (NULL == solver)
1805 {
1806 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1807 _("Failed to initialize solver!\n"));
1808 return GNUNET_SYSERR;
1809 }
1810 /* up and running */
1811 running = GNUNET_YES;
1812
1813 GNUNET_STATISTICS_set (stats,
1814 "# addresses", 849 "# addresses",
1815 GNUNET_CONTAINER_multipeermap_size (addresses), 850 GNUNET_CONTAINER_multipeermap_size (GSA_addresses),
1816 GNUNET_NO); 851 GNUNET_NO);
1817
1818 return GNUNET_OK;
1819} 852}
1820 853
1821 854
@@ -1835,12 +868,12 @@ destroy_all_address_it (void *cls,
1835 struct ATS_Address *aa = value; 868 struct ATS_Address *aa = value;
1836 869
1837 /* Remove */ 870 /* Remove */
1838 GNUNET_assert(GNUNET_YES == 871 GNUNET_assert (GNUNET_YES ==
1839 GNUNET_CONTAINER_multipeermap_remove (addresses, 872 GNUNET_CONTAINER_multipeermap_remove (GSA_addresses,
1840 key, 873 key,
1841 value)); 874 value));
1842 /* Notify */ 875 /* Notify */
1843 env.sf.s_del (solver, aa, GNUNET_NO); 876 GAS_plugin_delete_address (aa);
1844 /* Destroy */ 877 /* Destroy */
1845 GAS_performance_notify_all_clients (&aa->peer, 878 GAS_performance_notify_all_clients (&aa->peer,
1846 aa->plugin, 879 aa->plugin,
@@ -1861,17 +894,14 @@ destroy_all_address_it (void *cls,
1861void 894void
1862GAS_addresses_destroy_all () 895GAS_addresses_destroy_all ()
1863{ 896{
1864 if (GNUNET_NO == running)
1865 return;
1866
1867 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 897 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1868 "Destroying all addresses\n"); 898 "Destroying all addresses\n");
1869 env.sf.s_bulk_start (solver); 899 GAS_plugin_solver_lock ();
1870 if (NULL != addresses) 900 if (NULL != GSA_addresses)
1871 GNUNET_CONTAINER_multipeermap_iterate (addresses, 901 GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
1872 &destroy_all_address_it, 902 &destroy_all_address_it,
1873 NULL); 903 NULL);
1874 env.sf.s_bulk_start (solver); 904 GAS_plugin_solver_unlock ();
1875} 905}
1876 906
1877 907
@@ -1881,41 +911,11 @@ GAS_addresses_destroy_all ()
1881void 911void
1882GAS_addresses_done () 912GAS_addresses_done ()
1883{ 913{
1884 struct GAS_Addresses_Suggestion_Requests *cur;
1885 struct GAS_Addresses_Preference_Clients *pcur;
1886
1887 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 914 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1888 "Shutting down addresses\n"); 915 "Shutting down addresses\n");
1889 GAS_addresses_destroy_all (); 916 GAS_addresses_destroy_all ();
1890 running = GNUNET_NO; 917 GNUNET_CONTAINER_multipeermap_destroy (GSA_addresses);
1891 GNUNET_CONTAINER_multipeermap_destroy (addresses); 918 GSA_addresses = NULL;
1892 addresses = NULL;
1893 while (NULL != (cur = pending_requests_head))
1894 {
1895 GNUNET_CONTAINER_DLL_remove (pending_requests_head,
1896 pending_requests_tail,
1897 cur);
1898 GNUNET_free(cur);
1899 }
1900
1901 while (NULL != (pcur = preference_clients_head))
1902 {
1903 GNUNET_CONTAINER_DLL_remove (preference_clients_head,
1904 preference_clients_tail,
1905 pcur);
1906 GNUNET_assert (pref_clients > 0);
1907 pref_clients --;
1908 GNUNET_STATISTICS_set (stats,
1909 "# active performance clients",
1910 pref_clients,
1911 GNUNET_NO);
1912 GNUNET_free (pcur);
1913 }
1914 GNUNET_PLUGIN_unload (plugin,
1915 solver);
1916 GNUNET_free (plugin);
1917 /* Stop configured solution method */
1918 GAS_normalization_stop ();
1919} 919}
1920 920
1921 921
@@ -1990,15 +990,15 @@ GAS_addresses_get_peer_info (const struct GNUNET_PeerIdentity *peer,
1990 (NULL == peer) 990 (NULL == peer)
1991 ? "all peers" 991 ? "all peers"
1992 : GNUNET_i2s (peer), 992 : GNUNET_i2s (peer),
1993 (unsigned int) GNUNET_CONTAINER_multipeermap_size (addresses)); 993 (unsigned int) GNUNET_CONTAINER_multipeermap_size (GSA_addresses));
1994 pi_ctx.it = pi_it; 994 pi_ctx.it = pi_it;
1995 pi_ctx.it_cls = pi_it_cls; 995 pi_ctx.it_cls = pi_it_cls;
1996 if (NULL == peer) 996 if (NULL == peer)
1997 GNUNET_CONTAINER_multipeermap_iterate (addresses, 997 GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
1998 &peerinfo_it, 998 &peerinfo_it,
1999 &pi_ctx); 999 &pi_ctx);
2000 else 1000 else
2001 GNUNET_CONTAINER_multipeermap_get_multiple (addresses, 1001 GNUNET_CONTAINER_multipeermap_get_multiple (GSA_addresses,
2002 peer, 1002 peer,
2003 &peerinfo_it, &pi_ctx); 1003 &peerinfo_it, &pi_ctx);
2004 pi_it (pi_it_cls, 1004 pi_it (pi_it_cls,
diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h
index 8892f77c4..f26eb779d 100644
--- a/src/ats/gnunet-service-ats_addresses.h
+++ b/src/ats/gnunet-service-ats_addresses.h
@@ -216,38 +216,7 @@
216 * The bandwidth assigned to a peer can be influenced by setting a preference 216 * The bandwidth assigned to a peer can be influenced by setting a preference
217 * for a peer. The prefernce will be given to to the solver with s_pref which 217 * for a peer. The prefernce will be given to to the solver with s_pref which
218 * has to take care of the preference value 218 * has to take care of the preference value
219
220 */
221
222/**
223 * Available ressource assignment modes
224 */ 219 */
225enum ATS_Mode
226{
227 /**
228 * proportional mode:
229 *
230 * Assign each peer an equal amount of bandwidth (bw)
231 *
232 * bw_per_peer = bw_total / #active addresses
233 */
234 MODE_PROPORTIONAL,
235
236 /**
237 * MLP mode:
238 *
239 * Solve ressource assignment as an optimization problem
240 * Uses an mixed integer programming solver
241 */
242 MODE_MLP,
243
244 /**
245 * Reinforcement Learning mode:
246 *
247 * Solve resource assignment using a learning agent
248 */
249 MODE_RIL
250};
251 220
252 221
253/* 222/*
@@ -362,17 +331,6 @@ struct ATS_Address
362 */ 331 */
363 uint32_t last_notified_bw_out; 332 uint32_t last_notified_bw_out;
364 333
365
366 /**
367 * Blocking interval
368 */
369 struct GNUNET_TIME_Relative block_interval;
370
371 /**
372 * Time when address can be suggested again
373 */
374 struct GNUNET_TIME_Absolute blocked_until;
375
376 /** 334 /**
377 * Time when address had last activity (update, in uses) 335 * Time when address had last activity (update, in uses)
378 */ 336 */
@@ -402,19 +360,18 @@ struct ATS_Address
402 360
403 361
404/** 362/**
363 * A multihashmap to store all addresses
364 */
365extern struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses;
366
367
368
369/**
405 * Initialize address subsystem. The addresses subsystem manages the addresses 370 * Initialize address subsystem. The addresses subsystem manages the addresses
406 * known and current performance information. It has a solver component 371 * known and current performance information.
407 * responsible for the resource allocation. It tells the solver about changes
408 * and receives updates when the solver changes the ressource allocation.
409 *
410 * @param cfg configuration to use
411 * @param stats the statistics handle to use
412 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load
413 * solver plugin)
414 */ 372 */
415int 373void
416GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, 374GAS_addresses_init (void);
417 struct GNUNET_STATISTICS_Handle *stats);
418 375
419 376
420/** 377/**
@@ -480,83 +437,6 @@ void
480GAS_addresses_destroy_all (void); 437GAS_addresses_destroy_all (void);
481 438
482 439
483/**
484 * Request address suggestions for a peer
485 *
486 * @param peer the peer id
487 */
488void
489GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer);
490
491
492/**
493 * Cancel address suggestions for a peer
494 *
495 * @param peer the peer id
496 */
497void
498GAS_addresses_request_address_cancel (const struct GNUNET_PeerIdentity *peer);
499
500
501/**
502 * Reset suggestion backoff for a peer
503 *
504 * Suggesting addresses is blocked for ATS_BLOCKING_DELTA. Blocking can be
505 * reset using this function
506 *
507 * @param peer the peer id
508 */
509void
510GAS_addresses_handle_backoff_reset (const struct GNUNET_PeerIdentity *peer);
511
512
513/**
514 * A performance client disconnected
515 *
516 * @param client the client; FIXME: type!?
517 */
518void
519GAS_addresses_preference_client_disconnect (void *client);
520
521
522/**
523 * Change the preference for a peer
524 *
525 * @param client the client sending this request; FIXME: type!?
526 * @param peer the peer id
527 * @param kind the preference kind to change
528 * @param score_abs the new preference score
529 */
530void
531GAS_addresses_preference_change (void *client,
532 const struct GNUNET_PeerIdentity *peer,
533 enum GNUNET_ATS_PreferenceKind kind,
534 float score_abs);
535
536
537/**
538 * Application feedback on how good preference requirements are fulfilled
539 * for a specific preference in the given time scope [now - scope .. now]
540 *
541 * An application notifies ATS if (and only if) it has feedback information
542 * for a specific property. This value is valid until the feedback score is
543 * updated by the application.
544 *
545 * If the application has no feedback for this preference kind the application
546 * will not explicitly call.
547 *
548 * @param application the application sending this request; FIXME: type?
549 * @param peer the peer id
550 * @param scope the time interval this valid for: [now - scope .. now]
551 * @param kind the preference kind this feedback is intended for
552 * @param score_abs the new preference score
553 */
554void
555GAS_addresses_preference_feedback (void *application,
556 const struct GNUNET_PeerIdentity *peer,
557 const struct GNUNET_TIME_Relative scope,
558 enum GNUNET_ATS_PreferenceKind kind,
559 float score_abs);
560 440
561 441
562/** 442/**
diff --git a/src/ats/gnunet-service-ats_connectivity.c b/src/ats/gnunet-service-ats_connectivity.c
index da943f984..4aee2ddb8 100644
--- a/src/ats/gnunet-service-ats_connectivity.c
+++ b/src/ats/gnunet-service-ats_connectivity.c
@@ -34,8 +34,124 @@
34#include "gnunet-service-ats.h" 34#include "gnunet-service-ats.h"
35#include "gnunet-service-ats_addresses.h" 35#include "gnunet-service-ats_addresses.h"
36#include "gnunet-service-ats_connectivity.h" 36#include "gnunet-service-ats_connectivity.h"
37#include "gnunet-service-ats_plugins.h"
37#include "ats.h" 38#include "ats.h"
38 39
40
41/**
42 * Pending Address suggestion requests
43 */
44struct GAS_Addresses_Suggestion_Requests
45{
46 /**
47 * Next in DLL
48 */
49 struct GAS_Addresses_Suggestion_Requests *next;
50
51 /**
52 * Previous in DLL
53 */
54 struct GAS_Addresses_Suggestion_Requests *prev;
55
56 /**
57 * Peer ID
58 */
59 struct GNUNET_PeerIdentity id;
60};
61
62
63/**
64 * Address suggestion requests DLL head.
65 * FIXME: This must become a Multipeermap! O(n) operations
66 * galore instead of O(1)!!!
67 */
68static struct GAS_Addresses_Suggestion_Requests *pending_requests_head;
69
70/**
71 * Address suggestion requests DLL tail
72 */
73static struct GAS_Addresses_Suggestion_Requests *pending_requests_tail;
74
75
76
77
78/**
79 * Cancel address suggestions for a peer
80 *
81 * @param peer the peer id
82 */
83void
84GAS_addresses_request_address_cancel (const struct GNUNET_PeerIdentity *peer)
85{
86 struct GAS_Addresses_Suggestion_Requests *cur = pending_requests_head;
87
88 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
89 "Received request: `%s' for peer %s\n",
90 "request_address_cancel",
91 GNUNET_i2s (peer));
92
93 while (NULL != cur)
94 {
95 if (0 == memcmp (peer, &cur->id, sizeof(cur->id)))
96 break; /* found */
97 cur = cur->next;
98 }
99
100 if (NULL == cur)
101 {
102 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
103 "No address requests pending for peer `%s', cannot remove!\n",
104 GNUNET_i2s (peer));
105 return;
106 }
107 GAS_plugin_request_connect_stop (peer);
108 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
109 "Removed request pending for peer `%s\n",
110 GNUNET_i2s (peer));
111 GNUNET_CONTAINER_DLL_remove (pending_requests_head,
112 pending_requests_tail,
113 cur);
114 GNUNET_free (cur);
115}
116
117
118/**
119 * Request address suggestions for a peer
120 *
121 * @param peer the peer id
122 */
123void
124GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer)
125{
126 struct GAS_Addresses_Suggestion_Requests *cur = pending_requests_head;
127
128 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
129 "Received `%s' for peer `%s'\n",
130 "REQUEST ADDRESS",
131 GNUNET_i2s (peer));
132
133 while (NULL != cur)
134 {
135 if (0 == memcmp (peer, &cur->id, sizeof(cur->id)))
136 break; /* already suggesting */
137 cur = cur->next;
138 }
139 if (NULL == cur)
140 {
141 cur = GNUNET_new (struct GAS_Addresses_Suggestion_Requests);
142 cur->id = *peer;
143 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
144 "Adding new address suggestion request for `%s'\n",
145 GNUNET_i2s (peer));
146 GNUNET_CONTAINER_DLL_insert (pending_requests_head,
147 pending_requests_tail,
148 cur);
149 }
150 GAS_plugin_request_connect_start (peer);
151}
152
153
154
39/** 155/**
40 * Handle 'request address' messages from clients. 156 * Handle 'request address' messages from clients.
41 * 157 *
@@ -83,4 +199,36 @@ GAS_handle_request_address_cancel (void *cls,
83 GNUNET_SERVER_receive_done (client, GNUNET_OK); 199 GNUNET_SERVER_receive_done (client, GNUNET_OK);
84} 200}
85 201
202
203/**
204 * Unregister a client (which may have been a connectivity client,
205 * but this is not assured).
206 *
207 * @param client handle of the (now dead) client
208 */
209void
210GAS_connectivity_remove_client (struct GNUNET_SERVER_Client *client)
211{
212 // FIXME
213}
214
215
216/**
217 * Shutdown connectivity subsystem.
218 */
219void
220GAS_connectivity_done ()
221{
222 struct GAS_Addresses_Suggestion_Requests *cur;
223
224 while (NULL != (cur = pending_requests_head))
225 {
226 GNUNET_CONTAINER_DLL_remove (pending_requests_head,
227 pending_requests_tail,
228 cur);
229 GNUNET_free(cur);
230 }
231}
232
233
86/* end of gnunet-service-ats_connectivity.c */ 234/* end of gnunet-service-ats_connectivity.c */
diff --git a/src/ats/gnunet-service-ats_connectivity.h b/src/ats/gnunet-service-ats_connectivity.h
index c6b50f445..faa00ac40 100644
--- a/src/ats/gnunet-service-ats_connectivity.h
+++ b/src/ats/gnunet-service-ats_connectivity.h
@@ -27,6 +27,24 @@
27#ifndef GNUNET_SERVICE_ATS_CONNECTIVITY_H 27#ifndef GNUNET_SERVICE_ATS_CONNECTIVITY_H
28#define GNUNET_SERVICE_ATS_CONNECTIVITY_H 28#define GNUNET_SERVICE_ATS_CONNECTIVITY_H
29 29
30/**
31 * Request address suggestions for a peer
32 *
33 * @param peer the peer id
34 */
35void
36GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer);
37
38
39/**
40 * Cancel address suggestions for a peer
41 *
42 * @param peer the peer id
43 */
44void
45GAS_addresses_request_address_cancel (const struct GNUNET_PeerIdentity *peer);
46
47
30 48
31/** 49/**
32 * Handle 'request address' messages from clients. 50 * Handle 'request address' messages from clients.
@@ -54,5 +72,22 @@ GAS_handle_request_address_cancel (void *cls,
54 const struct GNUNET_MessageHeader *message); 72 const struct GNUNET_MessageHeader *message);
55 73
56 74
75/**
76 * Unregister a client (which may have been a connectivity client,
77 * but this is not assured).
78 *
79 * @param client handle of the (now dead) client
80 */
81void
82GAS_connectivity_remove_client (struct GNUNET_SERVER_Client *client);
83
84
85/**
86 * Shutdown connectivity subsystem.
87 */
88void
89GAS_connectivity_done (void);
90
91
57#endif 92#endif
58/* end of gnunet-service-ats_connectivity.h */ 93/* end of gnunet-service-ats_connectivity.h */
diff --git a/src/ats/gnunet-service-ats_normalization.c b/src/ats/gnunet-service-ats_normalization.c
index b4051c9fa..7003f69e4 100644
--- a/src/ats/gnunet-service-ats_normalization.c
+++ b/src/ats/gnunet-service-ats_normalization.c
@@ -23,116 +23,18 @@
23 * @brief ats service address: management of ATS properties and preferences normalization 23 * @brief ats service address: management of ATS properties and preferences normalization
24 * @author Matthias Wachs 24 * @author Matthias Wachs
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 *
27 * FIXME: rename to 'properties'!
26 */ 28 */
27#include "platform.h" 29#include "platform.h"
28#include "gnunet_ats_service.h" 30#include "gnunet_ats_service.h"
29#include "gnunet-service-ats_addresses.h" 31#include "gnunet-service-ats_addresses.h"
30#include "gnunet-service-ats_normalization.h" 32#include "gnunet-service-ats_normalization.h"
33#include "gnunet-service-ats_plugins.h"
31 34
32#define LOG(kind,...) GNUNET_log_from (kind, "ats-normalization",__VA_ARGS__) 35#define LOG(kind,...) GNUNET_log_from (kind, "ats-normalization",__VA_ARGS__)
33 36
34/**
35 * Preference client
36 */
37struct PreferenceClient
38{
39 /**
40 * Next in DLL
41 */
42 struct PreferenceClient *prev;
43
44 /**
45 * Next in DLL
46 */
47
48 struct PreferenceClient *next;
49
50 /**
51 * Client handle
52 */
53 void *client;
54
55 /**
56 * Array of sum of absolute preferences for this client
57 */
58 double f_abs_sum[GNUNET_ATS_PreferenceCount];
59
60 /**
61 * Array of sum of relative preferences for this client
62 */
63 double f_rel_sum[GNUNET_ATS_PreferenceCount];
64
65 /**
66 * List of peer preferences for this client
67 */
68
69 /**
70 * Head of peer list
71 */
72 struct PreferencePeer *p_head;
73
74 /**
75 * Tail of peer list
76 */
77 struct PreferencePeer *p_tail;
78};
79
80/**
81 * Preference peer
82 */
83struct PreferencePeer
84{
85 /**
86 * Next in DLL
87 */
88 struct PreferencePeer *next;
89
90 /**
91 * Previous in DLL
92 */
93 struct PreferencePeer *prev;
94
95 /**
96 * Client
97 */
98 struct PreferenceClient *client;
99
100 /**
101 * Peer id
102 */
103 struct GNUNET_PeerIdentity id;
104 37
105 /**
106 * Absolute preference values for all preference types
107 */
108 double f_abs[GNUNET_ATS_PreferenceCount];
109
110 /**
111 * Relative preference values for all preference types
112 */
113 double f_rel[GNUNET_ATS_PreferenceCount];
114
115 /**
116 * Absolute point of time of next aging process
117 */
118 struct GNUNET_TIME_Absolute next_aging[GNUNET_ATS_PreferenceCount];
119};
120
121/**
122 * Relative preferences for a peer
123 */
124struct PeerRelative
125{
126 /**
127 * Relative preference values
128 */
129 double f_rel[GNUNET_ATS_PreferenceCount];
130
131 /**
132 * Peer id
133 */
134 struct GNUNET_PeerIdentity id;
135};
136 38
137/** 39/**
138 * Quality Normalization 40 * Quality Normalization
@@ -147,490 +49,27 @@ struct Property
147 49
148static struct Property properties[GNUNET_ATS_QualityPropertiesCount]; 50static struct Property properties[GNUNET_ATS_QualityPropertiesCount];
149 51
150
151/**
152 * Callback to call on changing preference values
153 */
154static GAS_Normalization_preference_changed_cb pref_changed_cb;
155
156/**
157 * Closure for callback to call on changing preference values
158 */
159static void *pref_changed_cb_cls;
160
161/**
162 * Callback to call on changing property values
163 */
164static GAS_Normalization_property_changed_cb prop_ch_cb;
165
166/**
167 * Closure for callback to call on changing property values
168 */
169static void *prop_ch_cb_cls;
170
171/**
172 * Hashmap to store peer information for preference normalization
173 */
174static struct GNUNET_CONTAINER_MultiPeerMap *preference_peers;
175
176/** 52/**
177 * Hashmap to store peer information for property normalization 53 * Hashmap to store peer information for property normalization
178 * FIXME: this map is not used! 54 * FIXME: this map is not used!
179 */ 55 */
180static struct GNUNET_CONTAINER_MultiPeerMap *property_peers; 56static struct GNUNET_CONTAINER_MultiPeerMap *property_peers;
181 57
182/**
183 * Clients in DLL: head
184 */
185static struct PreferenceClient *pc_head;
186
187/**
188 * Clients in DLL: tail
189 */
190static struct PreferenceClient *pc_tail;
191
192/**
193 * Default values
194 */
195static struct PeerRelative defvalues;
196
197static struct GNUNET_SCHEDULER_Task * aging_task;
198
199
200/**
201 * Update a peer
202 *
203 * @param id peer id
204 * @param kind the kind
205 * @param rp the relative peer struct
206 * @return the new relative preference
207 */
208static void
209update_relative_values_for_peer (const struct GNUNET_PeerIdentity *id,
210 enum GNUNET_ATS_PreferenceKind kind, struct PeerRelative *rp)
211{
212 struct PreferenceClient *c_cur;
213 struct PreferencePeer *p_cur;
214 double f_rel_total;
215 double f_rel_sum;
216 double backup;
217 unsigned int peer_count;
218
219 f_rel_sum = 0.0;
220 f_rel_total = 0.0;
221 peer_count = 0;
222
223 /* For all clients */
224 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
225 {
226 /* For peer entries with this id */
227 for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
228 {
229 f_rel_sum += p_cur->f_rel[kind];
230 if (0 == memcmp (id, &p_cur->id, sizeof(struct GNUNET_PeerIdentity)))
231 {
232 peer_count ++;
233 f_rel_total += p_cur->f_rel[kind];
234 }
235
236 }
237 }
238
239 LOG (GNUNET_ERROR_TYPE_DEBUG,
240 "%u clients have a total relative preference for peer `%s' `%s' of %.3f and for %s in total %.3f\n",
241 peer_count, GNUNET_i2s (id),
242 GNUNET_ATS_print_preference_type (kind),
243 f_rel_total,
244 GNUNET_ATS_print_preference_type (kind),
245 f_rel_sum);
246
247 /* Find entry for the peer containing relative values in the hashmap */
248 if (NULL != rp)
249 {
250 backup = rp->f_rel[kind];
251 if (f_rel_sum > 0)
252 rp->f_rel[kind] = f_rel_total / f_rel_sum;
253 else
254 {
255 /* No client had any preferences for this type and any peer */
256 rp->f_rel[kind] = DEFAULT_REL_PREFERENCE;
257 }
258 if ((backup != rp->f_rel[kind]) && (NULL != pref_changed_cb))
259 {
260 pref_changed_cb (pref_changed_cb_cls, &rp->id, kind, rp->f_rel[kind]);
261 }
262 }
263}
264
265
266/**
267 * Recalculate preference for a specific ATS property
268 *
269 * @param c the preference client
270 * @param kind the preference kind
271 * @return the result
272 */
273static void
274recalculate_relative_preferences (struct PreferenceClient *c,
275 enum GNUNET_ATS_PreferenceKind kind)
276{
277 struct PreferencePeer *p_cur;
278
279 /* For this client: sum of absolute preference values for this preference */
280 c->f_abs_sum[kind] = 0.0;
281 /* For this client: sum of relative preference values for this preference
282 *
283 * Note: this value should also be 1.0, but:
284 * if no preferences exist due to aging, this value can be 0.0
285 * and the client can be removed */
286 c->f_rel_sum[kind] = 0.0;
287
288 for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next)
289 c->f_abs_sum[kind] += p_cur->f_abs[kind];
290 LOG (GNUNET_ERROR_TYPE_DEBUG,
291 "Client %p has sum of total preferences for %s of %.3f\n",
292 c->client, GNUNET_ATS_print_preference_type (kind), c->f_abs_sum[kind]);
293
294 /* For all peers: calculate relative preference */
295 for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next)
296 {
297 /* Calculate relative preference for specific kind */
298
299 /* Every application has a preference for each peer between
300 * [0 .. 1] in relative values
301 * and [0 .. inf] in absolute values */
302 p_cur->f_rel[kind] = p_cur->f_abs[kind] / c->f_abs_sum[kind];
303 c->f_rel_sum[kind] += p_cur->f_rel[kind];
304
305 LOG (GNUNET_ERROR_TYPE_DEBUG,
306 "Client %p has relative preference for %s for peer `%s' of %.3f\n",
307 c->client,
308 GNUNET_ATS_print_preference_type (kind),
309 GNUNET_i2s (&p_cur->id),
310 p_cur->f_rel[kind]);
311 }
312
313}
314
315
316/**
317 * Update the absolute preference value for a peer
318 * @param c the client
319 * @param p the peer
320 * @param kind the preference kind
321 * @param score_abs the absolute value
322 * @return the new relative preference value
323 */
324static void
325update_abs_preference (struct PreferenceClient *c,
326 struct PreferencePeer *p,
327 enum GNUNET_ATS_PreferenceKind kind,
328 float score_abs)
329{
330 double score = score_abs;
331
332 /* Update preference value according to type */
333 switch (kind)
334 {
335 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
336 case GNUNET_ATS_PREFERENCE_LATENCY:
337 p->f_abs[kind] = score;
338 /* p->f_abs[kind] = (p->f_abs[kind] + score) / 2; */
339 p->next_aging[kind] = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
340 PREF_AGING_INTERVAL);
341 break;
342 case GNUNET_ATS_PREFERENCE_END:
343 break;
344 default:
345 break;
346 }
347}
348
349
350static int
351update_iterator (void *cls,
352 const struct GNUNET_PeerIdentity *key,
353 void *value)
354{
355 enum GNUNET_ATS_PreferenceKind *kind = cls;
356 struct PeerRelative *pr = value;
357
358 update_relative_values_for_peer (key,
359 (*kind),
360 pr);
361 return GNUNET_OK;
362}
363
364
365static void
366run_preference_update (struct PreferenceClient *c_cur,
367 struct PreferencePeer *p_cur,
368 enum GNUNET_ATS_PreferenceKind kind,
369 float score_abs)
370{
371 double old_value;
372 58
373 /* Update relative value */
374 old_value = p_cur->f_rel[kind];
375 recalculate_relative_preferences (c_cur, kind);
376 if (p_cur->f_rel[kind] == old_value)
377 return;
378
379 /* Relative preference value changed, recalculate for all peers */
380 GNUNET_CONTAINER_multipeermap_iterate (preference_peers, &update_iterator, &kind);
381}
382
383
384/**
385 * Reduce absolute preferences since they got old
386 *
387 * @param cls the PreferencePeer
388 * @param tc context
389 */
390static void
391preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
392{
393 struct PreferencePeer *p;
394 struct PreferenceClient *cur_client;
395 int i;
396 int values_to_update;
397 double backup;
398
399 aging_task = NULL;
400 values_to_update = 0;
401 cur_client = NULL;
402
403 for (cur_client = pc_head; NULL != cur_client; cur_client = cur_client->next)
404 {
405 for (p = cur_client->p_head; NULL != p; p = p->next)
406 {
407 /* Aging absolute values: */
408 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
409 {
410 if (0
411 == GNUNET_TIME_absolute_get_remaining (p->next_aging[i]).rel_value_us)
412 {
413 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
414 "Aging preference for peer `%s'\n", GNUNET_i2s (&p->id));
415 backup = p->f_abs[i];
416 if (p->f_abs[i] > DEFAULT_ABS_PREFERENCE)
417 p->f_abs[i] *= PREF_AGING_FACTOR;
418
419 if (p->f_abs[i] <= DEFAULT_ABS_PREFERENCE + PREF_EPSILON)
420 p->f_abs[i] = DEFAULT_ABS_PREFERENCE;
421
422 if ( (p->f_abs[i] != DEFAULT_ABS_PREFERENCE) &&
423 (backup != p->f_abs[i]) )
424 {
425 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
426 "Aged preference for peer `%s' from %.3f to %.3f\n",
427 GNUNET_i2s (&p->id), backup, p->f_abs[i]);
428
429 run_preference_update(cur_client, p, i, p->f_abs[i]);
430
431 p->next_aging[i] = GNUNET_TIME_absolute_add (
432 GNUNET_TIME_absolute_get (), PREF_AGING_INTERVAL);
433 values_to_update++;
434 }
435 }
436 }
437 }
438 }
439
440 if (values_to_update > 0)
441 {
442 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
443 "Rescheduling aging task due to %u elements to age\n",
444 values_to_update);
445 aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL,
446 &preference_aging, NULL );
447 }
448 else
449 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
450 "No values to age left, not rescheduling aging task\n");
451
452}
453
454
455/**
456 * Normalize an updated preference value
457 *
458 * @param client the client with this preference
459 * @param peer the peer to change the preference for
460 * @param kind the kind to change the preference
461 * @param score_abs the normalized score
462 */
463void
464GAS_normalization_normalize_preference (void *client,
465 const struct GNUNET_PeerIdentity *peer,
466 enum GNUNET_ATS_PreferenceKind kind,
467 float score_abs)
468{
469 struct PreferenceClient *c_cur;
470 struct PreferencePeer *p_cur;
471 struct PeerRelative *r_cur;
472 double old_value;
473 int i;
474
475 GNUNET_assert(NULL != client);
476 GNUNET_assert(NULL != peer);
477
478 LOG (GNUNET_ERROR_TYPE_DEBUG,
479 "Client %p changes preference for peer `%s' for `%s' to %.2f\n",
480 client,
481 GNUNET_i2s (peer),
482 GNUNET_ATS_print_preference_type (kind),
483 score_abs);
484
485 if (kind >= GNUNET_ATS_PreferenceCount)
486 {
487 GNUNET_break(0);
488 return;
489 }
490
491 /* Find preference client */
492 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
493 {
494 if (client == c_cur->client)
495 break;
496 }
497 /* Not found: create new preference client */
498 if (NULL == c_cur)
499 {
500 c_cur = GNUNET_new (struct PreferenceClient);
501 c_cur->client = client;
502 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
503 {
504 c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE;
505 c_cur->f_rel_sum[i] = DEFAULT_REL_PREFERENCE;
506 }
507
508 GNUNET_CONTAINER_DLL_insert(pc_head, pc_tail, c_cur);
509 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding new client %p \n", c_cur);
510 }
511
512 /* Find entry for peer */
513 for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
514 if (0 == memcmp (&p_cur->id, peer, sizeof(p_cur->id)))
515 break;
516
517 /* Not found: create new peer entry */
518 if (NULL == p_cur)
519 {
520 p_cur = GNUNET_new (struct PreferencePeer);
521 p_cur->client = c_cur;
522 p_cur->id = (*peer);
523 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
524 {
525 /* Default value per peer absolute preference for a preference: 0 */
526 p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE;
527 /* Default value per peer relative preference for a quality: 1.0 */
528 p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE;
529 p_cur->next_aging[i] = GNUNET_TIME_UNIT_FOREVER_ABS;
530 }
531 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding new peer %p for client %p \n",
532 p_cur, c_cur);
533 GNUNET_CONTAINER_DLL_insert(c_cur->p_head, c_cur->p_tail, p_cur);
534 }
535
536 /* Create struct for peer */
537 if (NULL == GNUNET_CONTAINER_multipeermap_get (preference_peers, peer))
538 {
539 r_cur = GNUNET_new (struct PeerRelative);
540 r_cur->id = (*peer);
541 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
542 r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE;
543 GNUNET_assert(
544 GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (preference_peers,
545 &r_cur->id, r_cur, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
546 }
547
548 /* Update absolute value */
549 old_value = p_cur->f_abs[kind];
550 update_abs_preference (c_cur, p_cur, kind, score_abs);
551 if (p_cur->f_abs[kind] == old_value)
552 return;
553
554 run_preference_update (c_cur, p_cur, kind, score_abs);
555
556 /* Start aging task */
557 if (NULL == aging_task)
558 aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL,
559 &preference_aging, NULL );
560
561}
562
563
564/**
565 * Get the normalized preference values for a specific peer or
566 * the default values if
567 *
568 * @param id the peer
569 * @return pointer to the values, can be indexed with GNUNET_ATS_PreferenceKind,
570 * default preferences if peer does not exist
571 */
572const double *
573GAS_normalization_get_preferences_by_peer (const struct GNUNET_PeerIdentity *id)
574{
575 GNUNET_assert(NULL != preference_peers);
576 GNUNET_assert(NULL != id);
577
578 struct PeerRelative *rp;
579 if (NULL == (rp = GNUNET_CONTAINER_multipeermap_get (preference_peers, id)))
580 {
581 return defvalues.f_rel;
582 }
583 return rp->f_rel;
584}
585
586
587/**
588 * Get the normalized preference values for a specific client and peer
589 *
590 * @param client client
591 * @param peer the peer
592 * @param pref the preference type
593 * @return the value
594 */
595double
596GAS_normalization_get_preferences_by_client (const void *client,
597 const struct GNUNET_PeerIdentity *peer,
598 enum GNUNET_ATS_PreferenceKind pref)
599{
600 struct PreferenceClient *c_cur;
601 struct PreferencePeer *p_cur;
602
603 /* Find preference client */
604 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
605 {
606 if (client == c_cur->client)
607 break;
608 }
609 if (NULL == c_cur)
610 return -1.0;
611
612 for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
613 {
614 if (0 == memcmp (peer, &p_cur->id, sizeof (struct GNUNET_PeerIdentity)))
615 break;
616 }
617 if (NULL == p_cur)
618 return DEFAULT_REL_PREFERENCE; /* Not found, return default */
619
620 return p_cur->f_rel[pref];
621}
622 59
623 60
624/** 61/**
625 * Get the normalized properties values for a specific peer or 62 * Get the normalized properties values for a specific peer or
626 * the default values if 63 * the default values if
627 * 64 *
65 * @param cls ignored
628 * @param address the address 66 * @param address the address
629 * @return pointer to the values, can be indexed with GNUNET_ATS_PreferenceKind, 67 * @return pointer to the values, can be indexed with GNUNET_ATS_PreferenceKind,
630 * default preferences if peer does not exist 68 * default preferences if peer does not exist
631 */ 69 */
632const double * 70const double *
633GAS_normalization_get_properties (const struct ATS_Address *address) 71GAS_normalization_get_properties (void *cls,
72 const struct ATS_Address *address)
634{ 73{
635 static double norm_values[GNUNET_ATS_QualityPropertiesCount]; 74 static double norm_values[GNUNET_ATS_QualityPropertiesCount];
636 int i; 75 int i;
@@ -742,7 +181,9 @@ find_min_max_it (void *cls, const struct GNUNET_PeerIdentity *h, void *k)
742 181
743 182
744static int 183static int
745normalize_address (void *cls, const struct GNUNET_PeerIdentity *h, void *k) 184normalize_address (void *cls,
185 const struct GNUNET_PeerIdentity *h,
186 void *k)
746{ 187{
747 struct Property *p = cls; 188 struct Property *p = cls;
748 struct ATS_Address *address = k; 189 struct ATS_Address *address = k;
@@ -769,9 +210,9 @@ normalize_address (void *cls, const struct GNUNET_PeerIdentity *h, void *k)
769 address->atsin[p->prop_type].avg, p->min, p->max, 210 address->atsin[p->prop_type].avg, p->min, p->max,
770 address->atsin[p->prop_type].norm); 211 address->atsin[p->prop_type].norm);
771 212
772 if (NULL != prop_ch_cb) 213 GAS_normalized_property_changed (address,
773 prop_ch_cb (prop_ch_cb_cls, address, p->atsi_type, 214 p->atsi_type,
774 address->atsin[p->prop_type].norm); 215 address->atsin[p->prop_type].norm);
775 216
776 return GNUNET_OK; 217 return GNUNET_OK;
777} 218}
@@ -781,14 +222,14 @@ normalize_address (void *cls, const struct GNUNET_PeerIdentity *h, void *k)
781 * Normalize avg_value to a range of values between [1.0, 2.0] 222 * Normalize avg_value to a range of values between [1.0, 2.0]
782 * based on min max values currently known. 223 * based on min max values currently known.
783 * 224 *
784 * @param addresses the address hashmap
785 * @param p the property 225 * @param p the property
786 * @param address the address 226 * @param address the address
787 * @param avg_value the value to normalize 227 * @param avg_value the value to normalize
788 */ 228 */
789static void 229static void
790property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses, 230property_normalize (struct Property *p,
791 struct Property *p, struct ATS_Address *address, uint32_t avg_value) 231 struct ATS_Address *address,
232 uint32_t avg_value)
792{ 233{
793 struct FindMinMaxCtx find_ctx; 234 struct FindMinMaxCtx find_ctx;
794 int addr_count; 235 int addr_count;
@@ -797,8 +238,9 @@ property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses,
797 find_ctx.p = p; 238 find_ctx.p = p;
798 find_ctx.max = 0; 239 find_ctx.max = 0;
799 find_ctx.min = UINT32_MAX; 240 find_ctx.min = UINT32_MAX;
800 addr_count = GNUNET_CONTAINER_multipeermap_iterate (addresses, 241 addr_count = GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
801 &find_min_max_it, &find_ctx); 242 &find_min_max_it,
243 &find_ctx);
802 if (0 == addr_count) 244 if (0 == addr_count)
803 { 245 {
804 GNUNET_break(0); 246 GNUNET_break(0);
@@ -808,19 +250,21 @@ property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses,
808 limits_changed = GNUNET_NO; 250 limits_changed = GNUNET_NO;
809 if (find_ctx.max != p->max) 251 if (find_ctx.max != p->max)
810 { 252 {
811 LOG(GNUNET_ERROR_TYPE_DEBUG, 253 LOG (GNUNET_ERROR_TYPE_DEBUG,
812 "Normalizing %s: new maximum %u -> recalculate all values\n", 254 "Normalizing %s: new maximum %u -> recalculate all values\n",
813 GNUNET_ATS_print_property_type (p->atsi_type), find_ctx.max); 255 GNUNET_ATS_print_property_type (p->atsi_type),
256 find_ctx.max);
814 p->max = find_ctx.max; 257 p->max = find_ctx.max;
815 limits_changed = GNUNET_YES; 258 limits_changed = GNUNET_YES;
816 } 259 }
817 260
818 if ((find_ctx.min != p->min) && (find_ctx.min < p->max)) 261 if ((find_ctx.min != p->min) && (find_ctx.min < p->max))
819 { 262 {
820 LOG(GNUNET_ERROR_TYPE_DEBUG, 263 LOG (GNUNET_ERROR_TYPE_DEBUG,
821 "Normalizing %s: new minimum %u -> recalculate all values\n", 264 "Normalizing %s: new minimum %u -> recalculate all values\n",
822 GNUNET_ATS_print_property_type (p->atsi_type), find_ctx.min, 265 GNUNET_ATS_print_property_type (p->atsi_type),
823 find_ctx.max); 266 find_ctx.min,
267 find_ctx.max);
824 p->min = find_ctx.min; 268 p->min = find_ctx.min;
825 limits_changed = GNUNET_YES; 269 limits_changed = GNUNET_YES;
826 } 270 }
@@ -835,13 +279,13 @@ property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses,
835 { 279 {
836 /* normalize just this address */ 280 /* normalize just this address */
837 normalize_address (p, &address->peer, address); 281 normalize_address (p, &address->peer, address);
838 return;
839 } 282 }
840 else 283 else
841 { 284 {
842 /* limits changed, normalize all addresses */ 285 /* limits changed, normalize all addresses */
843 GNUNET_CONTAINER_multipeermap_iterate (addresses, &normalize_address, p); 286 GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
844 return; 287 &normalize_address,
288 p);
845 } 289 }
846} 290}
847 291
@@ -849,14 +293,12 @@ property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses,
849/** 293/**
850 * Update and normalize atsi performance information 294 * Update and normalize atsi performance information
851 * 295 *
852 * @param addresses hashmap containing all addresses
853 * @param address the address to update 296 * @param address the address to update
854 * @param atsi the array of performance information 297 * @param atsi the array of performance information
855 * @param atsi_count the number of atsi information in the array 298 * @param atsi_count the number of atsi information in the array
856 */ 299 */
857void 300void
858GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiPeerMap *addresses, 301GAS_normalization_normalize_property (struct ATS_Address *address,
859 struct ATS_Address *address,
860 const struct GNUNET_ATS_Information *atsi, 302 const struct GNUNET_ATS_Information *atsi,
861 uint32_t atsi_count) 303 uint32_t atsi_count)
862{ 304{
@@ -867,9 +309,6 @@ GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiPeerMap *addr
867 uint32_t current_val; 309 uint32_t current_val;
868 unsigned int existing_properties[] = GNUNET_ATS_QualityProperties; 310 unsigned int existing_properties[] = GNUNET_ATS_QualityProperties;
869 311
870 GNUNET_assert (NULL != address);
871 GNUNET_assert (NULL != atsi);
872
873 LOG (GNUNET_ERROR_TYPE_DEBUG, 312 LOG (GNUNET_ERROR_TYPE_DEBUG,
874 "Updating %u elements for peer `%s'\n", 313 "Updating %u elements for peer `%s'\n",
875 atsi_count, 314 atsi_count,
@@ -901,70 +340,22 @@ GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiPeerMap *addr
901 /* Normalizing */ 340 /* Normalizing */
902 /* Check min, max */ 341 /* Check min, max */
903 cur_prop = &properties[c2]; 342 cur_prop = &properties[c2];
904 property_normalize (addresses, cur_prop, address, current_val); 343 property_normalize (cur_prop, address, current_val);
905 } 344 }
906} 345}
907 346
908 347
909static void
910free_client (struct PreferenceClient *pc)
911{
912 struct PreferencePeer *next_p;
913 struct PreferencePeer *p;
914 next_p = pc->p_head;
915 while (NULL != (p = next_p))
916 {
917 next_p = p->next;
918 GNUNET_CONTAINER_DLL_remove(pc->p_head, pc->p_tail, p);
919 GNUNET_free(p);
920 }
921 GNUNET_free(pc);
922}
923
924
925/**
926 * A performance client disconnected
927 *
928 * @param client the client
929 */
930void
931GAS_normalization_preference_client_disconnect (void *client)
932{
933 struct PreferenceClient *c_cur;
934 /* Find preference client */
935
936 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
937 {
938 if (client == c_cur->client)
939 break;
940 }
941 if (NULL == c_cur)
942 return;
943
944 GNUNET_CONTAINER_DLL_remove(pc_head, pc_tail, c_cur);
945 free_client (c_cur);
946}
947
948 348
949/** 349/**
950 * Start the normalization component 350 * Start the normalization component
951 *
952 * @param pref_ch_cb callback to call on relative preference changing
953 * @param pref_ch_cb_cls cls for the preference callback
954 * @param property_ch_cb callback to call on relative property changing
955 * @param property_ch_cb_cls cls for the property callback
956 */ 351 */
957void 352void
958GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, 353GAS_normalization_start ()
959 void *pref_ch_cb_cls, GAS_Normalization_property_changed_cb property_ch_cb,
960 void *property_ch_cb_cls)
961{ 354{
962 int c1; 355 int c1;
963 int i;
964 preference_peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
965 property_peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
966 unsigned int existing_properties[] = GNUNET_ATS_QualityProperties; 356 unsigned int existing_properties[] = GNUNET_ATS_QualityProperties;
967 357
358 property_peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
968 for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) 359 for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++)
969 { 360 {
970 properties[c1].prop_type = c1; 361 properties[c1].prop_type = c1;
@@ -972,42 +363,9 @@ GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb,
972 properties[c1].min = 0; 363 properties[c1].min = 0;
973 properties[c1].max = 0; 364 properties[c1].max = 0;
974 } 365 }
975
976 pref_changed_cb = pref_ch_cb;
977 pref_changed_cb_cls = pref_ch_cb_cls;
978 prop_ch_cb = property_ch_cb;
979 prop_ch_cb_cls = pref_ch_cb_cls;
980
981 pc_head = NULL;
982 pc_tail = NULL;
983
984 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
985 defvalues.f_rel[i] = DEFAULT_REL_PREFERENCE;
986 aging_task = NULL;
987 return;
988} 366}
989 367
990 368
991/**
992 * Free a peer
993 *
994 * @param cls unused
995 * @param key the key
996 * @param value RelativePeer
997 * @return #GNUNET_OK to continue
998 */
999static int
1000free_peer (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
1001{
1002 struct PeerRelative *rp = value;
1003 if (GNUNET_YES
1004 == GNUNET_CONTAINER_multipeermap_remove (preference_peers, key, value))
1005 GNUNET_free(rp);
1006 else
1007 GNUNET_break(0);
1008 return GNUNET_OK;
1009}
1010
1011 369
1012/** 370/**
1013 * Stop the normalization component and free all items 371 * Stop the normalization component and free all items
@@ -1015,27 +373,7 @@ free_peer (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
1015void 373void
1016GAS_normalization_stop () 374GAS_normalization_stop ()
1017{ 375{
1018 struct PreferenceClient *pc;
1019 struct PreferenceClient *next_pc;
1020
1021 if (NULL != aging_task)
1022 {
1023 GNUNET_SCHEDULER_cancel (aging_task);
1024 aging_task = NULL;
1025 }
1026
1027 next_pc = pc_head;
1028 while (NULL != (pc = next_pc))
1029 {
1030 next_pc = pc->next;
1031 GNUNET_CONTAINER_DLL_remove(pc_head, pc_tail, pc);
1032 free_client (pc);
1033 }
1034
1035 GNUNET_CONTAINER_multipeermap_iterate (preference_peers, &free_peer, NULL );
1036 GNUNET_CONTAINER_multipeermap_destroy (preference_peers);
1037 GNUNET_CONTAINER_multipeermap_destroy (property_peers); 376 GNUNET_CONTAINER_multipeermap_destroy (property_peers);
1038 return;
1039} 377}
1040 378
1041/* end of gnunet-service-ats_normalization.c */ 379/* end of gnunet-service-ats_normalization.c */
diff --git a/src/ats/gnunet-service-ats_normalization.h b/src/ats/gnunet-service-ats_normalization.h
index 2cbf7ab77..e542097c9 100644
--- a/src/ats/gnunet-service-ats_normalization.h
+++ b/src/ats/gnunet-service-ats_normalization.h
@@ -24,51 +24,37 @@
24 * @author Matthias Wachs 24 * @author Matthias Wachs
25 * @author Christian Grothoff 25 * @author Christian Grothoff
26 */ 26 */
27#include "platform.h" 27#ifndef GNUNET_SERVICE_ATS_NORMALIZATION_H
28#define GNUNET_SERVICE_ATS_NORMALIZATION_H
28#include "gnunet_ats_service.h" 29#include "gnunet_ats_service.h"
29 30
30#define PREF_AGING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
31#define PREF_AGING_FACTOR 0.95
32#define PREF_EPSILON 0.01
33
34#define DEFAULT_REL_PREFERENCE 0.0
35#define DEFAULT_ABS_PREFERENCE 0.0
36
37#define DEFAULT_REL_QUALITY 1.0 31#define DEFAULT_REL_QUALITY 1.0
38 32
39typedef void
40(*GAS_Normalization_preference_changed_cb) (void *cls,
41 const struct GNUNET_PeerIdentity *peer,
42 enum GNUNET_ATS_PreferenceKind kind,
43 double pref_rel);
44
45typedef void
46(*GAS_Normalization_property_changed_cb) (void *cls,
47 struct ATS_Address *peer,
48 uint32_t type,
49 double prop_rel);
50
51 33
52/** 34/**
53 * Get the normalized preference values for a specific peer 35 * Get the normalized preference values for a specific peer
54 * 36 *
37 * @param cls ignored
55 * @param id the peer @return pointer to the values, can be indexed 38 * @param id the peer @return pointer to the values, can be indexed
56 * with GNUNET_ATS_PreferenceKind, NULL if peer does not exist 39 * with GNUNET_ATS_PreferenceKind, NULL if peer does not exist
57 */ 40 */
58const double * 41const double *
59GAS_normalization_get_preferences_by_peer (const struct GNUNET_PeerIdentity *id); 42GAS_normalization_get_preferences_by_peer (void *cls,
43 const struct GNUNET_PeerIdentity *id);
60 44
61 45
62/** 46/**
63 * Get the normalized properties values for a specific peer or 47 * Get the normalized properties values for a specific peer or
64 * the default values if 48 * the default values if
65 * 49 *
50 * @param cls ignored
66 * @param address the address 51 * @param address the address
67 * @return pointer to the values, can be indexed with GNUNET_ATS_PreferenceKind, 52 * @return pointer to the values, can be indexed with GNUNET_ATS_PreferenceKind,
68 * default preferences if peer does not exist 53 * default preferences if peer does not exist
69 */ 54 */
70const double * 55const double *
71GAS_normalization_get_properties (const struct ATS_Address *address); 56GAS_normalization_get_properties (void *cls,
57 const struct ATS_Address *address);
72 58
73 59
74/** 60/**
@@ -101,14 +87,12 @@ GAS_normalization_normalize_preference (void *client,
101/** 87/**
102 * Update and normalize a atsi performance information 88 * Update and normalize a atsi performance information
103 * 89 *
104 * @param addresses hashmap containing all addresses
105 * @param address the address to update 90 * @param address the address to update
106 * @param atsi the array of performance information 91 * @param atsi the array of performance information
107 * @param atsi_count the number of atsi information in the array 92 * @param atsi_count the number of atsi information in the array
108 */ 93 */
109void 94void
110GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiPeerMap *addresses, 95GAS_normalization_normalize_property (struct ATS_Address *address,
111 struct ATS_Address *address,
112 const struct GNUNET_ATS_Information *atsi, 96 const struct GNUNET_ATS_Information *atsi,
113 uint32_t atsi_count); 97 uint32_t atsi_count);
114 98
@@ -124,24 +108,16 @@ GAS_normalization_preference_client_disconnect (void *client);
124 108
125/** 109/**
126 * Start the normalization component 110 * Start the normalization component
127 *
128 * @param pref_ch_cb callback to call on relative preference changing
129 * @param pref_ch_cb_cls cls for the preference callback
130 * @param property_ch_cb callback to call on relative property changing
131 * @param property_ch_cb_cls cls for the property callback
132 */ 111 */
133void 112void
134GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, 113GAS_normalization_start (void);
135 void *pref_ch_cb_cls,
136 GAS_Normalization_property_changed_cb property_ch_cb,
137 void *property_ch_cb_cls);
138 114
139 115
140/** 116/**
141 * Stop the normalization component and free all items 117 * Stop the normalization component and free all items
142 */ 118 */
143void 119void
144GAS_normalization_stop (); 120GAS_normalization_stop (void);
145
146 121
122#endif
147/* end of gnunet-service-ats_normalization.h */ 123/* end of gnunet-service-ats_normalization.h */
diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c
index e0a5cbdae..c49821227 100644
--- a/src/ats/gnunet-service-ats_performance.c
+++ b/src/ats/gnunet-service-ats_performance.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2011-2014 Christian Grothoff (and other contributing authors) 3 (C) 2011-2015 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -69,6 +69,7 @@ static struct PerformanceClient *pc_head;
69 */ 69 */
70static struct PerformanceClient *pc_tail; 70static struct PerformanceClient *pc_tail;
71 71
72
72/** 73/**
73 * Context for sending messages to performance clients. 74 * Context for sending messages to performance clients.
74 */ 75 */
@@ -92,7 +93,6 @@ find_client (struct GNUNET_SERVER_Client *client)
92 return NULL; 93 return NULL;
93} 94}
94 95
95
96/** 96/**
97 * Unregister a client (which may have been a performance client, 97 * Unregister a client (which may have been a performance client,
98 * but this is not assured). 98 * but this is not assured).
@@ -108,7 +108,6 @@ GAS_performance_remove_client (struct GNUNET_SERVER_Client *client)
108 if (NULL == pc) 108 if (NULL == pc)
109 return; 109 return;
110 GNUNET_CONTAINER_DLL_remove (pc_head, pc_tail, pc); 110 GNUNET_CONTAINER_DLL_remove (pc_head, pc_tail, pc);
111 GAS_addresses_preference_client_disconnect (client);
112 GNUNET_free (pc); 111 GNUNET_free (pc);
113} 112}
114 113
@@ -593,109 +592,6 @@ GAS_handle_reservation_request (void *cls,
593} 592}
594 593
595 594
596/**
597 * Handle 'preference change' messages from clients.
598 *
599 * @param cls unused, NULL
600 * @param client client that sent the request
601 * @param message the request message
602 */
603void
604GAS_handle_preference_change (void *cls,
605 struct GNUNET_SERVER_Client *client,
606 const struct GNUNET_MessageHeader *message)
607{
608 const struct ChangePreferenceMessage *msg;
609 const struct PreferenceInformation *pi;
610 uint16_t msize;
611 uint32_t nump;
612 uint32_t i;
613
614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
615 "Received `%s' message\n",
616 "PREFERENCE_CHANGE");
617 msize = ntohs (message->size);
618 if (msize < sizeof (struct ChangePreferenceMessage))
619 {
620 GNUNET_break (0);
621 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
622 return;
623 }
624 msg = (const struct ChangePreferenceMessage *) message;
625 nump = ntohl (msg->num_preferences);
626 if (msize !=
627 sizeof (struct ChangePreferenceMessage) +
628 nump * sizeof (struct PreferenceInformation))
629 {
630 GNUNET_break (0);
631 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
632 return;
633 }
634 GNUNET_STATISTICS_update (GSA_stats,
635 "# preference change requests processed",
636 1, GNUNET_NO);
637 pi = (const struct PreferenceInformation *) &msg[1];
638 for (i = 0; i < nump; i++)
639 GAS_addresses_preference_change (client,
640 &msg->peer,
641 (enum GNUNET_ATS_PreferenceKind)
642 ntohl (pi[i].preference_kind),
643 pi[i].preference_value);
644 GNUNET_SERVER_receive_done (client, GNUNET_OK);
645}
646
647
648/**
649 * Handle 'preference feedback' messages from clients.
650 *
651 * @param cls unused, NULL
652 * @param client client that sent the request
653 * @param message the request message
654 */
655void
656GAS_handle_preference_feedback (void *cls,
657 struct GNUNET_SERVER_Client *client,
658 const struct GNUNET_MessageHeader *message)
659{
660 const struct FeedbackPreferenceMessage *msg;
661 const struct PreferenceInformation *pi;
662 uint16_t msize;
663 uint32_t nump;
664 uint32_t i;
665
666 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
667 "Received `%s' message\n",
668 "PREFERENCE_FEEDBACK");
669 msize = ntohs (message->size);
670 if (msize < sizeof (struct FeedbackPreferenceMessage))
671 {
672 GNUNET_break (0);
673 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
674 return;
675 }
676 msg = (const struct FeedbackPreferenceMessage *) message;
677 nump = ntohl (msg->num_feedback);
678 if (msize !=
679 sizeof (struct FeedbackPreferenceMessage) +
680 nump * sizeof (struct PreferenceInformation))
681 {
682 GNUNET_break (0);
683 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
684 return;
685 }
686 GNUNET_STATISTICS_update (GSA_stats,
687 "# preference feedbacks requests processed",
688 1, GNUNET_NO);
689 pi = (const struct PreferenceInformation *) &msg[1];
690 for (i = 0; i < nump; i++)
691 GAS_addresses_preference_feedback (client,
692 &msg->peer,
693 GNUNET_TIME_relative_ntoh(msg->scope),
694 (enum GNUNET_ATS_PreferenceKind)
695 ntohl (pi[i].preference_kind),
696 pi[i].preference_value);
697 GNUNET_SERVER_receive_done (client, GNUNET_OK);
698}
699 595
700 596
701/** 597/**
diff --git a/src/ats/gnunet-service-ats_plugins.c b/src/ats/gnunet-service-ats_plugins.c
new file mode 100644
index 000000000..1e234b56d
--- /dev/null
+++ b/src/ats/gnunet-service-ats_plugins.c
@@ -0,0 +1,661 @@
1/*
2 This file is part of GNUnet.
3 (C) 2011-2014 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/**
22 * @file ats/gnunet-service-ats_plugins.c
23 * @brief ats service plugin management
24 * @author Matthias Wachs
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_ats_service.h"
30#include "gnunet-service-ats.h"
31#include "gnunet_statistics_service.h"
32#include "gnunet_ats_plugin.h"
33#include "gnunet-service-ats_addresses.h"
34#include "gnunet-service-ats_performance.h"
35#include "gnunet-service-ats_plugins.h"
36#include "gnunet-service-ats_scheduling.h"
37#include "gnunet-service-ats_normalization.h"
38#include "ats.h"
39
40
41
42/**
43 * Configured ATS solver
44 */
45static int ats_mode;
46
47/**
48 * Solver handle. FIXME: TYPE!?
49 */
50static void *solver;
51
52/**
53 * Solver functions. FIXME.
54 */
55static struct GNUNET_ATS_PluginEnvironment env;
56
57/**
58 * Solver plugin name as string
59 */
60static char *plugin;
61
62
63/**
64 * The preference changed for a peer, update solver.
65 *
66 * @param peer the peer
67 * @param kind the ATS kind
68 * @param pref_rel the new relative preference value
69 */
70void
71GAS_normalized_preference_changed (const struct GNUNET_PeerIdentity *peer,
72 enum GNUNET_ATS_PreferenceKind kind,
73 double pref_rel)
74{
75 /* Tell solver about update */
76 env.sf.s_pref (solver, peer, kind, pref_rel);
77}
78
79
80/**
81 * The relative value for a property changed
82 *
83 * @param address the peer
84 * @param type the ATS type
85 * @param prop_rel the new relative preference value
86 */
87void
88GAS_normalized_property_changed (struct ATS_Address *address,
89 uint32_t type,
90 double prop_rel)
91{
92 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
93 "Normalized property %s for peer `%s' changed to %.3f \n",
94 GNUNET_ATS_print_property_type (type),
95 GNUNET_i2s (&address->peer),
96 prop_rel);
97 env.sf.s_address_update_property (solver,
98 address,
99 type,
100 0,
101 prop_rel);
102}
103
104
105/**
106 * Solver information callback
107 *
108 * @param cls the closure
109 * @param op the operation
110 * @param status operation status
111 * @param add additional information
112 */
113static void
114solver_info_cb (void *cls,
115 enum GAS_Solver_Operation op,
116 enum GAS_Solver_Status status,
117 enum GAS_Solver_Additional_Information add)
118{
119 char *add_info;
120
121 switch (add) {
122 case GAS_INFO_NONE:
123 add_info = "GAS_INFO_NONE";
124 break;
125 case GAS_INFO_FULL:
126 add_info = "GAS_INFO_MLP_FULL";
127 break;
128 case GAS_INFO_UPDATED:
129 add_info = "GAS_INFO_MLP_UPDATED";
130 break;
131 case GAS_INFO_PROP_ALL:
132 add_info = "GAS_INFO_PROP_ALL";
133 break;
134 case GAS_INFO_PROP_SINGLE:
135 add_info = "GAS_INFO_PROP_SINGLE";
136 break;
137 default:
138 add_info = "INVALID";
139 break;
140 }
141 switch (op)
142 {
143 case GAS_OP_SOLVE_START:
144 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
145 "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
146 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL", add_info);
147 return;
148 case GAS_OP_SOLVE_STOP:
149 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
150 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
151 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL", add_info);
152 return;
153
154 case GAS_OP_SOLVE_SETUP_START:
155 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
156 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
157 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
158 return;
159
160 case GAS_OP_SOLVE_SETUP_STOP:
161 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
162 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
163 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
164 return;
165
166 case GAS_OP_SOLVE_MLP_LP_START:
167 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
168 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
169 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
170 return;
171 case GAS_OP_SOLVE_MLP_LP_STOP:
172 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
173 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
174 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
175 return;
176
177 case GAS_OP_SOLVE_MLP_MLP_START:
178 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
179 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
180 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
181 return;
182 case GAS_OP_SOLVE_MLP_MLP_STOP:
183 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
184 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
185 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
186 return;
187 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
188 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
189 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
190 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
191 return;
192 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
193 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
194 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
195 (GAS_STAT_SUCCESS == status) ? "SUCCESS" : "FAIL");
196 return;
197 default:
198 break;
199 }
200}
201
202
203/**
204 * Callback for solver to notify about assignment changes
205 *
206 * @param cls NULL
207 * @param address the address with changes
208 */
209static void
210bandwidth_changed_cb (void *cls,
211 struct ATS_Address *address)
212{
213 uint32_t diff_out;
214 uint32_t diff_in;
215
216 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
217 "Bandwidth assignment changed for peer %s \n",
218 GNUNET_i2s (&address->peer));
219
220 /* Notify performance clients about changes to address */
221 GAS_performance_notify_all_clients (&address->peer,
222 address->plugin,
223 address->addr,
224 address->addr_len,
225 address->active,
226 address->atsi,
227 address->atsi_count,
228 GNUNET_BANDWIDTH_value_init (address->assigned_bw_out),
229 GNUNET_BANDWIDTH_value_init (address->assigned_bw_in));
230
231 if ( (0 == address->assigned_bw_in) &&
232 (0 == address->assigned_bw_out) )
233 {
234 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
235 "Telling transport to disconnect peer `%s'\n",
236 GNUNET_i2s (&address->peer));
237
238 /* Notify scheduling clients about suggestion */
239 GAS_scheduling_transmit_address_suggestion (&address->peer,
240 address->session_id,
241 GNUNET_BANDWIDTH_ZERO,
242 GNUNET_BANDWIDTH_ZERO);
243 return;
244 }
245
246 /* Do bandwidth stability check */
247 diff_out = abs (address->assigned_bw_out - address->last_notified_bw_out);
248 diff_in = abs (address->assigned_bw_in - address->last_notified_bw_in);
249
250 if ( (diff_out < htonl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) &&
251 (diff_in < htonl(GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__)) )
252 return;
253
254 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
255 "Sending bandwidth update for peer `%s': %u %u\n",
256 GNUNET_i2s (&address->peer), address->assigned_bw_out,
257 address->assigned_bw_out);
258
259 /* *Notify scheduling clients about suggestion */
260 GAS_scheduling_transmit_address_suggestion (&address->peer,
261 address->session_id,
262 GNUNET_BANDWIDTH_value_init (address->assigned_bw_out),
263 GNUNET_BANDWIDTH_value_init (address->assigned_bw_in));
264
265 address->last_notified_bw_out = address->assigned_bw_out;
266 address->last_notified_bw_in = address->assigned_bw_in;
267}
268
269
270/**
271 * Load quotas for networks from configuration
272 *
273 * @param cfg configuration handle
274 * @param out_dest where to write outbound quotas
275 * @param in_dest where to write inbound quotas
276 * @param dest_length length of inbound and outbound arrays
277 * @return number of networks loaded
278 */
279static unsigned int
280load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
281 unsigned long long *out_dest, unsigned long long *in_dest, int dest_length)
282{
283 char * entry_in = NULL;
284 char * entry_out = NULL;
285 char * quota_out_str;
286 char * quota_in_str;
287 int c;
288 int res;
289
290 for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
291 {
292 in_dest[c] = 0;
293 out_dest[c] = 0;
294 GNUNET_asprintf (&entry_out,
295 "%s_QUOTA_OUT",
296 GNUNET_ATS_print_network_type (c));
297 GNUNET_asprintf (&entry_in,
298 "%s_QUOTA_IN",
299 GNUNET_ATS_print_network_type (c));
300
301 /* quota out */
302 if (GNUNET_OK
303 == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", entry_out,
304 &quota_out_str))
305 {
306 res = GNUNET_NO;
307 if (0 == strcmp (quota_out_str, GNUNET_ATS_MaxBandwidthString))
308 {
309 out_dest[c] = GNUNET_ATS_MaxBandwidth;
310 res = GNUNET_YES;
311 }
312 if ((GNUNET_NO == res)
313 && (GNUNET_OK
314 == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str,
315 &out_dest[c])))
316 res = GNUNET_YES;
317 if ((GNUNET_NO == res)
318 && (GNUNET_OK
319 == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out,
320 &out_dest[c])))
321 res = GNUNET_YES;
322
323 if (GNUNET_NO == res)
324 {
325 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
326 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
327 GNUNET_ATS_print_network_type (c),
328 quota_out_str,
329 GNUNET_ATS_DefaultBandwidth);
330 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
331 }
332 else
333 {
334 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
335 _("Outbound quota configure for network `%s' is %llu\n"),
336 GNUNET_ATS_print_network_type (c),
337 out_dest[c]);
338 }
339 GNUNET_free(quota_out_str);
340 }
341 else
342 {
343 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
344 _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
345 GNUNET_ATS_print_network_type (c),
346 GNUNET_ATS_DefaultBandwidth);
347 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
348 }
349
350 /* quota in */
351 if (GNUNET_OK
352 == GNUNET_CONFIGURATION_get_value_string (cfg, "ats", entry_in,
353 &quota_in_str))
354 {
355 res = GNUNET_NO;
356 if (0 == strcmp (quota_in_str, GNUNET_ATS_MaxBandwidthString))
357 {
358 in_dest[c] = GNUNET_ATS_MaxBandwidth;
359 res = GNUNET_YES;
360 }
361 if ((GNUNET_NO == res)
362 && (GNUNET_OK
363 == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
364 res = GNUNET_YES;
365 if ((GNUNET_NO == res)
366 && (GNUNET_OK
367 == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in,
368 &in_dest[c])))
369 res = GNUNET_YES;
370
371 if (GNUNET_NO == res)
372 {
373 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
374 _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
375 GNUNET_ATS_print_network_type (c),
376 quota_in_str,
377 GNUNET_ATS_DefaultBandwidth);
378 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
379 }
380 else
381 {
382 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
383 _("Inbound quota configured for network `%s' is %llu\n"),
384 GNUNET_ATS_print_network_type (c),
385 in_dest[c]);
386 }
387 GNUNET_free(quota_in_str);
388 }
389 else
390 {
391 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
392 _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
393 GNUNET_ATS_print_network_type (c),
394 GNUNET_ATS_DefaultBandwidth);
395 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
396 }
397 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
398 "Loaded quota for network `%s' (in/out): %llu %llu\n",
399 GNUNET_ATS_print_network_type (c),
400 in_dest[c],
401 out_dest[c]);
402 GNUNET_free(entry_out);
403 GNUNET_free(entry_in);
404 }
405 return GNUNET_ATS_NetworkTypeCount;
406}
407
408
409/**
410 * Initialize plugins subsystem.
411 *
412 * @param cfg configuration to use
413 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load
414 * solver plugin)
415 */
416int
417GAS_plugins_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
418{
419 unsigned long long quotas_in[GNUNET_ATS_NetworkTypeCount];
420 unsigned long long quotas_out[GNUNET_ATS_NetworkTypeCount];
421 char *mode_str;
422 char *plugin_short;
423 int c;
424
425 /* Figure out configured solution method */
426 if (GNUNET_SYSERR ==
427 GNUNET_CONFIGURATION_get_value_string (cfg, "ats", "MODE", &mode_str))
428 {
429 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
430 "No resource assignment method configured, using proportional approach\n");
431 ats_mode = MODE_PROPORTIONAL;
432 }
433 else
434 {
435 for (c = 0; c < strlen (mode_str); c++)
436 mode_str[c] = toupper (mode_str[c]);
437 if (0 == strcmp (mode_str, "PROPORTIONAL"))
438 ats_mode = MODE_PROPORTIONAL;
439 else if (0 == strcmp (mode_str, "MLP"))
440 {
441 ats_mode = MODE_MLP;
442#if !HAVE_LIBGLPK
443 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
444 "Assignment method `%s' configured, but GLPK is not available, please install \n",
445 mode_str);
446 ats_mode = MODE_PROPORTIONAL;
447#endif
448 }
449 else if (0 == strcmp (mode_str, "RIL"))
450 ats_mode = MODE_RIL;
451 else
452 {
453 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
454 "Invalid resource assignment method `%s' configured, using proportional approach\n",
455 mode_str);
456 ats_mode = MODE_PROPORTIONAL;
457 }
458 GNUNET_free(mode_str);
459 }
460
461 load_quotas (cfg, quotas_out, quotas_in, GNUNET_ATS_NetworkTypeCount);
462 env.info_cb = &solver_info_cb;
463 env.info_cb_cls = NULL;
464 env.bandwidth_changed_cb = &bandwidth_changed_cb;
465 env.bw_changed_cb_cls = NULL;
466 env.get_preferences = &GAS_normalization_get_preferences_by_peer;
467 env.get_preference_cls = NULL;
468 env.get_property = &GAS_normalization_get_properties;
469 env.get_property_cls = NULL;
470 env.cfg = cfg;
471 env.stats = GSA_stats;
472 env.addresses = GSA_addresses;
473
474 env.network_count = GNUNET_ATS_NetworkTypeCount;
475 int networks[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
476 for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
477 {
478 env.networks[c] = networks[c];
479 env.out_quota[c] = quotas_out[c];
480 env.in_quota[c] = quotas_in[c];
481 }
482
483 switch (ats_mode) {
484 case MODE_PROPORTIONAL:
485 plugin_short = "proportional";
486 break;
487 case MODE_MLP:
488 plugin_short = "mlp";
489 break;
490 case MODE_RIL:
491 plugin_short = "ril";
492 break;
493 default:
494 plugin_short = NULL;
495 break;
496 }
497 GNUNET_asprintf (&plugin,
498 "libgnunet_plugin_ats_%s",
499 plugin_short);
500 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
501 "Initializing solver `%s '`%s'\n",
502 plugin_short,
503 plugin);
504 if (NULL == (solver = GNUNET_PLUGIN_load (plugin, &env)))
505 {
506 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
507 _("Failed to initialize solver `%s'!\n"),
508 plugin);
509 return GNUNET_SYSERR;
510 }
511
512
513 GNUNET_assert (NULL != env.sf.s_add);
514 GNUNET_assert (NULL != env.sf.s_address_update_property);
515 GNUNET_assert (NULL != env.sf.s_get);
516 GNUNET_assert (NULL != env.sf.s_get_stop);
517 GNUNET_assert (NULL != env.sf.s_pref);
518 GNUNET_assert (NULL != env.sf.s_feedback);
519 GNUNET_assert (NULL != env.sf.s_del);
520 GNUNET_assert (NULL != env.sf.s_bulk_start);
521 GNUNET_assert (NULL != env.sf.s_bulk_stop);
522
523 if (NULL == solver)
524 {
525 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
526 _("Failed to initialize solver!\n"));
527 return GNUNET_SYSERR;
528 }
529 return GNUNET_OK;
530}
531
532
533/**
534 * Shutdown address subsystem.
535 */
536void
537GAS_plugins_done ()
538{
539 GNUNET_PLUGIN_unload (plugin,
540 solver);
541 solver = NULL;
542 GNUNET_free (plugin);
543 plugin = NULL;
544}
545
546
547void
548GAS_plugin_new_address (struct ATS_Address *new_address,
549 enum GNUNET_ATS_Network_Type addr_net,
550 const struct GNUNET_ATS_Information *atsi,
551 uint32_t atsi_count)
552{
553 env.sf.s_add (solver, new_address, addr_net);
554 env.sf.s_bulk_start (solver);
555 GAS_normalization_normalize_property (new_address,
556 atsi,
557 atsi_count);
558 env.sf.s_bulk_stop (solver);
559}
560
561
562void
563GAS_plugin_update_address (struct ATS_Address *address,
564 const struct GNUNET_ATS_Information *atsi,
565 uint32_t atsi_count)
566{
567 env.sf.s_bulk_start (solver);
568 GAS_normalization_normalize_property (address,
569 atsi,
570 atsi_count);
571 env.sf.s_bulk_stop (solver);
572}
573
574
575void
576GAS_plugin_delete_address (struct ATS_Address *address)
577{
578 env.sf.s_del (solver, address, GNUNET_NO);
579}
580
581
582void
583GAS_plugin_update_preferences (void *client,
584 const struct GNUNET_PeerIdentity *peer,
585 enum GNUNET_ATS_PreferenceKind kind,
586 float score_abs)
587{
588 env.sf.s_bulk_start (solver);
589 /* Tell normalization about change, normalization will call callback if preference changed */
590 GAS_normalization_normalize_preference (client, peer, kind, score_abs);
591 env.sf.s_bulk_stop (solver);
592}
593
594
595void
596GAS_plugin_preference_feedback (void *application,
597 const struct GNUNET_PeerIdentity *peer,
598 const struct GNUNET_TIME_Relative scope,
599 enum GNUNET_ATS_PreferenceKind kind,
600 float score_abs)
601{
602 env.sf.s_feedback (solver,
603 application,
604 peer,
605 scope,
606 kind,
607 score_abs);
608}
609
610
611void
612GAS_plugin_solver_lock ()
613{
614 env.sf.s_bulk_start (solver);
615}
616
617
618void
619GAS_plugin_solver_unlock ()
620{
621 env.sf.s_bulk_start (solver);
622}
623
624
625void
626GAS_plugin_request_connect_start (const struct GNUNET_PeerIdentity *pid)
627{
628 const struct ATS_Address *aa;
629
630 aa = env.sf.s_get (solver, pid);
631 if (NULL == aa)
632 {
633 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
634 "Cannot suggest address for peer `%s'\n",
635 GNUNET_i2s (pid));
636 return;
637 }
638 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
639 "Suggesting address %p for peer `%s'\n",
640 aa,
641 GNUNET_i2s (pid));
642
643 GAS_scheduling_transmit_address_suggestion (pid,
644 aa->session_id,
645 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_out),
646 GNUNET_BANDWIDTH_value_init (aa->assigned_bw_in));
647
648 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
649 "Address %p ready for suggestion\n",
650 aa);
651}
652
653
654void
655GAS_plugin_request_connect_stop (const struct GNUNET_PeerIdentity *pid)
656{
657 env.sf.s_get_stop (solver, pid);
658}
659
660
661/* end of gnunet-service-ats_plugins.c */
diff --git a/src/ats/gnunet-service-ats_plugins.h b/src/ats/gnunet-service-ats_plugins.h
new file mode 100644
index 000000000..a31024b1b
--- /dev/null
+++ b/src/ats/gnunet-service-ats_plugins.h
@@ -0,0 +1,163 @@
1/*
2 This file is part of GNUnet.
3 (C) 2011-2014 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/**
22 * @file ats/gnunet-service-ats_plugins.h
23 * @brief ats service plugin management
24 * @author Matthias Wachs
25 * @author Christian Grothoff
26 */
27#ifndef GNUNET_SERVICE_ATS_PLUGINS_H
28#define GNUNET_SERVICE_ATS_PLUGINS_H
29
30#include "gnunet_util_lib.h"
31#include "gnunet_ats_service.h"
32#include "gnunet-service-ats.h"
33#include "gnunet_statistics_service.h"
34#include "ats.h"
35
36
37/**
38 * Available ressource assignment modes
39 */
40enum ATS_Mode
41{
42 /**
43 * proportional mode:
44 *
45 * Assign each peer an equal amount of bandwidth (bw)
46 *
47 * bw_per_peer = bw_total / #active addresses
48 */
49 MODE_PROPORTIONAL,
50
51 /**
52 * MLP mode:
53 *
54 * Solve ressource assignment as an optimization problem
55 * Uses an mixed integer programming solver
56 */
57 MODE_MLP,
58
59 /**
60 * Reinforcement Learning mode:
61 *
62 * Solve resource assignment using a learning agent
63 */
64 MODE_RIL
65};
66
67
68/**
69 * Initialize address subsystem. The addresses subsystem manages the addresses
70 * known and current performance information. It has a solver component
71 * responsible for the resource allocation. It tells the solver about changes
72 * and receives updates when the solver changes the ressource allocation.
73 *
74 * @param cfg configuration to use
75 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error (failed to load
76 * solver plugin)
77 */
78int
79GAS_plugins_init (const struct GNUNET_CONFIGURATION_Handle *cfg);
80
81
82/**
83 * Shutdown address subsystem.
84 */
85void
86GAS_plugins_done (void);
87
88
89/**
90 * The preference changed for a peer, update solver.
91 *
92 * @param peer the peer
93 * @param kind the ATS kind
94 * @param pref_rel the new relative preference value
95 */
96void
97GAS_normalized_preference_changed (const struct GNUNET_PeerIdentity *peer,
98 enum GNUNET_ATS_PreferenceKind kind,
99 double pref_rel);
100
101
102/**
103 * The relative value for a property changed
104 *
105 * @param address the peer
106 * @param type the ATS type
107 * @param prop_rel the new relative preference value
108 */
109void
110GAS_normalized_property_changed (struct ATS_Address *address,
111 uint32_t type,
112 double prop_rel);
113
114
115void
116GAS_plugin_new_address (struct ATS_Address *new_address,
117 enum GNUNET_ATS_Network_Type addr_net,
118 const struct GNUNET_ATS_Information *atsi,
119 uint32_t atsi_count);
120
121
122void
123GAS_plugin_update_address (struct ATS_Address *address,
124 const struct GNUNET_ATS_Information *atsi,
125 uint32_t atsi_count);
126
127
128void
129GAS_plugin_update_preferences (void *client,
130 const struct GNUNET_PeerIdentity *peer,
131 enum GNUNET_ATS_PreferenceKind kind,
132 float score_abs);
133
134
135void
136GAS_plugin_preference_feedback (void *application,
137 const struct GNUNET_PeerIdentity *peer,
138 const struct GNUNET_TIME_Relative scope,
139 enum GNUNET_ATS_PreferenceKind kind,
140 float score_abs);
141
142
143void
144GAS_plugin_delete_address (struct ATS_Address *address);
145
146
147void
148GAS_plugin_request_connect_start (const struct GNUNET_PeerIdentity *pid);
149
150
151void
152GAS_plugin_request_connect_stop (const struct GNUNET_PeerIdentity *pid);
153
154
155void
156GAS_plugin_solver_lock (void);
157
158
159void
160GAS_plugin_solver_unlock (void);
161
162
163#endif
diff --git a/src/ats/gnunet-service-ats_preferences.c b/src/ats/gnunet-service-ats_preferences.c
new file mode 100644
index 000000000..cf0082f9d
--- /dev/null
+++ b/src/ats/gnunet-service-ats_preferences.c
@@ -0,0 +1,1004 @@
1/*
2 This file is part of GNUnet.
3 (C) 2011-2015 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file ats/gnunet-service-ats_performance.c
23 * @brief ats service, interaction with 'performance' API
24 * @author Matthias Wachs
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet-service-ats.h"
29#include "gnunet-service-ats_addresses.h"
30#include "gnunet-service-ats_performance.h"
31#include "gnunet-service-ats_plugins.h"
32#include "gnunet-service-ats_preferences.h"
33#include "gnunet-service-ats_reservations.h"
34#include "ats.h"
35
36#define LOG(kind,...) GNUNET_log_from (kind, "ats-preferencesx",__VA_ARGS__)
37
38#define PREF_AGING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
39#define PREF_AGING_FACTOR 0.95
40#define PREF_EPSILON 0.01
41
42
43/**
44 * Relative preferences for a peer
45 */
46struct PeerRelative
47{
48 /**
49 * Relative preference values
50 */
51 double f_rel[GNUNET_ATS_PreferenceCount];
52
53 /**
54 * Peer id
55 */
56 struct GNUNET_PeerIdentity id;
57};
58
59
60/**
61 * FIXME
62 */
63struct GAS_Addresses_Preference_Clients
64{
65 /**
66 * Next in DLL
67 */
68 struct GAS_Addresses_Preference_Clients *next;
69
70 /**
71 * Previous in DLL
72 */
73 struct GAS_Addresses_Preference_Clients *prev;
74
75 /**
76 * Peer ID
77 */
78 void *client;
79};
80
81
82/**
83 * Preference requests DLL head
84 */
85static struct GAS_Addresses_Preference_Clients *preference_clients_head;
86
87/**
88 * Preference requests DLL head
89 */
90static struct GAS_Addresses_Preference_Clients *preference_clients_tail;
91
92/**
93 * Preferences clients
94 */
95static int pref_clients;
96
97/**
98 * Default values
99 */
100static struct PeerRelative defvalues;
101
102
103
104/**
105 * Preference client
106 */
107struct PreferenceClient
108{
109 /**
110 * Next in DLL
111 */
112 struct PreferenceClient *prev;
113
114 /**
115 * Next in DLL
116 */
117
118 struct PreferenceClient *next;
119
120 /**
121 * Client handle
122 */
123 void *client;
124
125 /**
126 * Array of sum of absolute preferences for this client
127 */
128 double f_abs_sum[GNUNET_ATS_PreferenceCount];
129
130 /**
131 * Array of sum of relative preferences for this client
132 */
133 double f_rel_sum[GNUNET_ATS_PreferenceCount];
134
135 /**
136 * List of peer preferences for this client
137 */
138
139 /**
140 * Head of peer list
141 */
142 struct PreferencePeer *p_head;
143
144 /**
145 * Tail of peer list
146 */
147 struct PreferencePeer *p_tail;
148};
149
150/**
151 * Preference peer
152 */
153struct PreferencePeer
154{
155 /**
156 * Next in DLL
157 */
158 struct PreferencePeer *next;
159
160 /**
161 * Previous in DLL
162 */
163 struct PreferencePeer *prev;
164
165 /**
166 * Client
167 */
168 struct PreferenceClient *client;
169
170 /**
171 * Peer id
172 */
173 struct GNUNET_PeerIdentity id;
174
175 /**
176 * Absolute preference values for all preference types
177 */
178 double f_abs[GNUNET_ATS_PreferenceCount];
179
180 /**
181 * Relative preference values for all preference types
182 */
183 double f_rel[GNUNET_ATS_PreferenceCount];
184
185 /**
186 * Absolute point of time of next aging process
187 */
188 struct GNUNET_TIME_Absolute next_aging[GNUNET_ATS_PreferenceCount];
189};
190
191
192/**
193 * Hashmap to store peer information for preference normalization
194 */
195static struct GNUNET_CONTAINER_MultiPeerMap *preference_peers;
196
197
198/**
199 * Clients in DLL: head
200 */
201static struct PreferenceClient *pc_head;
202
203/**
204 * Clients in DLL: tail
205 */
206static struct PreferenceClient *pc_tail;
207
208
209
210static struct GNUNET_SCHEDULER_Task * aging_task;
211
212
213
214
215static struct GAS_Addresses_Preference_Clients *
216find_preference_client (void *client)
217{
218 struct GAS_Addresses_Preference_Clients *cur;
219
220 for (cur = preference_clients_head; NULL != cur; cur = cur->next)
221 if (cur->client == client)
222 return cur;
223 return NULL;
224}
225
226
227/**
228 * Update a peer
229 *
230 * @param id peer id
231 * @param kind the kind
232 * @param rp the relative peer struct
233 * @return the new relative preference
234 */
235static void
236update_relative_values_for_peer (const struct GNUNET_PeerIdentity *id,
237 enum GNUNET_ATS_PreferenceKind kind,
238 struct PeerRelative *rp)
239{
240 struct PreferenceClient *c_cur;
241 struct PreferencePeer *p_cur;
242 double f_rel_total;
243 double f_rel_sum;
244 double backup;
245 unsigned int peer_count;
246
247 f_rel_sum = 0.0;
248 f_rel_total = 0.0;
249 peer_count = 0;
250
251 /* For all clients */
252 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
253 {
254 /* For peer entries with this id */
255 for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
256 {
257 f_rel_sum += p_cur->f_rel[kind];
258 if (0 == memcmp (id, &p_cur->id, sizeof(struct GNUNET_PeerIdentity)))
259 {
260 peer_count ++;
261 f_rel_total += p_cur->f_rel[kind];
262 }
263
264 }
265 }
266
267 LOG (GNUNET_ERROR_TYPE_DEBUG,
268 "%u clients have a total relative preference for peer `%s' `%s' of %.3f and for %s in total %.3f\n",
269 peer_count, GNUNET_i2s (id),
270 GNUNET_ATS_print_preference_type (kind),
271 f_rel_total,
272 GNUNET_ATS_print_preference_type (kind),
273 f_rel_sum);
274
275 /* Find entry for the peer containing relative values in the hashmap */
276 if (NULL != rp)
277 {
278 backup = rp->f_rel[kind];
279 if (f_rel_sum > 0)
280 rp->f_rel[kind] = f_rel_total / f_rel_sum;
281 else
282 {
283 /* No client had any preferences for this type and any peer */
284 rp->f_rel[kind] = DEFAULT_REL_PREFERENCE;
285 }
286 if (backup != rp->f_rel[kind])
287 GAS_normalized_preference_changed (&rp->id, kind, rp->f_rel[kind]);
288 }
289}
290
291
292static int
293update_iterator (void *cls,
294 const struct GNUNET_PeerIdentity *key,
295 void *value)
296{
297 enum GNUNET_ATS_PreferenceKind *kind = cls;
298 struct PeerRelative *pr = value;
299
300 update_relative_values_for_peer (key,
301 *kind,
302 pr);
303 return GNUNET_OK;
304}
305
306
307
308/**
309 * Recalculate preference for a specific ATS property
310 *
311 * @param c the preference client
312 * @param kind the preference kind
313 * @return the result
314 */
315static void
316recalculate_relative_preferences (struct PreferenceClient *c,
317 enum GNUNET_ATS_PreferenceKind kind)
318{
319 struct PreferencePeer *p_cur;
320
321 /* For this client: sum of absolute preference values for this preference */
322 c->f_abs_sum[kind] = 0.0;
323 /* For this client: sum of relative preference values for this preference
324 *
325 * Note: this value should also be 1.0, but:
326 * if no preferences exist due to aging, this value can be 0.0
327 * and the client can be removed */
328 c->f_rel_sum[kind] = 0.0;
329
330 for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next)
331 c->f_abs_sum[kind] += p_cur->f_abs[kind];
332 LOG (GNUNET_ERROR_TYPE_DEBUG,
333 "Client %p has sum of total preferences for %s of %.3f\n",
334 c->client, GNUNET_ATS_print_preference_type (kind), c->f_abs_sum[kind]);
335
336 /* For all peers: calculate relative preference */
337 for (p_cur = c->p_head; NULL != p_cur; p_cur = p_cur->next)
338 {
339 /* Calculate relative preference for specific kind */
340
341 /* Every application has a preference for each peer between
342 * [0 .. 1] in relative values
343 * and [0 .. inf] in absolute values */
344 p_cur->f_rel[kind] = p_cur->f_abs[kind] / c->f_abs_sum[kind];
345 c->f_rel_sum[kind] += p_cur->f_rel[kind];
346
347 LOG (GNUNET_ERROR_TYPE_DEBUG,
348 "Client %p has relative preference for %s for peer `%s' of %.3f\n",
349 c->client,
350 GNUNET_ATS_print_preference_type (kind),
351 GNUNET_i2s (&p_cur->id),
352 p_cur->f_rel[kind]);
353 }
354
355}
356
357
358
359static void
360run_preference_update (struct PreferenceClient *c_cur,
361 struct PreferencePeer *p_cur,
362 enum GNUNET_ATS_PreferenceKind kind,
363 float score_abs)
364{
365 double old_value;
366
367 /* Update relative value */
368 old_value = p_cur->f_rel[kind];
369 recalculate_relative_preferences (c_cur, kind);
370 if (p_cur->f_rel[kind] == old_value)
371 return;
372
373 /* Relative preference value changed, recalculate for all peers */
374 GNUNET_CONTAINER_multipeermap_iterate (preference_peers,
375 &update_iterator,
376 &kind);
377}
378
379
380
381
382/**
383 * Reduce absolute preferences since they got old
384 *
385 * @param cls the PreferencePeer
386 * @param tc context
387 */
388static void
389preference_aging (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
390{
391 struct PreferencePeer *p;
392 struct PreferenceClient *cur_client;
393 int i;
394 int values_to_update;
395 double backup;
396
397 aging_task = NULL;
398 values_to_update = 0;
399 cur_client = NULL;
400
401 for (cur_client = pc_head; NULL != cur_client; cur_client = cur_client->next)
402 {
403 for (p = cur_client->p_head; NULL != p; p = p->next)
404 {
405 /* Aging absolute values: */
406 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
407 {
408 if (0
409 == GNUNET_TIME_absolute_get_remaining (p->next_aging[i]).rel_value_us)
410 {
411 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
412 "Aging preference for peer `%s'\n", GNUNET_i2s (&p->id));
413 backup = p->f_abs[i];
414 if (p->f_abs[i] > DEFAULT_ABS_PREFERENCE)
415 p->f_abs[i] *= PREF_AGING_FACTOR;
416
417 if (p->f_abs[i] <= DEFAULT_ABS_PREFERENCE + PREF_EPSILON)
418 p->f_abs[i] = DEFAULT_ABS_PREFERENCE;
419
420 if ( (p->f_abs[i] != DEFAULT_ABS_PREFERENCE) &&
421 (backup != p->f_abs[i]) )
422 {
423 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
424 "Aged preference for peer `%s' from %.3f to %.3f\n",
425 GNUNET_i2s (&p->id), backup, p->f_abs[i]);
426
427 run_preference_update(cur_client, p, i, p->f_abs[i]);
428
429 p->next_aging[i] = GNUNET_TIME_absolute_add (
430 GNUNET_TIME_absolute_get (), PREF_AGING_INTERVAL);
431 values_to_update++;
432 }
433 }
434 }
435 }
436 }
437
438 if (values_to_update > 0)
439 {
440 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
441 "Rescheduling aging task due to %u elements to age\n",
442 values_to_update);
443 aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL,
444 &preference_aging, NULL );
445 }
446 else
447 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
448 "No values to age left, not rescheduling aging task\n");
449
450}
451
452
453/**
454 * Update the absolute preference value for a peer
455 * @param c the client
456 * @param p the peer
457 * @param kind the preference kind
458 * @param score_abs the absolute value
459 * @return the new relative preference value
460 */
461static void
462update_abs_preference (struct PreferenceClient *c,
463 struct PreferencePeer *p,
464 enum GNUNET_ATS_PreferenceKind kind,
465 float score_abs)
466{
467 double score = score_abs;
468
469 /* Update preference value according to type */
470 switch (kind)
471 {
472 case GNUNET_ATS_PREFERENCE_BANDWIDTH:
473 case GNUNET_ATS_PREFERENCE_LATENCY:
474 p->f_abs[kind] = score;
475 /* p->f_abs[kind] = (p->f_abs[kind] + score) / 2; */
476 p->next_aging[kind] = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
477 PREF_AGING_INTERVAL);
478 break;
479 case GNUNET_ATS_PREFERENCE_END:
480 break;
481 default:
482 break;
483 }
484}
485
486
487
488
489
490/**
491 * A performance client disconnected
492 *
493 * @param client the client
494 */
495void
496GAS_addresses_preference_client_disconnect (void *client)
497{
498 struct GAS_Addresses_Preference_Clients *pc;
499
500 if (NULL != (pc = find_preference_client (client)))
501 {
502 GNUNET_CONTAINER_DLL_remove (preference_clients_head,
503 preference_clients_tail,
504 pc);
505 GNUNET_free (pc);
506 GNUNET_assert (pref_clients > 0);
507 pref_clients --;
508 GNUNET_STATISTICS_set (GSA_stats,
509 "# active performance clients",
510 pref_clients,
511 GNUNET_NO);
512 }
513}
514
515
516
517/**
518 * Change the preference for a peer
519 *
520 * @param client the client sending this request
521 * @param peer the peer id
522 * @param kind the preference kind to change
523 * @param score_abs the new preference score
524 */
525void
526GAS_addresses_preference_change (void *client,
527 const struct GNUNET_PeerIdentity *peer,
528 enum GNUNET_ATS_PreferenceKind kind,
529 float score_abs)
530{
531 struct GAS_Addresses_Preference_Clients *pc;
532
533 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
534 "Received `%s' for peer `%s' for client %p\n", "CHANGE PREFERENCE",
535 GNUNET_i2s (peer), client);
536
537 if (GNUNET_NO ==
538 GNUNET_CONTAINER_multipeermap_contains (GSA_addresses,
539 peer))
540 {
541 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
542 "Received `%s' for unknown peer `%s' from client %p\n",
543 "CHANGE PREFERENCE", GNUNET_i2s (peer), client);
544 return;
545 }
546
547 if (NULL == find_preference_client (client))
548 {
549 pc = GNUNET_new (struct GAS_Addresses_Preference_Clients);
550 pc->client = client;
551 GNUNET_CONTAINER_DLL_insert (preference_clients_head,
552 preference_clients_tail,
553 pc);
554 pref_clients ++;
555 GNUNET_STATISTICS_set (GSA_stats,
556 "# active performance clients",
557 pref_clients,
558 GNUNET_NO);
559 }
560 GAS_plugin_update_preferences (client, peer, kind, score_abs);
561}
562
563
564/**
565 * Handle 'preference change' messages from clients.
566 *
567 * @param cls unused, NULL
568 * @param client client that sent the request
569 * @param message the request message
570 */
571void
572GAS_handle_preference_change (void *cls,
573 struct GNUNET_SERVER_Client *client,
574 const struct GNUNET_MessageHeader *message)
575{
576 const struct ChangePreferenceMessage *msg;
577 const struct PreferenceInformation *pi;
578 uint16_t msize;
579 uint32_t nump;
580 uint32_t i;
581
582 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
583 "Received `%s' message\n",
584 "PREFERENCE_CHANGE");
585 msize = ntohs (message->size);
586 if (msize < sizeof (struct ChangePreferenceMessage))
587 {
588 GNUNET_break (0);
589 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
590 return;
591 }
592 msg = (const struct ChangePreferenceMessage *) message;
593 nump = ntohl (msg->num_preferences);
594 if (msize !=
595 sizeof (struct ChangePreferenceMessage) +
596 nump * sizeof (struct PreferenceInformation))
597 {
598 GNUNET_break (0);
599 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
600 return;
601 }
602 GNUNET_STATISTICS_update (GSA_stats,
603 "# preference change requests processed",
604 1, GNUNET_NO);
605 pi = (const struct PreferenceInformation *) &msg[1];
606 for (i = 0; i < nump; i++)
607 GAS_addresses_preference_change (client,
608 &msg->peer,
609 (enum GNUNET_ATS_PreferenceKind)
610 ntohl (pi[i].preference_kind),
611 pi[i].preference_value);
612 GNUNET_SERVER_receive_done (client, GNUNET_OK);
613}
614
615
616
617
618/**
619 * Change the preference for a peer
620 *
621 * @param application the client sending this request
622 * @param peer the peer id
623 * @param scope the time interval for this feedback: [now - scope .. now]
624 * @param kind the preference kind to change
625 * @param score_abs the new preference score
626 */
627void
628GAS_addresses_preference_feedback (void *application,
629 const struct GNUNET_PeerIdentity *peer,
630 const struct GNUNET_TIME_Relative scope,
631 enum GNUNET_ATS_PreferenceKind kind,
632 float score_abs)
633{
634 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
635 "Received `%s' for peer `%s' for client %p\n",
636 "PREFERENCE FEEDBACK",
637 GNUNET_i2s (peer),
638 application);
639
640 if (GNUNET_NO ==
641 GNUNET_CONTAINER_multipeermap_contains (GSA_addresses,
642 peer))
643 {
644 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
645 "Received `%s' for unknown peer `%s' from client %p\n",
646 "PREFERENCE FEEDBACK",
647 GNUNET_i2s (peer),
648 application);
649 return;
650 }
651
652 GAS_plugin_preference_feedback (application,
653 peer,
654 scope,
655 kind,
656 score_abs);
657}
658
659
660/**
661 * Handle 'preference feedback' messages from clients.
662 *
663 * @param cls unused, NULL
664 * @param client client that sent the request
665 * @param message the request message
666 */
667void
668GAS_handle_preference_feedback (void *cls,
669 struct GNUNET_SERVER_Client *client,
670 const struct GNUNET_MessageHeader *message)
671{
672 const struct FeedbackPreferenceMessage *msg;
673 const struct PreferenceInformation *pi;
674 uint16_t msize;
675 uint32_t nump;
676 uint32_t i;
677
678 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
679 "Received `%s' message\n",
680 "PREFERENCE_FEEDBACK");
681 msize = ntohs (message->size);
682 if (msize < sizeof (struct FeedbackPreferenceMessage))
683 {
684 GNUNET_break (0);
685 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
686 return;
687 }
688 msg = (const struct FeedbackPreferenceMessage *) message;
689 nump = ntohl (msg->num_feedback);
690 if (msize !=
691 sizeof (struct FeedbackPreferenceMessage) +
692 nump * sizeof (struct PreferenceInformation))
693 {
694 GNUNET_break (0);
695 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
696 return;
697 }
698 GNUNET_STATISTICS_update (GSA_stats,
699 "# preference feedbacks requests processed",
700 1, GNUNET_NO);
701 pi = (const struct PreferenceInformation *) &msg[1];
702 for (i = 0; i < nump; i++)
703 GAS_addresses_preference_feedback (client,
704 &msg->peer,
705 GNUNET_TIME_relative_ntoh(msg->scope),
706 (enum GNUNET_ATS_PreferenceKind)
707 ntohl (pi[i].preference_kind),
708 pi[i].preference_value);
709 GNUNET_SERVER_receive_done (client, GNUNET_OK);
710}
711
712
713/**
714 * Shutdown preferences subsystem.
715 */
716void
717GAS_preference_init ()
718{
719 int i;
720
721 preference_peers = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
722 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
723 defvalues.f_rel[i] = DEFAULT_REL_PREFERENCE;
724
725}
726
727
728/**
729 * Free a peer
730 *
731 * @param cls unused
732 * @param key the key
733 * @param value RelativePeer
734 * @return #GNUNET_OK to continue
735 */
736static int
737free_peer (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
738{
739 struct PeerRelative *rp = value;
740 if (GNUNET_YES
741 == GNUNET_CONTAINER_multipeermap_remove (preference_peers, key, value))
742 GNUNET_free(rp);
743 else
744 GNUNET_break(0);
745 return GNUNET_OK;
746}
747
748
749static void
750free_client (struct PreferenceClient *pc)
751{
752 struct PreferencePeer *next_p;
753 struct PreferencePeer *p;
754 next_p = pc->p_head;
755 while (NULL != (p = next_p))
756 {
757 next_p = p->next;
758 GNUNET_CONTAINER_DLL_remove(pc->p_head, pc->p_tail, p);
759 GNUNET_free(p);
760 }
761 GNUNET_free(pc);
762}
763
764
765
766
767
768/**
769 * Shutdown preferences subsystem.
770 */
771void
772GAS_preference_done ()
773{
774 struct GAS_Addresses_Preference_Clients *pcur;
775 struct PreferenceClient *pc;
776 struct PreferenceClient *next_pc;
777
778 if (NULL != aging_task)
779 {
780 GNUNET_SCHEDULER_cancel (aging_task);
781 aging_task = NULL;
782 }
783
784 next_pc = pc_head;
785 while (NULL != (pc = next_pc))
786 {
787 next_pc = pc->next;
788 GNUNET_CONTAINER_DLL_remove(pc_head, pc_tail, pc);
789 free_client (pc);
790 }
791
792 GNUNET_CONTAINER_multipeermap_iterate (preference_peers,
793 &free_peer, NULL);
794 GNUNET_CONTAINER_multipeermap_destroy (preference_peers);
795
796 while (NULL != (pcur = preference_clients_head))
797 {
798 GNUNET_CONTAINER_DLL_remove (preference_clients_head,
799 preference_clients_tail,
800 pcur);
801 GNUNET_assert (pref_clients > 0);
802 pref_clients --;
803 GNUNET_STATISTICS_set (GSA_stats,
804 "# active performance clients",
805 pref_clients,
806 GNUNET_NO);
807 GNUNET_free (pcur);
808 }
809}
810
811
812
813
814/**
815 * Normalize an updated preference value
816 *
817 * @param client the client with this preference
818 * @param peer the peer to change the preference for
819 * @param kind the kind to change the preference
820 * @param score_abs the normalized score
821 */
822void
823GAS_normalization_normalize_preference (void *client,
824 const struct GNUNET_PeerIdentity *peer,
825 enum GNUNET_ATS_PreferenceKind kind,
826 float score_abs)
827{
828 struct PreferenceClient *c_cur;
829 struct PreferencePeer *p_cur;
830 struct PeerRelative *r_cur;
831 double old_value;
832 int i;
833
834 LOG (GNUNET_ERROR_TYPE_DEBUG,
835 "Client changes preference for peer `%s' for `%s' to %.2f\n",
836 GNUNET_i2s (peer),
837 GNUNET_ATS_print_preference_type (kind),
838 score_abs);
839
840 if (kind >= GNUNET_ATS_PreferenceCount)
841 {
842 GNUNET_break(0);
843 return;
844 }
845
846 /* Find preference client */
847 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
848 {
849 if (client == c_cur->client)
850 break;
851 }
852 /* Not found: create new preference client */
853 if (NULL == c_cur)
854 {
855 c_cur = GNUNET_new (struct PreferenceClient);
856 c_cur->client = client;
857 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
858 {
859 c_cur->f_abs_sum[i] = DEFAULT_ABS_PREFERENCE;
860 c_cur->f_rel_sum[i] = DEFAULT_REL_PREFERENCE;
861 }
862
863 GNUNET_CONTAINER_DLL_insert(pc_head, pc_tail, c_cur);
864 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding new client %p \n", c_cur);
865 }
866
867 /* Find entry for peer */
868 for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
869 if (0 == memcmp (&p_cur->id, peer, sizeof(p_cur->id)))
870 break;
871
872 /* Not found: create new peer entry */
873 if (NULL == p_cur)
874 {
875 p_cur = GNUNET_new (struct PreferencePeer);
876 p_cur->client = c_cur;
877 p_cur->id = (*peer);
878 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
879 {
880 /* Default value per peer absolute preference for a preference: 0 */
881 p_cur->f_abs[i] = DEFAULT_ABS_PREFERENCE;
882 /* Default value per peer relative preference for a quality: 1.0 */
883 p_cur->f_rel[i] = DEFAULT_REL_PREFERENCE;
884 p_cur->next_aging[i] = GNUNET_TIME_UNIT_FOREVER_ABS;
885 }
886 LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding new peer %p for client %p \n",
887 p_cur, c_cur);
888 GNUNET_CONTAINER_DLL_insert(c_cur->p_head, c_cur->p_tail, p_cur);
889 }
890
891 /* Create struct for peer */
892 if (NULL == GNUNET_CONTAINER_multipeermap_get (preference_peers, peer))
893 {
894 r_cur = GNUNET_new (struct PeerRelative);
895 r_cur->id = (*peer);
896 for (i = 0; i < GNUNET_ATS_PreferenceCount; i++)
897 r_cur->f_rel[i] = DEFAULT_REL_PREFERENCE;
898 GNUNET_assert(
899 GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (preference_peers,
900 &r_cur->id, r_cur, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
901 }
902
903 /* Update absolute value */
904 old_value = p_cur->f_abs[kind];
905 update_abs_preference (c_cur, p_cur, kind, score_abs);
906 if (p_cur->f_abs[kind] == old_value)
907 return;
908
909 run_preference_update (c_cur, p_cur, kind, score_abs);
910
911 /* Start aging task */
912 if (NULL == aging_task)
913 aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL,
914 &preference_aging, NULL );
915
916}
917
918
919/**
920 * Get the normalized preference values for a specific peer or
921 * the default values if
922 *
923 * @param cls ignored
924 * @param id the peer
925 * @return pointer to the values, can be indexed with GNUNET_ATS_PreferenceKind,
926 * default preferences if peer does not exist
927 */
928const double *
929GAS_normalization_get_preferences_by_peer (void *cls,
930 const struct GNUNET_PeerIdentity *id)
931{
932 GNUNET_assert(NULL != preference_peers);
933 GNUNET_assert(NULL != id);
934
935 struct PeerRelative *rp;
936 if (NULL == (rp = GNUNET_CONTAINER_multipeermap_get (preference_peers, id)))
937 {
938 return defvalues.f_rel;
939 }
940 return rp->f_rel;
941}
942
943
944/**
945 * Get the normalized preference values for a specific client and peer
946 *
947 * @param client client
948 * @param peer the peer
949 * @param pref the preference type
950 * @return the value
951 */
952double
953GAS_normalization_get_preferences_by_client (const void *client,
954 const struct GNUNET_PeerIdentity *peer,
955 enum GNUNET_ATS_PreferenceKind pref)
956{
957 struct PreferenceClient *c_cur;
958 struct PreferencePeer *p_cur;
959
960 /* Find preference client */
961 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
962 {
963 if (client == c_cur->client)
964 break;
965 }
966 if (NULL == c_cur)
967 return -1.0;
968
969 for (p_cur = c_cur->p_head; NULL != p_cur; p_cur = p_cur->next)
970 {
971 if (0 == memcmp (peer, &p_cur->id, sizeof (struct GNUNET_PeerIdentity)))
972 break;
973 }
974 if (NULL == p_cur)
975 return DEFAULT_REL_PREFERENCE; /* Not found, return default */
976
977 return p_cur->f_rel[pref];
978}
979
980
981
982/**
983 * A performance client disconnected
984 *
985 * @param client the client
986 */
987void
988GAS_normalization_preference_client_disconnect (void *client)
989{
990 struct PreferenceClient *c_cur;
991 /* Find preference client */
992
993 for (c_cur = pc_head; NULL != c_cur; c_cur = c_cur->next)
994 {
995 if (client == c_cur->client)
996 break;
997 }
998 if (NULL == c_cur)
999 return;
1000
1001 GNUNET_CONTAINER_DLL_remove(pc_head, pc_tail, c_cur);
1002 free_client (c_cur);
1003}
1004
diff --git a/src/ats/gnunet-service-ats_preferences.h b/src/ats/gnunet-service-ats_preferences.h
new file mode 100644
index 000000000..bab604d21
--- /dev/null
+++ b/src/ats/gnunet-service-ats_preferences.h
@@ -0,0 +1,101 @@
1/*
2 This file is part of GNUnet.
3 (C) 2011-2014 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/**
22 * @file ats/gnunet-service-ats_preferences.h
23 * @brief FIXME
24 * @author Matthias Wachs
25 * @author Christian Grothoff
26 */
27#ifndef GNUNET_SERVICE_ATS_PREFERENCES_H
28#define GNUNET_SERVICE_ATS_PREFERENCES_H
29
30#include "gnunet_util_lib.h"
31#include "gnunet_ats_service.h"
32#include "gnunet-service-ats.h"
33#include "gnunet_statistics_service.h"
34#include "ats.h"
35
36
37#define DEFAULT_ABS_PREFERENCE 0.0
38
39#define DEFAULT_REL_PREFERENCE 0.0
40
41
42
43
44/**
45 * A preference client disconnected
46 *
47 * @param client the client; FIXME: type!?
48 */
49void
50GAS_addresses_preference_client_disconnect (void *client);
51
52
53
54
55/**
56 * Change the preference for a peer
57 *
58 * @param client the client sending this request; FIXME: type!?
59 * @param peer the peer id
60 * @param kind the preference kind to change
61 * @param score_abs the new preference score
62 */
63void
64GAS_addresses_preference_change (void *client,
65 const struct GNUNET_PeerIdentity *peer,
66 enum GNUNET_ATS_PreferenceKind kind,
67 float score_abs);
68
69
70/**
71 * Application feedback on how good preference requirements are fulfilled
72 * for a specific preference in the given time scope [now - scope .. now]
73 *
74 * An application notifies ATS if (and only if) it has feedback information
75 * for a specific property. This value is valid until the feedback score is
76 * updated by the application.
77 *
78 * If the application has no feedback for this preference kind the application
79 * will not explicitly call.
80 *
81 * @param application the application sending this request; FIXME: type?
82 * @param peer the peer id
83 * @param scope the time interval this valid for: [now - scope .. now]
84 * @param kind the preference kind this feedback is intended for
85 * @param score_abs the new preference score
86 */
87void
88GAS_addresses_preference_feedback (void *application,
89 const struct GNUNET_PeerIdentity *peer,
90 const struct GNUNET_TIME_Relative scope,
91 enum GNUNET_ATS_PreferenceKind kind,
92 float score_abs);
93
94/**
95 * Shutdown preferences subsystem.
96 */
97void
98GAS_preference_done (void);
99
100
101#endif
diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c
index 9d7562e7b..e1e60c063 100644
--- a/src/ats/gnunet-service-ats_scheduling.c
+++ b/src/ats/gnunet-service-ats_scheduling.c
@@ -99,7 +99,8 @@ GAS_scheduling_transmit_address_suggestion (const struct GNUNET_PeerIdentity *pe
99 if (NULL == my_client) 99 if (NULL == my_client)
100 return; 100 return;
101 GNUNET_STATISTICS_update (GSA_stats, 101 GNUNET_STATISTICS_update (GSA_stats,
102 "# address suggestions made", 1, 102 "# address suggestions made",
103 1,
103 GNUNET_NO); 104 GNUNET_NO);
104 msg.header.size = htons (sizeof (struct AddressSuggestionMessage)); 105 msg.header.size = htons (sizeof (struct AddressSuggestionMessage));
105 msg.header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION); 106 msg.header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION);
@@ -179,7 +180,7 @@ GAS_handle_address_add (void *cls,
179 plugin_name, 180 plugin_name,
180 address, 181 address,
181 address_length, 182 address_length,
182 ntohl(m->address_local_info), 183 ntohl (m->address_local_info),
183 ntohl (m->session_id), 184 ntohl (m->session_id),
184 atsi, ats_count); 185 atsi, ats_count);
185 GNUNET_SERVER_receive_done (client, GNUNET_OK); 186 GNUNET_SERVER_receive_done (client, GNUNET_OK);
diff --git a/src/ats/gnunet-service-ats_scheduling.h b/src/ats/gnunet-service-ats_scheduling.h
index fe8adc8c5..eab9819cf 100644
--- a/src/ats/gnunet-service-ats_scheduling.h
+++ b/src/ats/gnunet-service-ats_scheduling.h
@@ -51,19 +51,6 @@ GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client);
51 51
52 52
53/** 53/**
54 * Handle 'reset backoff' messages from clients.
55 *
56 * @param cls unused, NULL
57 * @param client client that sent the request
58 * @param message the request message
59 */
60void
61GAS_handle_reset_backoff (void *cls,
62 struct GNUNET_SERVER_Client *client,
63 const struct GNUNET_MessageHeader *message);
64
65
66/**
67 * Transmit the given address suggestion and bandwidth update to all scheduling 54 * Transmit the given address suggestion and bandwidth update to all scheduling
68 * clients. 55 * clients.
69 * 56 *
@@ -106,19 +93,6 @@ GAS_handle_address_update (void *cls,
106 93
107 94
108/** 95/**
109 * Handle 'address in use' messages from clients.
110 *
111 * @param cls unused, NULL
112 * @param client client that sent the request
113 * @param message the request message
114 */
115void
116GAS_handle_address_in_use (void *cls,
117 struct GNUNET_SERVER_Client *client,
118 const struct GNUNET_MessageHeader *message);
119
120
121/**
122 * Handle 'address destroyed' messages from clients. 96 * Handle 'address destroyed' messages from clients.
123 * 97 *
124 * @param cls unused, NULL 98 * @param cls unused, NULL
diff --git a/src/ats/perf_ats_solver.c b/src/ats/perf_ats_solver.c
index d25d5da58..769acea99 100644
--- a/src/ats/perf_ats_solver.c
+++ b/src/ats/perf_ats_solver.c
@@ -27,6 +27,7 @@
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_statistics_service.h" 28#include "gnunet_statistics_service.h"
29#include "gnunet-service-ats_addresses.h" 29#include "gnunet-service-ats_addresses.h"
30#include "gnunet-service-ats_plugins.h"
30#include "gnunet-service-ats_normalization.h" 31#include "gnunet-service-ats_normalization.h"
31#include "gnunet_ats_service.h" 32#include "gnunet_ats_service.h"
32#include "gnunet_ats_plugin.h" 33#include "gnunet_ats_plugin.h"
@@ -40,6 +41,11 @@
40 41
41 42
42/** 43/**
44 * Handle for statistics.
45 */
46struct GNUNET_STATISTICS_Handle *GSA_stats;
47
48/**
43 * Handle for ATS address component 49 * Handle for ATS address component
44 */ 50 */
45struct PerfHandle 51struct PerfHandle
@@ -385,7 +391,6 @@ perf_update_address (struct ATS_Address *cur)
385 default: 391 default:
386 break; 392 break;
387 } 393 }
388 ph.env.sf.s_address_update_inuse (ph.solver, cur, GNUNET_YES);
389} 394}
390 395
391 396
@@ -411,22 +416,17 @@ bandwidth_changed_cb (void *cls,
411const double * 416const double *
412get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id) 417get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
413{ 418{
414 return GAS_normalization_get_preferences_by_peer (id); 419 return GAS_normalization_get_preferences_by_peer (NULL, id);
415} 420}
416 421
417 422
418const double * 423const double *
419get_property_cb (void *cls, const struct ATS_Address *address) 424get_property_cb (void *cls, const struct ATS_Address *address)
420{ 425{
421 return GAS_normalization_get_properties ((struct ATS_Address *) address); 426 return GAS_normalization_get_properties (NULL,
427 address);
422} 428}
423 429
424static void
425normalized_property_changed_cb (void *cls, struct ATS_Address *peer,
426 uint32_t type, double prop_rel)
427{
428 /* TODO */
429}
430 430
431static void 431static void
432perf_address_initial_update (void *solver, 432perf_address_initial_update (void *solver,
@@ -1284,7 +1284,7 @@ run (void *cls, char * const *args, const char *cfgfile,
1284 ph.env.out_quota[c], 1284 ph.env.out_quota[c],
1285 ph.env.in_quota[c]); 1285 ph.env.in_quota[c]);
1286 } 1286 }
1287 GAS_normalization_start (NULL, NULL, &normalized_property_changed_cb, NULL ); 1287 GAS_normalization_start ();
1288 1288
1289 GNUNET_asprintf (&plugin, "libgnunet_plugin_ats_%s", ph.ats_string); 1289 GNUNET_asprintf (&plugin, "libgnunet_plugin_ats_%s", ph.ats_string);
1290 GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Initializing solver `%s'\n"), ph.ats_string); 1290 GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Initializing solver `%s'\n"), ph.ats_string);
diff --git a/src/ats/plugin_ats_mlp.c b/src/ats/plugin_ats_mlp.c
index 15fa5e6bd..eeffb3454 100644
--- a/src/ats/plugin_ats_mlp.c
+++ b/src/ats/plugin_ats_mlp.c
@@ -2043,131 +2043,6 @@ GAS_mlp_address_property_changed (void *solver,
2043 2043
2044 2044
2045/** 2045/**
2046 * Transport session for this address has changed
2047 *
2048 * NOTE: values in addresses are already updated
2049 *
2050 * @param solver solver handle
2051 * @param address the address
2052 * @param cur_session the current session
2053 * @param new_session the new session
2054 */
2055static void
2056GAS_mlp_address_session_changed (void *solver,
2057 struct ATS_Address *address,
2058 uint32_t cur_session,
2059 uint32_t new_session)
2060{
2061 /* Nothing to do here */
2062 return;
2063}
2064
2065
2066/**
2067 * Network scope for this address has changed
2068 *
2069 * NOTE: values in addresses are already updated
2070 *
2071 * @param solver solver handle
2072 * @param address the address
2073 * @param current_network the current network
2074 * @param new_network the new network
2075 */
2076static void
2077GAS_mlp_address_change_network (void *solver,
2078 struct ATS_Address *address,
2079 uint32_t current_network,
2080 uint32_t new_network)
2081{
2082 struct MLP_information *mlpi = address->solver_information;
2083 struct GAS_MLP_Handle *mlp = solver;
2084 int nets_avail[] = GNUNET_ATS_NetworkType;
2085 int c1;
2086
2087 GNUNET_assert (NULL != solver);
2088 GNUNET_assert (NULL != address);
2089
2090 if (GNUNET_ATS_NetworkTypeCount <= new_network)
2091 {
2092 GNUNET_break (0);
2093 return;
2094 }
2095
2096 if (NULL == mlpi)
2097 {
2098 GNUNET_break (0);
2099 return;
2100 }
2101
2102 if (mlpi->c_b == MLP_UNDEFINED)
2103 return; /* This address is not yet in the matrix*/
2104
2105 if (NULL ==
2106 GNUNET_CONTAINER_multipeermap_get (mlp->requested_peers,
2107 &address->peer))
2108 {
2109 /* Peer is not requested, so no need to update problem */
2110 GNUNET_break (0);
2111 return;
2112 }
2113
2114 if (current_network == new_network)
2115 {
2116 GNUNET_break (0);
2117 return;
2118 }
2119
2120 for (c1 = 0; c1 < GNUNET_ATS_NetworkTypeCount ; c1 ++)
2121 {
2122 if (nets_avail[c1] == new_network)
2123 break;
2124 }
2125
2126 if (GNUNET_ATS_NetworkTypeCount == c1)
2127 {
2128 /* Invalid network */
2129 GNUNET_break (0);
2130 return;
2131 }
2132
2133 LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating network for peer `%s' from `%s' to `%s'\n",
2134 GNUNET_i2s (&address->peer),
2135 GNUNET_ATS_print_network_type(current_network),
2136 GNUNET_ATS_print_network_type(new_network));
2137
2138 for (c1 = 0; c1 < GNUNET_ATS_NetworkTypeCount; c1++)
2139 {
2140 if (mlp->pv.quota_index[c1] == current_network)
2141 {
2142 /* Remove from old network */
2143 mlp_create_problem_update_value (&mlp->p,
2144 mlp->p.r_quota[c1],
2145 mlpi->c_b, 0.0, __LINE__);
2146 break;
2147 }
2148 }
2149
2150 for (c1 = 0; c1 < GNUNET_ATS_NetworkTypeCount; c1++)
2151 {
2152 if (mlp->pv.quota_index[c1] == new_network)
2153 {
2154 /* Remove from old network */
2155 if (GNUNET_SYSERR == mlp_create_problem_update_value (&mlp->p,
2156 mlp->p.r_quota[c1],
2157 mlpi->c_b, 1.0, __LINE__))
2158 {
2159 /* This quota did not exist in the problem, recreate */
2160 GNUNET_break (0);
2161 }
2162 break;
2163 }
2164 }
2165
2166 mlp->stat_mlp_prob_changed = GNUNET_YES;
2167}
2168
2169
2170/**
2171 * Find the active address in the set of addresses of a peer 2046 * Find the active address in the set of addresses of a peer
2172 * @param cls destination 2047 * @param cls destination
2173 * @param key peer id 2048 * @param key peer id
@@ -2953,8 +2828,6 @@ libgnunet_plugin_ats_mlp_init (void *cls)
2953 mlp->env = env; 2828 mlp->env = env;
2954 env->sf.s_add = &GAS_mlp_address_add; 2829 env->sf.s_add = &GAS_mlp_address_add;
2955 env->sf.s_address_update_property = &GAS_mlp_address_property_changed; 2830 env->sf.s_address_update_property = &GAS_mlp_address_property_changed;
2956 env->sf.s_address_update_session = &GAS_mlp_address_session_changed;
2957 env->sf.s_address_update_network = &GAS_mlp_address_change_network;
2958 env->sf.s_get = &GAS_mlp_get_preferred_address; 2831 env->sf.s_get = &GAS_mlp_get_preferred_address;
2959 env->sf.s_get_stop = &GAS_mlp_stop_get_preferred_address; 2832 env->sf.s_get_stop = &GAS_mlp_stop_get_preferred_address;
2960 env->sf.s_pref = &GAS_mlp_address_change_preference; 2833 env->sf.s_pref = &GAS_mlp_address_change_preference;
diff --git a/src/ats/plugin_ats_proportional.c b/src/ats/plugin_ats_proportional.c
index 7bcc948b7..cc5a55ebb 100644
--- a/src/ats/plugin_ats_proportional.c
+++ b/src/ats/plugin_ats_proportional.c
@@ -713,7 +713,6 @@ find_best_address_it (void *cls,
713 struct FindBestAddressCtx *ctx = cls; 713 struct FindBestAddressCtx *ctx = cls;
714 struct ATS_Address *current = value; 714 struct ATS_Address *current = value;
715 struct ATS_Address *current_best = current; 715 struct ATS_Address *current_best = current;
716 struct GNUNET_TIME_Absolute now;
717 struct AddressSolverInformation *asi; 716 struct AddressSolverInformation *asi;
718 struct GNUNET_TIME_Relative active_time; 717 struct GNUNET_TIME_Relative active_time;
719 struct GNUNET_TIME_Relative min_active_time; 718 struct GNUNET_TIME_Relative min_active_time;
@@ -727,20 +726,6 @@ find_best_address_it (void *cls,
727 726
728 current_best = NULL; 727 current_best = NULL;
729 asi = current->solver_information; 728 asi = current->solver_information;
730 now = GNUNET_TIME_absolute_get ();
731
732 if ((current->active == GNUNET_NO)
733 && (current->blocked_until.abs_value_us
734 == GNUNET_TIME_absolute_max (now, current->blocked_until).abs_value_us))
735 {
736 /* This address is blocked for suggestion */
737 LOG (GNUNET_ERROR_TYPE_DEBUG,
738 "Address %p blocked for suggestion for %s \n",
739 current,
740 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_difference (now, current->blocked_until),
741 GNUNET_YES));
742 return GNUNET_OK;
743 }
744 if (NULL == asi) 729 if (NULL == asi)
745 { 730 {
746 GNUNET_break (0); 731 GNUNET_break (0);
@@ -1695,143 +1680,6 @@ GAS_proportional_address_property_changed (void *solver,
1695 } 1680 }
1696} 1681}
1697 1682
1698/**
1699 * Transport session for this address has changed
1700 *
1701 * NOTE: values in addresses are already updated
1702 *
1703 * @param solver solver handle
1704 * @param address the address
1705 * @param cur_session the current session
1706 * @param new_session the new session
1707 */
1708static void
1709GAS_proportional_address_session_changed (void *solver,
1710 struct ATS_Address *address,
1711 uint32_t cur_session,
1712 uint32_t new_session)
1713{
1714 struct GAS_PROPORTIONAL_Handle *s = solver;
1715 struct ATS_Address *best_address;
1716 struct ATS_Address *active_address;
1717 struct AddressSolverInformation *asi;
1718
1719 if (cur_session != new_session)
1720 {
1721 LOG (GNUNET_ERROR_TYPE_DEBUG,
1722 "Session changed from %u to %u\n",
1723 cur_session,
1724 new_session);
1725 }
1726
1727 if (NULL == address->solver_information)
1728 {
1729 GNUNET_break (0);
1730 return;
1731 }
1732
1733 if (GNUNET_NO ==
1734 GNUNET_CONTAINER_multipeermap_contains (s->requests, &address->peer))
1735 return; /* Peer is not requested */
1736
1737 /* This peer is requested, find active and best address */
1738 active_address = get_active_address (s, s->addresses, &address->peer);
1739 best_address = update_active_address (s, &address->peer);
1740
1741 if ((NULL != best_address) && ((NULL != active_address) &&
1742 (GNUNET_YES == address_eq (active_address, best_address))))
1743 {
1744 asi = best_address->solver_information;
1745 GNUNET_assert (NULL != asi);
1746
1747 /* We sticked to the same address, therefore redistribute */
1748 distribute_bandwidth_in_network (s, asi->network);
1749 }
1750}
1751
1752
1753/**
1754 * Network scope for this address has changed
1755 *
1756 * NOTE: values in addresses are already updated
1757 *
1758 * @param solver solver handle
1759 * @param address the address
1760 * @param current_network the current network
1761 * @param new_network the new network
1762 */
1763static void
1764GAS_proportional_address_change_network (void *solver,
1765 struct ATS_Address *address,
1766 uint32_t current_network,
1767 uint32_t new_network)
1768{
1769 struct GAS_PROPORTIONAL_Handle *s = solver;
1770 struct AddressSolverInformation *asi;
1771 int save_active = GNUNET_NO;
1772
1773 if (current_network == new_network)
1774 {
1775 GNUNET_break(0);
1776 return;
1777 }
1778
1779 asi = address->solver_information;
1780 if (NULL == asi)
1781 {
1782 GNUNET_break(0);
1783 return;
1784 }
1785
1786 /* Network changed */
1787 LOG(GNUNET_ERROR_TYPE_DEBUG,
1788 "Network type changed, moving %s address from `%s' to `%s'\n",
1789 (GNUNET_YES == address->active) ? "active" : "inactive",
1790 GNUNET_ATS_print_network_type (current_network),
1791 GNUNET_ATS_print_network_type (new_network));
1792
1793
1794 /* Start bulk to prevent disconnect */
1795 GAS_proportional_bulk_start(s);
1796
1797 save_active = address->active;
1798
1799 /* Disable and assign no bandwidth */
1800 address->active = GNUNET_NO;
1801 address->assigned_bw_in = 0; /* no bandwidth assigned */
1802 address->assigned_bw_out = 0; /* no bandwidth assigned */
1803
1804 /* Remove from old network */
1805 GAS_proportional_address_delete (solver, address, GNUNET_NO);
1806
1807 /* Set new network type */
1808 if (NULL == get_network (solver, new_network))
1809 {
1810 /* Address changed to invalid network... */
1811 LOG(GNUNET_ERROR_TYPE_ERROR,
1812 _("Invalid network type `%u' `%s': Disconnect!\n"), new_network,
1813 GNUNET_ATS_print_network_type (new_network));
1814 s->bw_changed (s->bw_changed_cls, address);
1815 }
1816 else
1817 {
1818 /* Add to new network and update*/
1819 GAS_proportional_address_add (solver, address, new_network);
1820 }
1821 GAS_proportional_bulk_stop (s);
1822
1823 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (s->requests, &address->peer))
1824 return; /* Peer is not requested */
1825
1826 /* Find new address to suggest */
1827 if (GNUNET_YES == save_active)
1828 {
1829 /* No address available, therefore disconnect */
1830 if (NULL == update_active_address (s, &address->peer))
1831 s->bw_changed (s->bw_changed_cls, address);
1832 }
1833
1834}
1835 1683
1836/** 1684/**
1837 * Add a new single address to a network 1685 * Add a new single address to a network
@@ -1914,8 +1762,6 @@ libgnunet_plugin_ats_proportional_init (void *cls)
1914 s->env = env; 1762 s->env = env;
1915 env->sf.s_add = &GAS_proportional_address_add; 1763 env->sf.s_add = &GAS_proportional_address_add;
1916 env->sf.s_address_update_property = &GAS_proportional_address_property_changed; 1764 env->sf.s_address_update_property = &GAS_proportional_address_property_changed;
1917 env->sf.s_address_update_session = &GAS_proportional_address_session_changed;
1918 env->sf.s_address_update_network = &GAS_proportional_address_change_network;
1919 env->sf.s_get = &GAS_proportional_get_preferred_address; 1765 env->sf.s_get = &GAS_proportional_get_preferred_address;
1920 env->sf.s_get_stop = &GAS_proportional_stop_get_preferred_address; 1766 env->sf.s_get_stop = &GAS_proportional_stop_get_preferred_address;
1921 env->sf.s_pref = &GAS_proportional_address_change_preference; 1767 env->sf.s_pref = &GAS_proportional_address_change_preference;
diff --git a/src/ats/plugin_ats_ril.c b/src/ats/plugin_ats_ril.c
index 5c396e82e..31bed2a27 100644
--- a/src/ats/plugin_ats_ril.c
+++ b/src/ats/plugin_ats_ril.c
@@ -2386,74 +2386,6 @@ GAS_ril_address_property_changed (void *solver,
2386 2386
2387 2387
2388/** 2388/**
2389 * Update the session of an address in the solver
2390 *
2391 * NOTE: values in addresses are already updated
2392 *
2393 * @param solver solver handle
2394 * @param address the address
2395 * @param cur_session the current session
2396 * @param new_session the new session
2397 */
2398static void
2399GAS_ril_address_session_changed (void *solver,
2400 struct ATS_Address *address,
2401 uint32_t cur_session,
2402 uint32_t new_session)
2403{
2404 LOG(GNUNET_ERROR_TYPE_DEBUG,
2405 "API_address_session_changed()\n");
2406}
2407
2408
2409/**
2410 * Notify solver that the network an address is located in has changed
2411 *
2412 * NOTE: values in addresses are already updated
2413 *
2414 * @param solver solver handle
2415 * @param address the address
2416 * @param current_network the current network
2417 * @param new_network the new network
2418 */
2419static void
2420GAS_ril_address_change_network (void *solver,
2421 struct ATS_Address *address,
2422 uint32_t current_network,
2423 uint32_t new_network)
2424{
2425 struct GAS_RIL_Handle *s = solver;
2426 struct RIL_Peer_Agent *agent;
2427
2428 LOG(GNUNET_ERROR_TYPE_DEBUG,
2429 "API_address_change_network() Network type changed, moving "
2430 "%s address of peer %s from '%s' to '%s'\n",
2431 (GNUNET_YES == address->active) ? "active" : "inactive", GNUNET_i2s (&address->peer),
2432 GNUNET_ATS_print_network_type (current_network), GNUNET_ATS_print_network_type (new_network));
2433
2434 s->parameters.temperature = s->parameters.temperature_init;
2435 s->parameters.epsilon = s->parameters.epsilon_init;
2436
2437 if (address->active && !ril_network_is_active (solver, new_network))
2438 {
2439 GAS_ril_address_delete (solver, address, GNUNET_NO);
2440 return;
2441 }
2442
2443 agent = ril_get_agent (s, &address->peer, GNUNET_NO);
2444 if (NULL == agent)
2445 {
2446 GNUNET_assert(!ril_network_is_active (solver, current_network));
2447
2448 GAS_ril_address_add (s, address, new_network);
2449 return;
2450 }
2451
2452 address->solver_information = ril_get_network(solver, new_network);
2453}
2454
2455
2456/**
2457 * Give feedback about the current assignment 2389 * Give feedback about the current assignment
2458 * 2390 *
2459 * @param solver the solver handle 2391 * @param solver the solver handle
@@ -2850,8 +2782,6 @@ libgnunet_plugin_ats_ril_init (void *cls)
2850 2782
2851 env->sf.s_add = &GAS_ril_address_add; 2783 env->sf.s_add = &GAS_ril_address_add;
2852 env->sf.s_address_update_property = &GAS_ril_address_property_changed; 2784 env->sf.s_address_update_property = &GAS_ril_address_property_changed;
2853 env->sf.s_address_update_session = &GAS_ril_address_session_changed;
2854 env->sf.s_address_update_network = &GAS_ril_address_change_network;
2855 env->sf.s_get = &GAS_ril_get_preferred_address; 2785 env->sf.s_get = &GAS_ril_get_preferred_address;
2856 env->sf.s_get_stop = &GAS_ril_stop_get_preferred_address; 2786 env->sf.s_get_stop = &GAS_ril_stop_get_preferred_address;
2857 env->sf.s_pref = &GAS_ril_address_change_preference; 2787 env->sf.s_pref = &GAS_ril_address_change_preference;
diff --git a/src/include/gnunet_ats_plugin.h b/src/include/gnunet_ats_plugin.h
index 02875a070..e2272fdc8 100644
--- a/src/include/gnunet_ats_plugin.h
+++ b/src/include/gnunet_ats_plugin.h
@@ -128,34 +128,6 @@ typedef void
128 struct ATS_Address *address, uint32_t type, uint32_t abs_value, 128 struct ATS_Address *address, uint32_t type, uint32_t abs_value,
129 double rel_value); 129 double rel_value);
130 130
131/**
132 * Transport session for this address has changed
133 *
134 * NOTE: values in addresses are already updated
135 *
136 * @param solver solver handle
137 * @param address the address
138 * @param cur_session the current session
139 * @param new_session the new session
140 */
141typedef void
142(*GAS_solver_address_session_changed) (void *solver,
143 struct ATS_Address *address, uint32_t cur_session, uint32_t new_session);
144
145
146/**
147 * Network scope for this address has changed
148 *
149 * NOTE: values in addresses are already updated
150 *
151 * @param solver solver handle
152 * @param address the address
153 * @param current_network the current network
154 * @param new_network the new network
155 */
156typedef void
157(*GAS_solver_address_network_changed) (void *solver,
158 struct ATS_Address *address, uint32_t current_network, uint32_t new_network);
159 131
160/** 132/**
161 * Get the prefered address for a peer from solver 133 * Get the prefered address for a peer from solver
@@ -201,16 +173,6 @@ struct GNUNET_ATS_SolverFunctions
201 GAS_solver_address_property_changed s_address_update_property; 173 GAS_solver_address_property_changed s_address_update_property;
202 174
203 /** 175 /**
204 * Update the session of an address in the solver
205 */
206 GAS_solver_address_session_changed s_address_update_session;
207
208 /**
209 * Notify solver that the network an address is located in has changed
210 */
211 GAS_solver_address_network_changed s_address_update_network;
212
213 /**
214 * Tell solver to notify ATS if the address to use changes for a specific 176 * Tell solver to notify ATS if the address to use changes for a specific
215 * peer using the bandwidth changed callback 177 * peer using the bandwidth changed callback
216 * 178 *
diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h
index 380a2a7af..8c3c5361e 100644
--- a/src/include/gnunet_ats_service.h
+++ b/src/include/gnunet_ats_service.h
@@ -704,14 +704,16 @@ struct GNUNET_ATS_ReservationContext;
704 * @param amount reserve N bytes for receiving, negative 704 * @param amount reserve N bytes for receiving, negative
705 * amounts can be used to undo a (recent) reservation; 705 * amounts can be used to undo a (recent) reservation;
706 * @param rcb function to call with the resulting reservation information 706 * @param rcb function to call with the resulting reservation information
707 * @param rcb_cls closure for info 707 * @param rcb_cls closure for @a rcb
708 * @return NULL on error 708 * @return NULL on error
709 * @deprecated will be replaced soon 709 * @deprecated will be replaced soon
710 */ 710 */
711struct GNUNET_ATS_ReservationContext * 711struct GNUNET_ATS_ReservationContext *
712GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph, 712GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph,
713 const struct GNUNET_PeerIdentity *peer, int32_t amount, 713 const struct GNUNET_PeerIdentity *peer,
714 GNUNET_ATS_ReservationCallback rcb, void *rcb_cls); 714 int32_t amount,
715 GNUNET_ATS_ReservationCallback rcb,
716 void *rcb_cls);
715 717
716 718
717/** 719/**
@@ -786,7 +788,8 @@ GNUNET_ATS_print_preference_type (uint32_t type);
786 */ 788 */
787void 789void
788GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, 790GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph,
789 const struct GNUNET_PeerIdentity *peer, ...); 791 const struct GNUNET_PeerIdentity *peer,
792 ...);
790 793
791 794
792/** 795/**
@@ -808,8 +811,9 @@ GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *p
808 */ 811 */
809void 812void
810GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph, 813GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph,
811 const struct GNUNET_PeerIdentity *peer, 814 const struct GNUNET_PeerIdentity *peer,
812 const struct GNUNET_TIME_Relative scope, ...); 815 const struct GNUNET_TIME_Relative scope,
816 ...);
813 817
814#endif 818#endif
815/* end of file gnunet-service-transport_ats.h */ 819/* end of file gnunet-service-transport_ats.h */