diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-12-05 14:06:58 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-12-05 14:06:58 +0000 |
commit | c5c7f5a17498e46fd185261bca847aad844c7cd4 (patch) | |
tree | a65ae02cddcadde6151d283428db9c26ff262f58 /src/ats/gnunet-service-ats_addresses_simplistic.c | |
parent | 6aa0b9eb1b7bed77d8c4a7727a7f66c52439167f (diff) | |
download | gnunet-c5c7f5a17498e46fd185261bca847aad844c7cd4.tar.gz gnunet-c5c7f5a17498e46fd185261bca847aad844c7cd4.zip |
commit required ... things can be broken
Diffstat (limited to 'src/ats/gnunet-service-ats_addresses_simplistic.c')
-rw-r--r-- | src/ats/gnunet-service-ats_addresses_simplistic.c | 176 |
1 files changed, 170 insertions, 6 deletions
diff --git a/src/ats/gnunet-service-ats_addresses_simplistic.c b/src/ats/gnunet-service-ats_addresses_simplistic.c index 62d996117..ff2933a59 100644 --- a/src/ats/gnunet-service-ats_addresses_simplistic.c +++ b/src/ats/gnunet-service-ats_addresses_simplistic.c | |||
@@ -29,13 +29,17 @@ | |||
29 | #include "gnunet-service-ats_addresses.h" | 29 | #include "gnunet-service-ats_addresses.h" |
30 | #include "gnunet_statistics_service.h" | 30 | #include "gnunet_statistics_service.h" |
31 | 31 | ||
32 | #define LOG(kind,...) GNUNET_log_from (kind, "ats-simplistic",__VA_ARGS__) | ||
32 | 33 | ||
33 | /** | 34 | /** |
34 | * A handle for the simplistic solver | 35 | * A handle for the simplistic solver |
35 | */ | 36 | */ |
36 | struct GAS_SIMPLISTIC_Handle | 37 | struct GAS_SIMPLISTIC_Handle |
37 | { | 38 | { |
38 | 39 | unsigned int active_addresses; | |
40 | int *quota_net; | ||
41 | unsigned long long *quota_in; | ||
42 | unsigned long long *quota_out; | ||
39 | }; | 43 | }; |
40 | 44 | ||
41 | 45 | ||
@@ -48,9 +52,23 @@ struct GAS_SIMPLISTIC_Handle | |||
48 | */ | 52 | */ |
49 | void * | 53 | void * |
50 | GAS_simplistic_init (const struct GNUNET_CONFIGURATION_Handle *cfg, | 54 | GAS_simplistic_init (const struct GNUNET_CONFIGURATION_Handle *cfg, |
51 | const struct GNUNET_STATISTICS_Handle *stats) | 55 | const struct GNUNET_STATISTICS_Handle *stats, |
56 | int *network, | ||
57 | unsigned long long *out_dest, | ||
58 | unsigned long long *in_dest, | ||
59 | int dest_length) | ||
52 | { | 60 | { |
53 | struct GAS_SIMPLISTIC_Handle *solver = GNUNET_malloc (sizeof (struct GAS_SIMPLISTIC_Handle)); | 61 | struct GAS_SIMPLISTIC_Handle *solver = GNUNET_malloc (sizeof (struct GAS_SIMPLISTIC_Handle)); |
62 | |||
63 | solver->quota_net = GNUNET_malloc (dest_length * sizeof (int)); | ||
64 | memcpy (solver->quota_net, network, dest_length * sizeof (int)); | ||
65 | |||
66 | solver->quota_in = GNUNET_malloc (dest_length * sizeof (unsigned long long)); | ||
67 | memcpy (solver->quota_in, out_dest, dest_length * sizeof (int)); | ||
68 | |||
69 | solver->quota_out = GNUNET_malloc (dest_length * sizeof (unsigned long long)); | ||
70 | memcpy (solver->quota_out, out_dest, dest_length * sizeof (unsigned long long)); | ||
71 | |||
54 | return solver; | 72 | return solver; |
55 | } | 73 | } |
56 | 74 | ||
@@ -63,8 +81,12 @@ GAS_simplistic_init (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
63 | void | 81 | void |
64 | GAS_simplistic_done (void *solver) | 82 | GAS_simplistic_done (void *solver) |
65 | { | 83 | { |
66 | GNUNET_assert (solver != NULL); | 84 | struct GAS_SIMPLISTIC_Handle *s = solver; |
67 | GNUNET_free (solver); | 85 | GNUNET_assert (s != NULL); |
86 | GNUNET_free (s->quota_net); | ||
87 | GNUNET_free (s->quota_in); | ||
88 | GNUNET_free (s->quota_out); | ||
89 | GNUNET_free (s); | ||
68 | } | 90 | } |
69 | 91 | ||
70 | /** | 92 | /** |
@@ -95,6 +117,128 @@ GAS_simplistic_address_delete (void *solver, struct GNUNET_CONTAINER_MultiHashMa | |||
95 | } | 117 | } |
96 | 118 | ||
97 | 119 | ||
120 | |||
121 | /** | ||
122 | * Find a "good" address to use for a peer. If we already have an existing | ||
123 | * address, we stick to it. Otherwise, we pick by lowest distance and then | ||
124 | * by lowest latency. | ||
125 | * | ||
126 | * @param cls the 'struct ATS_Address**' where we store the result | ||
127 | * @param key unused | ||
128 | * @param value another 'struct ATS_Address*' to consider using | ||
129 | * @return GNUNET_OK (continue to iterate) | ||
130 | */ | ||
131 | static int | ||
132 | find_address_it (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
133 | { | ||
134 | struct ATS_Address **previous_p = cls; | ||
135 | struct ATS_Address *current = (struct ATS_Address *) value; | ||
136 | struct ATS_Address *previous = *previous_p; | ||
137 | struct GNUNET_TIME_Absolute now; | ||
138 | |||
139 | now = GNUNET_TIME_absolute_get(); | ||
140 | |||
141 | if (current->blocked_until.abs_value == GNUNET_TIME_absolute_max (now, current->blocked_until).abs_value) | ||
142 | { | ||
143 | /* This address is blocked for suggestion */ | ||
144 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
145 | "Address %p blocked for suggestion for %llu ms \n", | ||
146 | current, | ||
147 | GNUNET_TIME_absolute_get_difference(now, current->blocked_until).rel_value); | ||
148 | return GNUNET_OK; | ||
149 | } | ||
150 | |||
151 | current->block_interval = GNUNET_TIME_relative_add (current->block_interval, ATS_BLOCKING_DELTA); | ||
152 | current->blocked_until = GNUNET_TIME_absolute_add (now, current->block_interval); | ||
153 | |||
154 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
155 | "Address %p ready for suggestion, block interval now %llu \n", | ||
156 | current, current->block_interval); | ||
157 | |||
158 | if (NULL != previous) | ||
159 | { | ||
160 | if ((0 == strcmp (previous->plugin, "tcp")) && | ||
161 | (0 == strcmp (current->plugin, "tcp"))) | ||
162 | { | ||
163 | if ((0 != previous->addr_len) && | ||
164 | (0 == current->addr_len)) | ||
165 | { | ||
166 | /* saved address was an outbound address, but we have an inbound address */ | ||
167 | *previous_p = current; | ||
168 | return GNUNET_OK; | ||
169 | } | ||
170 | if (0 == previous->addr_len) | ||
171 | { | ||
172 | /* saved address was an inbound address, so do not overwrite */ | ||
173 | return GNUNET_OK; | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | |||
178 | if (NULL == previous) | ||
179 | { | ||
180 | *previous_p = current; | ||
181 | return GNUNET_OK; | ||
182 | } | ||
183 | if ((ntohl (previous->assigned_bw_in.value__) == 0) && | ||
184 | (ntohl (current->assigned_bw_in.value__) > 0)) | ||
185 | { | ||
186 | /* stick to existing connection */ | ||
187 | *previous_p = current; | ||
188 | return GNUNET_OK; | ||
189 | } | ||
190 | if (previous->atsp_distance > current->atsp_distance) | ||
191 | { | ||
192 | /* user shorter distance */ | ||
193 | *previous_p = current; | ||
194 | return GNUNET_OK; | ||
195 | } | ||
196 | if (previous->atsp_latency.rel_value > current->atsp_latency.rel_value) | ||
197 | { | ||
198 | /* user lower latency */ | ||
199 | *previous_p = current; | ||
200 | return GNUNET_OK; | ||
201 | } | ||
202 | /* don't care */ | ||
203 | return GNUNET_OK; | ||
204 | } | ||
205 | |||
206 | static int | ||
207 | update_bw_simple_it (void *cls, const struct GNUNET_HashCode * key, void *value) | ||
208 | { | ||
209 | struct GAS_SIMPLISTIC_Handle *s = cls; | ||
210 | struct ATS_Address *aa = value; | ||
211 | |||
212 | if (GNUNET_YES != aa->active) | ||
213 | return GNUNET_OK; | ||
214 | GNUNET_assert (s->active_addresses > 0); | ||
215 | |||
216 | |||
217 | /* Simple method */ | ||
218 | |||
219 | aa->assigned_bw_in.value__ = htonl (UINT32_MAX / s->active_addresses); | ||
220 | aa->assigned_bw_out.value__ = htonl (UINT32_MAX / s->active_addresses); | ||
221 | |||
222 | //send_bw_notification (aa); | ||
223 | |||
224 | return GNUNET_OK; | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * Some (significant) input changed, recalculate bandwidth assignment | ||
229 | * for all peers. | ||
230 | */ | ||
231 | static void | ||
232 | recalculate_assigned_bw (void *solver, | ||
233 | struct GNUNET_CONTAINER_MultiHashMap * addresses) | ||
234 | { | ||
235 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
236 | "Recalculating bandwidth for all active connections\n"); | ||
237 | GNUNET_CONTAINER_multihashmap_iterate (addresses, &update_bw_simple_it, solver); | ||
238 | } | ||
239 | |||
240 | |||
241 | |||
98 | /** | 242 | /** |
99 | * Get the prefered address for a specific peer | 243 | * Get the prefered address for a specific peer |
100 | * | 244 | * |
@@ -102,12 +246,32 @@ GAS_simplistic_address_delete (void *solver, struct GNUNET_CONTAINER_MultiHashMa | |||
102 | * @param addresses the address hashmap containing all addresses | 246 | * @param addresses the address hashmap containing all addresses |
103 | * @param peer the identity of the peer | 247 | * @param peer the identity of the peer |
104 | */ | 248 | */ |
105 | struct ATS_PreferedAddress * | 249 | struct ATS_Address * |
106 | GAS_simplistic_get_preferred_address (void *solver, | 250 | GAS_simplistic_get_preferred_address (void *solver, |
107 | struct GNUNET_CONTAINER_MultiHashMap * addresses, | 251 | struct GNUNET_CONTAINER_MultiHashMap * addresses, |
108 | const struct GNUNET_PeerIdentity *peer) | 252 | const struct GNUNET_PeerIdentity *peer) |
109 | { | 253 | { |
110 | return NULL; | 254 | struct GAS_SIMPLISTIC_Handle *s = solver; |
255 | struct ATS_Address *aa; | ||
256 | |||
257 | GNUNET_assert (s != NULL); | ||
258 | aa = NULL; | ||
259 | /* Get address with: stick to current address, lower distance, lower latency */ | ||
260 | GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey, | ||
261 | &find_address_it, &aa); | ||
262 | if (NULL == aa) | ||
263 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Cannot suggest address for peer `%s'\n", GNUNET_i2s (peer)); | ||
264 | else | ||
265 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Suggesting address %p for peer `%s'\n", aa, GNUNET_i2s (peer)); | ||
266 | |||
267 | if (GNUNET_NO == aa->active) | ||
268 | { | ||
269 | aa->active = GNUNET_YES; | ||
270 | s->active_addresses++; | ||
271 | recalculate_assigned_bw (s, addresses); | ||
272 | } | ||
273 | |||
274 | return aa; | ||
111 | } | 275 | } |
112 | 276 | ||
113 | 277 | ||