diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-02-05 12:52:20 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-02-05 12:52:20 +0000 |
commit | c55971f17dc99f9833af48e078c8f681be771cb7 (patch) | |
tree | 544fd671b67903506419c98d463d086a696e25a1 | |
parent | 15dd8e6cc1199d611d804853e134882bf13b234a (diff) | |
download | gnunet-c55971f17dc99f9833af48e078c8f681be771cb7.tar.gz gnunet-c55971f17dc99f9833af48e078c8f681be771cb7.zip |
big ATS refactoring, no serious semantic changes should stem from this
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 | ||
44 | gnunet_ats_solver_eval_SOURCES = \ | 44 | gnunet_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 |
47 | gnunet_ats_solver_eval_LDADD = \ | 53 | gnunet_ats_solver_eval_LDADD = \ |
48 | $(top_builddir)/src/util/libgnunetutil.la \ | 54 | $(top_builddir)/src/util/libgnunetutil.la \ |
@@ -101,9 +107,11 @@ libexec_PROGRAMS = \ | |||
101 | gnunet_service_ats_SOURCES = \ | 107 | gnunet_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 |
109 | gnunet_service_ats_LDADD = \ | 117 | gnunet_service_ats_LDADD = \ |
@@ -516,7 +524,16 @@ test_ats_solver_alternative_after_delete_address_ril_LDADD = \ | |||
516 | # libgnunetats.la | 524 | # libgnunetats.la |
517 | 525 | ||
518 | perf_ats_solver_mlp_SOURCES = \ | 526 | perf_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 | |||
520 | perf_ats_solver_mlp_LDADD = \ | 537 | perf_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 | ||
526 | perf_ats_solver_proportional_SOURCES = \ | 543 | perf_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 | |||
528 | perf_ats_solver_proportional_LDADD = \ | 554 | perf_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 | ||
534 | perf_ats_solver_ril_SOURCES = \ | 560 | perf_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 | |||
536 | perf_ats_solver_ril_LDADD = \ | 571 | perf_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 | */ | ||
37 | struct GNUNET_STATISTICS_Handle *GSA_stats; | ||
38 | |||
39 | |||
32 | static struct Experiment *e; | 40 | static struct Experiment *e; |
33 | 41 | ||
34 | static struct LoggingHandle *l; | 42 | static struct LoggingHandle *l; |
@@ -36,6 +44,7 @@ static struct LoggingHandle *l; | |||
36 | static struct SolverHandle *sh; | 44 | static struct SolverHandle *sh; |
37 | 45 | ||
38 | static struct TestPeer *peer_head; | 46 | static struct TestPeer *peer_head; |
47 | |||
39 | static struct TestPeer *peer_tail; | 48 | static struct TestPeer *peer_tail; |
40 | 49 | ||
41 | static double default_properties[GNUNET_ATS_PropertyCount]; | 50 | static 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 | |||
3065 | static void | ||
3066 | set_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 | |||
3087 | static void | ||
3088 | normalized_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 | |||
3121 | static void | ||
3122 | set_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 | |||
3139 | static void | ||
3140 | normalized_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 | |||
121 | cleanup_task (void *cls, | 126 | cleanup_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 | */ | ||
222 | struct 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 | */ | ||
243 | struct 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 | */ | ||
265 | static struct GNUNET_STATISTICS_Handle *stats; | ||
266 | |||
267 | /** | ||
268 | * A multihashmap to store all addresses | 222 | * A multihashmap to store all addresses |
269 | */ | 223 | */ |
270 | static struct GNUNET_CONTAINER_MultiPeerMap *addresses; | 224 | struct GNUNET_CONTAINER_MultiPeerMap *GSA_addresses; |
271 | 225 | ||
272 | /** | ||
273 | * Is ATS addresses running | ||
274 | */ | ||
275 | static int running; | ||
276 | |||
277 | /** | ||
278 | * Preferences clients | ||
279 | */ | ||
280 | static int pref_clients; | ||
281 | |||
282 | /** | ||
283 | * Configured ATS solver | ||
284 | */ | ||
285 | static int ats_mode; | ||
286 | |||
287 | /** | ||
288 | * Solver handle | ||
289 | */ | ||
290 | static 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 | */ | ||
297 | static struct GAS_Addresses_Suggestion_Requests *pending_requests_head; | ||
298 | |||
299 | /** | ||
300 | * Address suggestion requests DLL tail | ||
301 | */ | ||
302 | static struct GAS_Addresses_Suggestion_Requests *pending_requests_tail; | ||
303 | |||
304 | /** | ||
305 | * Preference requests DLL head | ||
306 | */ | ||
307 | static struct GAS_Addresses_Preference_Clients *preference_clients_head; | ||
308 | |||
309 | /** | ||
310 | * Preference requests DLL head | ||
311 | */ | ||
312 | static struct GAS_Addresses_Preference_Clients *preference_clients_tail; | ||
313 | |||
314 | /** | ||
315 | * Solver functions | ||
316 | */ | ||
317 | static struct GNUNET_ATS_PluginEnvironment env; | ||
318 | |||
319 | /** | ||
320 | * Solver plugin name as string | ||
321 | */ | ||
322 | static 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 | */ | ||
699 | const double * | ||
700 | get_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 | */ | ||
715 | const double * | ||
716 | get_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 | */ | ||
1083 | void | ||
1084 | GAS_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 | */ | ||
1123 | void | ||
1124 | GAS_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 | */ | ||
1190 | static void | ||
1191 | solver_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 | */ | ||
1288 | static void | ||
1289 | normalized_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 | */ | ||
1307 | static void | ||
1308 | normalized_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 | |||
1326 | static struct GAS_Addresses_Preference_Clients * | ||
1327 | find_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 | */ | ||
1343 | void | ||
1344 | GAS_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 | */ | ||
1373 | void | ||
1374 | GAS_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 | */ | ||
1428 | void | ||
1429 | GAS_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 | */ | ||
1468 | static unsigned int | ||
1469 | load_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 | "a_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 | "a_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 | */ | ||
1604 | static void | ||
1605 | bandwidth_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 | */ |
1685 | int | 843 | void |
1686 | GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, | 844 | GAS_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, | |||
1861 | void | 894 | void |
1862 | GAS_addresses_destroy_all () | 895 | GAS_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 () | |||
1881 | void | 911 | void |
1882 | GAS_addresses_done () | 912 | GAS_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 | */ |
225 | enum 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 | */ | ||
365 | extern 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 | */ |
415 | int | 373 | void |
416 | GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, | 374 | GAS_addresses_init (void); |
417 | struct GNUNET_STATISTICS_Handle *stats); | ||
418 | 375 | ||
419 | 376 | ||
420 | /** | 377 | /** |
@@ -480,83 +437,6 @@ void | |||
480 | GAS_addresses_destroy_all (void); | 437 | GAS_addresses_destroy_all (void); |
481 | 438 | ||
482 | 439 | ||
483 | /** | ||
484 | * Request address suggestions for a peer | ||
485 | * | ||
486 | * @param peer the peer id | ||
487 | */ | ||
488 | void | ||
489 | GAS_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 | */ | ||
497 | void | ||
498 | GAS_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 | */ | ||
509 | void | ||
510 | GAS_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 | */ | ||
518 | void | ||
519 | GAS_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 | */ | ||
530 | void | ||
531 | GAS_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 | */ | ||
554 | void | ||
555 | GAS_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 | */ | ||
44 | struct 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 | */ | ||
68 | static struct GAS_Addresses_Suggestion_Requests *pending_requests_head; | ||
69 | |||
70 | /** | ||
71 | * Address suggestion requests DLL tail | ||
72 | */ | ||
73 | static 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 | */ | ||
83 | void | ||
84 | GAS_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 | */ | ||
123 | void | ||
124 | GAS_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 | */ | ||
209 | void | ||
210 | GAS_connectivity_remove_client (struct GNUNET_SERVER_Client *client) | ||
211 | { | ||
212 | // FIXME | ||
213 | } | ||
214 | |||
215 | |||
216 | /** | ||
217 | * Shutdown connectivity subsystem. | ||
218 | */ | ||
219 | void | ||
220 | GAS_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 | */ | ||
35 | void | ||
36 | GAS_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 | */ | ||
44 | void | ||
45 | GAS_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 | */ | ||
81 | void | ||
82 | GAS_connectivity_remove_client (struct GNUNET_SERVER_Client *client); | ||
83 | |||
84 | |||
85 | /** | ||
86 | * Shutdown connectivity subsystem. | ||
87 | */ | ||
88 | void | ||
89 | GAS_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 | */ | ||
37 | struct 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 | */ | ||
83 | struct 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 | */ | ||
124 | struct 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 | ||
148 | static struct Property properties[GNUNET_ATS_QualityPropertiesCount]; | 50 | static struct Property properties[GNUNET_ATS_QualityPropertiesCount]; |
149 | 51 | ||
150 | |||
151 | /** | ||
152 | * Callback to call on changing preference values | ||
153 | */ | ||
154 | static GAS_Normalization_preference_changed_cb pref_changed_cb; | ||
155 | |||
156 | /** | ||
157 | * Closure for callback to call on changing preference values | ||
158 | */ | ||
159 | static void *pref_changed_cb_cls; | ||
160 | |||
161 | /** | ||
162 | * Callback to call on changing property values | ||
163 | */ | ||
164 | static GAS_Normalization_property_changed_cb prop_ch_cb; | ||
165 | |||
166 | /** | ||
167 | * Closure for callback to call on changing property values | ||
168 | */ | ||
169 | static void *prop_ch_cb_cls; | ||
170 | |||
171 | /** | ||
172 | * Hashmap to store peer information for preference normalization | ||
173 | */ | ||
174 | static 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 | */ |
180 | static struct GNUNET_CONTAINER_MultiPeerMap *property_peers; | 56 | static struct GNUNET_CONTAINER_MultiPeerMap *property_peers; |
181 | 57 | ||
182 | /** | ||
183 | * Clients in DLL: head | ||
184 | */ | ||
185 | static struct PreferenceClient *pc_head; | ||
186 | |||
187 | /** | ||
188 | * Clients in DLL: tail | ||
189 | */ | ||
190 | static struct PreferenceClient *pc_tail; | ||
191 | |||
192 | /** | ||
193 | * Default values | ||
194 | */ | ||
195 | static struct PeerRelative defvalues; | ||
196 | |||
197 | static 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 | */ | ||
208 | static void | ||
209 | update_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 | */ | ||
273 | static void | ||
274 | recalculate_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 | */ | ||
324 | static void | ||
325 | update_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 | |||
350 | static int | ||
351 | update_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 | |||
365 | static void | ||
366 | run_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 | */ | ||
390 | static void | ||
391 | preference_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 | */ | ||
463 | void | ||
464 | GAS_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 | */ | ||
572 | const double * | ||
573 | GAS_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 | */ | ||
595 | double | ||
596 | GAS_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 | */ |
632 | const double * | 70 | const double * |
633 | GAS_normalization_get_properties (const struct ATS_Address *address) | 71 | GAS_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 | ||
744 | static int | 183 | static int |
745 | normalize_address (void *cls, const struct GNUNET_PeerIdentity *h, void *k) | 184 | normalize_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 | */ |
789 | static void | 229 | static void |
790 | property_normalize (struct GNUNET_CONTAINER_MultiPeerMap *addresses, | 230 | property_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 | */ |
857 | void | 300 | void |
858 | GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiPeerMap *addresses, | 301 | GAS_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 | ||
909 | static void | ||
910 | free_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 | */ | ||
930 | void | ||
931 | GAS_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 | */ |
957 | void | 352 | void |
958 | GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, | 353 | GAS_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 | */ | ||
999 | static int | ||
1000 | free_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) | |||
1015 | void | 373 | void |
1016 | GAS_normalization_stop () | 374 | GAS_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 | ||
39 | typedef 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 | |||
45 | typedef 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 | */ |
58 | const double * | 41 | const double * |
59 | GAS_normalization_get_preferences_by_peer (const struct GNUNET_PeerIdentity *id); | 42 | GAS_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 | */ |
70 | const double * | 55 | const double * |
71 | GAS_normalization_get_properties (const struct ATS_Address *address); | 56 | GAS_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 | */ |
109 | void | 94 | void |
110 | GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiPeerMap *addresses, | 95 | GAS_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 | */ |
133 | void | 112 | void |
134 | GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, | 113 | GAS_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 | */ |
143 | void | 119 | void |
144 | GAS_normalization_stop (); | 120 | GAS_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 | */ |
70 | static struct PerformanceClient *pc_tail; | 70 | static 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 | */ | ||
603 | void | ||
604 | GAS_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 | */ | ||
655 | void | ||
656 | GAS_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 | */ | ||
45 | static int ats_mode; | ||
46 | |||
47 | /** | ||
48 | * Solver handle. FIXME: TYPE!? | ||
49 | */ | ||
50 | static void *solver; | ||
51 | |||
52 | /** | ||
53 | * Solver functions. FIXME. | ||
54 | */ | ||
55 | static struct GNUNET_ATS_PluginEnvironment env; | ||
56 | |||
57 | /** | ||
58 | * Solver plugin name as string | ||
59 | */ | ||
60 | static 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 | */ | ||
70 | void | ||
71 | GAS_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 | */ | ||
87 | void | ||
88 | GAS_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 | */ | ||
113 | static void | ||
114 | solver_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 | */ | ||
209 | static void | ||
210 | bandwidth_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 | */ | ||
279 | static unsigned int | ||
280 | load_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 | "a_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 | "a_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 | */ | ||
416 | int | ||
417 | GAS_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 | */ | ||
536 | void | ||
537 | GAS_plugins_done () | ||
538 | { | ||
539 | GNUNET_PLUGIN_unload (plugin, | ||
540 | solver); | ||
541 | solver = NULL; | ||
542 | GNUNET_free (plugin); | ||
543 | plugin = NULL; | ||
544 | } | ||
545 | |||
546 | |||
547 | void | ||
548 | GAS_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 | |||
562 | void | ||
563 | GAS_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 | |||
575 | void | ||
576 | GAS_plugin_delete_address (struct ATS_Address *address) | ||
577 | { | ||
578 | env.sf.s_del (solver, address, GNUNET_NO); | ||
579 | } | ||
580 | |||
581 | |||
582 | void | ||
583 | GAS_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 | |||
595 | void | ||
596 | GAS_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 | |||
611 | void | ||
612 | GAS_plugin_solver_lock () | ||
613 | { | ||
614 | env.sf.s_bulk_start (solver); | ||
615 | } | ||
616 | |||
617 | |||
618 | void | ||
619 | GAS_plugin_solver_unlock () | ||
620 | { | ||
621 | env.sf.s_bulk_start (solver); | ||
622 | } | ||
623 | |||
624 | |||
625 | void | ||
626 | GAS_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 | |||
654 | void | ||
655 | GAS_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 | */ | ||
40 | enum 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 | */ | ||
78 | int | ||
79 | GAS_plugins_init (const struct GNUNET_CONFIGURATION_Handle *cfg); | ||
80 | |||
81 | |||
82 | /** | ||
83 | * Shutdown address subsystem. | ||
84 | */ | ||
85 | void | ||
86 | GAS_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 | */ | ||
96 | void | ||
97 | GAS_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 | */ | ||
109 | void | ||
110 | GAS_normalized_property_changed (struct ATS_Address *address, | ||
111 | uint32_t type, | ||
112 | double prop_rel); | ||
113 | |||
114 | |||
115 | void | ||
116 | GAS_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 | |||
122 | void | ||
123 | GAS_plugin_update_address (struct ATS_Address *address, | ||
124 | const struct GNUNET_ATS_Information *atsi, | ||
125 | uint32_t atsi_count); | ||
126 | |||
127 | |||
128 | void | ||
129 | GAS_plugin_update_preferences (void *client, | ||
130 | const struct GNUNET_PeerIdentity *peer, | ||
131 | enum GNUNET_ATS_PreferenceKind kind, | ||
132 | float score_abs); | ||
133 | |||
134 | |||
135 | void | ||
136 | GAS_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 | |||
143 | void | ||
144 | GAS_plugin_delete_address (struct ATS_Address *address); | ||
145 | |||
146 | |||
147 | void | ||
148 | GAS_plugin_request_connect_start (const struct GNUNET_PeerIdentity *pid); | ||
149 | |||
150 | |||
151 | void | ||
152 | GAS_plugin_request_connect_stop (const struct GNUNET_PeerIdentity *pid); | ||
153 | |||
154 | |||
155 | void | ||
156 | GAS_plugin_solver_lock (void); | ||
157 | |||
158 | |||
159 | void | ||
160 | GAS_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 | */ | ||
46 | struct 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 | */ | ||
63 | struct 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 | */ | ||
85 | static struct GAS_Addresses_Preference_Clients *preference_clients_head; | ||
86 | |||
87 | /** | ||
88 | * Preference requests DLL head | ||
89 | */ | ||
90 | static struct GAS_Addresses_Preference_Clients *preference_clients_tail; | ||
91 | |||
92 | /** | ||
93 | * Preferences clients | ||
94 | */ | ||
95 | static int pref_clients; | ||
96 | |||
97 | /** | ||
98 | * Default values | ||
99 | */ | ||
100 | static struct PeerRelative defvalues; | ||
101 | |||
102 | |||
103 | |||
104 | /** | ||
105 | * Preference client | ||
106 | */ | ||
107 | struct 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 | */ | ||
153 | struct 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 | */ | ||
195 | static struct GNUNET_CONTAINER_MultiPeerMap *preference_peers; | ||
196 | |||
197 | |||
198 | /** | ||
199 | * Clients in DLL: head | ||
200 | */ | ||
201 | static struct PreferenceClient *pc_head; | ||
202 | |||
203 | /** | ||
204 | * Clients in DLL: tail | ||
205 | */ | ||
206 | static struct PreferenceClient *pc_tail; | ||
207 | |||
208 | |||
209 | |||
210 | static struct GNUNET_SCHEDULER_Task * aging_task; | ||
211 | |||
212 | |||
213 | |||
214 | |||
215 | static struct GAS_Addresses_Preference_Clients * | ||
216 | find_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 | */ | ||
235 | static void | ||
236 | update_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 | |||
292 | static int | ||
293 | update_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 | */ | ||
315 | static void | ||
316 | recalculate_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 | |||
359 | static void | ||
360 | run_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 | */ | ||
388 | static void | ||
389 | preference_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 | */ | ||
461 | static void | ||
462 | update_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 | */ | ||
495 | void | ||
496 | GAS_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 | */ | ||
525 | void | ||
526 | GAS_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 | */ | ||
571 | void | ||
572 | GAS_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 | */ | ||
627 | void | ||
628 | GAS_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 | */ | ||
667 | void | ||
668 | GAS_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 | */ | ||
716 | void | ||
717 | GAS_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 | */ | ||
736 | static int | ||
737 | free_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 | |||
749 | static void | ||
750 | free_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 | */ | ||
771 | void | ||
772 | GAS_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 | */ | ||
822 | void | ||
823 | GAS_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 | */ | ||
928 | const double * | ||
929 | GAS_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 | */ | ||
952 | double | ||
953 | GAS_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 | */ | ||
987 | void | ||
988 | GAS_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 | */ | ||
49 | void | ||
50 | GAS_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 | */ | ||
63 | void | ||
64 | GAS_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 | */ | ||
87 | void | ||
88 | GAS_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 | */ | ||
97 | void | ||
98 | GAS_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 | */ | ||
60 | void | ||
61 | GAS_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 | */ | ||
115 | void | ||
116 | GAS_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 | */ | ||
46 | struct GNUNET_STATISTICS_Handle *GSA_stats; | ||
47 | |||
48 | /** | ||
43 | * Handle for ATS address component | 49 | * Handle for ATS address component |
44 | */ | 50 | */ |
45 | struct PerfHandle | 51 | struct 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, | |||
411 | const double * | 416 | const double * |
412 | get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id) | 417 | get_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 | ||
418 | const double * | 423 | const double * |
419 | get_property_cb (void *cls, const struct ATS_Address *address) | 424 | get_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 | ||
424 | static void | ||
425 | normalized_property_changed_cb (void *cls, struct ATS_Address *peer, | ||
426 | uint32_t type, double prop_rel) | ||
427 | { | ||
428 | /* TODO */ | ||
429 | } | ||
430 | 430 | ||
431 | static void | 431 | static void |
432 | perf_address_initial_update (void *solver, | 432 | perf_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 | */ | ||
2055 | static void | ||
2056 | GAS_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 | */ | ||
2076 | static void | ||
2077 | GAS_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 | */ | ||
1708 | static void | ||
1709 | GAS_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 | */ | ||
1763 | static void | ||
1764 | GAS_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 | */ | ||
2398 | static void | ||
2399 | GAS_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 | */ | ||
2419 | static void | ||
2420 | GAS_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 | */ | ||
141 | typedef 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 | */ | ||
156 | typedef 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 | */ |
711 | struct GNUNET_ATS_ReservationContext * | 711 | struct GNUNET_ATS_ReservationContext * |
712 | GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph, | 712 | GNUNET_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 | */ |
787 | void | 789 | void |
788 | GNUNET_ATS_performance_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, | 790 | GNUNET_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 | */ |
809 | void | 812 | void |
810 | GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph, | 813 | GNUNET_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 */ |