aboutsummaryrefslogtreecommitdiff
path: root/src/ats/gnunet-service-ats_addresses.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ats/gnunet-service-ats_addresses.c')
-rw-r--r--src/ats/gnunet-service-ats_addresses.c236
1 files changed, 100 insertions, 136 deletions
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c
index 99dc0e17a..22304aa6d 100644
--- a/src/ats/gnunet-service-ats_addresses.c
+++ b/src/ats/gnunet-service-ats_addresses.c
@@ -42,11 +42,11 @@ struct ATS_Address
42 42
43 uint32_t ats_count; 43 uint32_t ats_count;
44 44
45 const void * addr; 45 const void *addr;
46 46
47 char * plugin; 47 char *plugin;
48 48
49 struct GNUNET_ATS_Information * ats; 49 struct GNUNET_ATS_Information *ats;
50 50
51 struct GNUNET_TIME_Relative atsp_latency; 51 struct GNUNET_TIME_Relative atsp_latency;
52 52
@@ -74,7 +74,7 @@ struct ATS_Address
74}; 74};
75 75
76 76
77static struct GNUNET_CONTAINER_MultiHashMap * addresses; 77static struct GNUNET_CONTAINER_MultiHashMap *addresses;
78 78
79static unsigned long long total_quota_in; 79static unsigned long long total_quota_in;
80 80
@@ -92,10 +92,8 @@ static unsigned int active_addr_count;
92 * @param value the 'struct ATS_Address' 92 * @param value the 'struct ATS_Address'
93 * @return GNUNET_OK (continue to iterate) 93 * @return GNUNET_OK (continue to iterate)
94 */ 94 */
95static int 95static int
96update_bw_it (void *cls, 96update_bw_it (void *cls, const GNUNET_HashCode * key, void *value)
97 const GNUNET_HashCode * key,
98 void *value)
99{ 97{
100 struct ATS_Address *aa = value; 98 struct ATS_Address *aa = value;
101 99
@@ -104,24 +102,18 @@ update_bw_it (void *cls,
104 GNUNET_assert (active_addr_count > 0); 102 GNUNET_assert (active_addr_count > 0);
105 aa->assigned_bw_in.value__ = htonl (total_quota_in / active_addr_count); 103 aa->assigned_bw_in.value__ = htonl (total_quota_in / active_addr_count);
106 aa->assigned_bw_out.value__ = htonl (total_quota_out / active_addr_count); 104 aa->assigned_bw_out.value__ = htonl (total_quota_out / active_addr_count);
107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 105 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New bandwidth for peer %s is %u/%u\n",
108 "New bandwidth for peer %s is %u/%u\n", 106 GNUNET_i2s (&aa->peer), ntohl (aa->assigned_bw_in.value__),
109 GNUNET_i2s (&aa->peer), 107 ntohl (aa->assigned_bw_out.value__));
110 ntohl (aa->assigned_bw_in.value__), 108 GAS_scheduling_transmit_address_suggestion (&aa->peer, aa->plugin, aa->addr,
111 ntohl (aa->assigned_bw_out.value__)); 109 aa->addr_len, aa->session_id,
112 GAS_scheduling_transmit_address_suggestion (&aa->peer, 110 aa->ats, aa->ats_count,
113 aa->plugin, 111 aa->assigned_bw_out,
114 aa->addr, aa->addr_len, 112 aa->assigned_bw_in);
115 aa->session_id, 113 GAS_reservations_set_bandwidth (&aa->peer, aa->assigned_bw_in);
116 aa->ats, aa->ats_count, 114 GAS_performance_notify_clients (&aa->peer, aa->plugin, aa->addr, aa->addr_len,
117 aa->assigned_bw_out, aa->assigned_bw_in); 115 aa->ats, aa->ats_count, aa->assigned_bw_out,
118 GAS_reservations_set_bandwidth (&aa->peer, 116 aa->assigned_bw_in);
119 aa->assigned_bw_in);
120 GAS_performance_notify_clients (&aa->peer,
121 aa->plugin,
122 aa->addr, aa->addr_len,
123 aa->ats, aa->ats_count,
124 aa->assigned_bw_out, aa->assigned_bw_in);
125 return GNUNET_OK; 117 return GNUNET_OK;
126} 118}
127 119
@@ -134,18 +126,12 @@ static void
134recalculate_assigned_bw () 126recalculate_assigned_bw ()
135{ 127{
136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 128 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
137 "Recalculating bandwidth for all active connections\n"); 129 "Recalculating bandwidth for all active connections\n");
138 GNUNET_STATISTICS_update (GSA_stats, 130 GNUNET_STATISTICS_update (GSA_stats, "# bandwidth recalculations performed",
139 "# bandwidth recalculations performed", 131 1, GNUNET_NO);
140 1, 132 GNUNET_STATISTICS_set (GSA_stats, "# active addresses", active_addr_count,
141 GNUNET_NO); 133 GNUNET_NO);
142 GNUNET_STATISTICS_set (GSA_stats, 134 GNUNET_CONTAINER_multihashmap_iterate (addresses, &update_bw_it, NULL);
143 "# active addresses",
144 active_addr_count,
145 GNUNET_NO);
146 GNUNET_CONTAINER_multihashmap_iterate (addresses,
147 &update_bw_it,
148 NULL);
149} 135}
150 136
151 137
@@ -161,10 +147,10 @@ destroy_address (struct ATS_Address *addr)
161 int ret; 147 int ret;
162 148
163 ret = GNUNET_NO; 149 ret = GNUNET_NO;
164 GNUNET_assert (GNUNET_YES == 150 GNUNET_assert (GNUNET_YES ==
165 GNUNET_CONTAINER_multihashmap_remove(addresses, 151 GNUNET_CONTAINER_multihashmap_remove (addresses,
166 &addr->peer.hashPubKey, 152 &addr->peer.hashPubKey,
167 addr)); 153 addr));
168 if (GNUNET_YES == addr->active) 154 if (GNUNET_YES == addr->active)
169 { 155 {
170 active_addr_count--; 156 active_addr_count--;
@@ -180,24 +166,22 @@ destroy_address (struct ATS_Address *addr)
180 166
181struct CompareAddressContext 167struct CompareAddressContext
182{ 168{
183 const struct ATS_Address * search; 169 const struct ATS_Address *search;
184 struct ATS_Address * result; 170 struct ATS_Address *result;
185}; 171};
186 172
187 173
188static int 174static int
189compare_address_it (void *cls, 175compare_address_it (void *cls, const GNUNET_HashCode * key, void *value)
190 const GNUNET_HashCode * key,
191 void *value)
192{ 176{
193 struct CompareAddressContext * cac = cls; 177 struct CompareAddressContext *cac = cls;
194 struct ATS_Address * aa = value; 178 struct ATS_Address *aa = value;
195 179
196 if ( ( (aa->addr_len != cac->search->addr_len) || 180 if (((aa->addr_len != cac->search->addr_len) ||
197 (0 != strcmp(aa->plugin, cac->search->plugin)) || 181 (0 != strcmp (aa->plugin, cac->search->plugin)) ||
198 (0 != memcmp (aa->addr, cac->search->addr, aa->addr_len)) ) && 182 (0 != memcmp (aa->addr, cac->search->addr, aa->addr_len))) &&
199 ( (aa->session_id != cac->search->session_id) || 183 ((aa->session_id != cac->search->session_id) ||
200 (cac->search->session_id == 0) )) 184 (cac->search->session_id == 0)))
201 return GNUNET_YES; 185 return GNUNET_YES;
202 cac->result = aa; 186 cac->result = aa;
203 return GNUNET_NO; 187 return GNUNET_NO;
@@ -205,7 +189,7 @@ compare_address_it (void *cls,
205 189
206 190
207/** 191/**
208 * Find an existing equivalent address record. 192 * Find an existing equivalent address record.
209 * Compares by peer identity and network address OR by session ID 193 * Compares by peer identity and network address OR by session ID
210 * (one of the two must match). 194 * (one of the two must match).
211 * 195 *
@@ -215,34 +199,31 @@ compare_address_it (void *cls,
215 */ 199 */
216struct ATS_Address * 200struct ATS_Address *
217find_address (const struct GNUNET_PeerIdentity *peer, 201find_address (const struct GNUNET_PeerIdentity *peer,
218 const struct ATS_Address * addr) 202 const struct ATS_Address *addr)
219{ 203{
220 struct CompareAddressContext cac; 204 struct CompareAddressContext cac;
221 205
222 cac.result = NULL; 206 cac.result = NULL;
223 cac.search = addr; 207 cac.search = addr;
224 GNUNET_CONTAINER_multihashmap_get_multiple(addresses, 208 GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
225 &peer->hashPubKey, 209 compare_address_it, &cac);
226 compare_address_it,
227 &cac);
228 return cac.result; 210 return cac.result;
229} 211}
230 212
231 213
232void 214void
233GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, 215GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
234 const char *plugin_name, 216 const char *plugin_name, const void *plugin_addr,
235 const void *plugin_addr, size_t plugin_addr_len, 217 size_t plugin_addr_len, uint32_t session_id,
236 uint32_t session_id, 218 const struct GNUNET_ATS_Information *atsi,
237 const struct GNUNET_ATS_Information *atsi, 219 uint32_t atsi_count)
238 uint32_t atsi_count)
239{ 220{
240 struct ATS_Address * aa; 221 struct ATS_Address *aa;
241 struct ATS_Address * old; 222 struct ATS_Address *old;
242 uint32_t i; 223 uint32_t i;
243 224
244 aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len); 225 aa = GNUNET_malloc (sizeof (struct ATS_Address) + plugin_addr_len);
245 aa->ats = GNUNET_malloc(atsi_count * sizeof (struct GNUNET_ATS_Information)); 226 aa->ats = GNUNET_malloc (atsi_count * sizeof (struct GNUNET_ATS_Information));
246 aa->peer = *peer; 227 aa->peer = *peer;
247 aa->addr_len = plugin_addr_len; 228 aa->addr_len = plugin_addr_len;
248 aa->ats_count = atsi_count; 229 aa->ats_count = atsi_count;
@@ -256,19 +237,17 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
256 { 237 {
257 GNUNET_assert (GNUNET_OK == 238 GNUNET_assert (GNUNET_OK ==
258 GNUNET_CONTAINER_multihashmap_put (addresses, 239 GNUNET_CONTAINER_multihashmap_put (addresses,
259 &peer->hashPubKey, 240 &peer->hashPubKey, aa,
260 aa, 241 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
261 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 242 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %X\n",
262 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 243 GNUNET_i2s (peer), aa);
263 "Added new address for peer `%s' %X\n",
264 GNUNET_i2s (peer), aa);
265 old = aa; 244 old = aa;
266 } 245 }
267 else 246 else
268 { 247 {
269 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 248 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
270 "Updated existing address for peer `%s' %X \n", 249 "Updated existing address for peer `%s' %X \n",
271 GNUNET_i2s (peer), old); 250 GNUNET_i2s (peer), old);
272 GNUNET_free_non_null (old->ats); 251 GNUNET_free_non_null (old->ats);
273 old->session_id = session_id; 252 old->session_id = session_id;
274 old->ats = NULL; 253 old->ats = NULL;
@@ -278,7 +257,7 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
278 GNUNET_free (aa->plugin); 257 GNUNET_free (aa->plugin);
279 GNUNET_free (aa); 258 GNUNET_free (aa);
280 } 259 }
281 for (i=0;i<atsi_count;i++) 260 for (i = 0; i < atsi_count; i++)
282 switch (ntohl (atsi[i].type)) 261 switch (ntohl (atsi[i].type))
283 { 262 {
284 case GNUNET_ATS_UTILIZATION_UP: 263 case GNUNET_ATS_UTILIZATION_UP:
@@ -304,8 +283,7 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
304 break; 283 break;
305 default: 284 default:
306 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 285 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
307 "Received unsupported ATS type %u\n", 286 "Received unsupported ATS type %u\n", ntohl (atsi[i].type));
308 ntohl (atsi[i].type));
309 GNUNET_break (0); 287 GNUNET_break (0);
310 break; 288 break;
311 } 289 }
@@ -314,9 +292,8 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
314 292
315void 293void
316GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, 294GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
317 const char *plugin_name, 295 const char *plugin_name, const void *plugin_addr,
318 const void *plugin_addr, size_t plugin_addr_len, 296 size_t plugin_addr_len, uint32_t session_id)
319 uint32_t session_id)
320{ 297{
321 struct ATS_Address aa; 298 struct ATS_Address aa;
322 struct ATS_Address *res; 299 struct ATS_Address *res;
@@ -324,20 +301,18 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
324 aa.peer = *peer; 301 aa.peer = *peer;
325 aa.addr_len = plugin_addr_len; 302 aa.addr_len = plugin_addr_len;
326 aa.addr = plugin_addr; 303 aa.addr = plugin_addr;
327 aa.plugin = (char*) plugin_name; 304 aa.plugin = (char *) plugin_name;
328 aa.session_id = session_id; 305 aa.session_id = session_id;
329 res = find_address (peer, &aa); 306 res = find_address (peer, &aa);
330 if (res == NULL) 307 if (res == NULL)
331 { 308 {
332 /* we don't even know this one, can this happen? */ 309 /* we don't even know this one, can this happen? */
333 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 310 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
334 "Asked to delete unknown address for peer `%s'\n", 311 "Asked to delete unknown address for peer `%s'\n",
335 GNUNET_i2s (peer)); 312 GNUNET_i2s (peer));
336 return; 313 return;
337 } 314 }
338 if ( (aa.session_id == session_id) && 315 if ((aa.session_id == session_id) && (session_id != 0) && (res->addr_len > 0))
339 (session_id != 0) &&
340 (res->addr_len > 0) )
341 { 316 {
342 /* just session died */ 317 /* just session died */
343 res->session_id = 0; 318 res->session_id = 0;
@@ -350,10 +325,9 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
350 return; 325 return;
351 } 326 }
352 /* destroy address entirely (either was only session or was 327 /* destroy address entirely (either was only session or was
353 not even with a session) */ 328 * not even with a session) */
354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 329 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deleting address for peer `%s': `%s'\n",
355 "Deleting address for peer `%s': `%s'\n", 330 GNUNET_i2s (peer), plugin_name);
356 GNUNET_i2s (peer), plugin_name);
357 if (GNUNET_YES == destroy_address (res)) 331 if (GNUNET_YES == destroy_address (res))
358 recalculate_assigned_bw (); 332 recalculate_assigned_bw ();
359} 333}
@@ -362,29 +336,27 @@ GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer,
362/** 336/**
363 * Find a "good" address to use for a peer. If we already have an existing 337 * Find a "good" address to use for a peer. If we already have an existing
364 * address, we stick to it. Otherwise, we pick by lowest distance and then 338 * address, we stick to it. Otherwise, we pick by lowest distance and then
365 * by lowest latency. 339 * by lowest latency.
366 * 340 *
367 * @param cls the 'struct ATS_Address**' where we store the result 341 * @param cls the 'struct ATS_Address**' where we store the result
368 * @param key unused 342 * @param key unused
369 * @param value another 'struct ATS_Address*' to consider using 343 * @param value another 'struct ATS_Address*' to consider using
370 * @return GNUNET_OK (continue to iterate) 344 * @return GNUNET_OK (continue to iterate)
371 */ 345 */
372static int 346static int
373find_address_it (void *cls, 347find_address_it (void *cls, const GNUNET_HashCode * key, void *value)
374 const GNUNET_HashCode * key,
375 void *value)
376{ 348{
377 struct ATS_Address **ap = cls; 349 struct ATS_Address **ap = cls;
378 struct ATS_Address * aa = (struct ATS_Address *) value; 350 struct ATS_Address *aa = (struct ATS_Address *) value;
379 struct ATS_Address * ab = *ap; 351 struct ATS_Address *ab = *ap;
380 352
381 if (NULL == ab) 353 if (NULL == ab)
382 { 354 {
383 *ap = aa; 355 *ap = aa;
384 return GNUNET_OK; 356 return GNUNET_OK;
385 } 357 }
386 if ( (ntohl (ab->assigned_bw_in.value__) == 0) && 358 if ((ntohl (ab->assigned_bw_in.value__) == 0) &&
387 (ntohl (aa->assigned_bw_in.value__) > 0) ) 359 (ntohl (aa->assigned_bw_in.value__) > 0))
388 { 360 {
389 /* stick to existing connection */ 361 /* stick to existing connection */
390 *ap = aa; 362 *ap = aa;
@@ -410,19 +382,16 @@ find_address_it (void *cls,
410void 382void
411GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) 383GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer)
412{ 384{
413 struct ATS_Address * aa; 385 struct ATS_Address *aa;
414 386
415 aa = NULL; 387 aa = NULL;
416 GNUNET_CONTAINER_multihashmap_get_multiple (addresses, 388 GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey,
417 &peer->hashPubKey, 389 &find_address_it, &aa);
418 &find_address_it,
419 &aa);
420 if (aa == NULL) 390 if (aa == NULL)
421 { 391 {
422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
423 "Cannot suggest address for peer `%s'\n", 393 "Cannot suggest address for peer `%s'\n", GNUNET_i2s (peer));
424 GNUNET_i2s (peer)); 394 return;
425 return;
426 } 395 }
427 if (aa->active == GNUNET_NO) 396 if (aa->active == GNUNET_NO)
428 { 397 {
@@ -433,11 +402,11 @@ GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer)
433 else 402 else
434 { 403 {
435 /* just to be sure... */ 404 /* just to be sure... */
436 GAS_scheduling_transmit_address_suggestion (peer, aa->plugin, 405 GAS_scheduling_transmit_address_suggestion (peer, aa->plugin, aa->addr,
437 aa->addr, aa->addr_len, 406 aa->addr_len, aa->session_id,
438 aa->session_id, 407 aa->ats, aa->ats_count,
439 aa->ats, aa->ats_count, 408 aa->assigned_bw_out,
440 aa->assigned_bw_out, aa->assigned_bw_in); 409 aa->assigned_bw_in);
441 } 410 }
442} 411}
443 412
@@ -446,8 +415,8 @@ GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer)
446// not with 'addresses' in the future... 415// not with 'addresses' in the future...
447void 416void
448GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer, 417GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer,
449 enum GNUNET_ATS_PreferenceKind kind, 418 enum GNUNET_ATS_PreferenceKind kind,
450 float score) 419 float score)
451{ 420{
452 // do nothing for now... 421 // do nothing for now...
453} 422}
@@ -462,16 +431,14 @@ void
462GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg) 431GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
463{ 432{
464 GNUNET_assert (GNUNET_OK == 433 GNUNET_assert (GNUNET_OK ==
465 GNUNET_CONFIGURATION_get_value_number (cfg, 434 GNUNET_CONFIGURATION_get_value_number (cfg, "core",
466 "core", 435 "TOTAL_QUOTA_IN",
467 "TOTAL_QUOTA_IN", 436 &total_quota_in));
468 &total_quota_in));
469 GNUNET_assert (GNUNET_OK == 437 GNUNET_assert (GNUNET_OK ==
470 GNUNET_CONFIGURATION_get_value_number (cfg, 438 GNUNET_CONFIGURATION_get_value_number (cfg, "core",
471 "core", 439 "TOTAL_QUOTA_OUT",
472 "TOTAL_QUOTA_OUT", 440 &total_quota_out));
473 &total_quota_out)); 441 addresses = GNUNET_CONTAINER_multihashmap_create (128);
474 addresses = GNUNET_CONTAINER_multihashmap_create(128);
475} 442}
476 443
477 444
@@ -483,12 +450,10 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
483 * @param value the 'struct ATS_Address' to free 450 * @param value the 'struct ATS_Address' to free
484 * @return GNUNET_OK (continue to iterate) 451 * @return GNUNET_OK (continue to iterate)
485 */ 452 */
486static int 453static int
487free_address_it (void *cls, 454free_address_it (void *cls, const GNUNET_HashCode * key, void *value)
488 const GNUNET_HashCode * key,
489 void *value)
490{ 455{
491 struct ATS_Address * aa = value; 456 struct ATS_Address *aa = value;
492 457
493 destroy_address (aa); 458 destroy_address (aa);
494 return GNUNET_OK; 459 return GNUNET_OK;
@@ -499,8 +464,7 @@ void
499GAS_addresses_destroy_all () 464GAS_addresses_destroy_all ()
500{ 465{
501 if (addresses != NULL) 466 if (addresses != NULL)
502 GNUNET_CONTAINER_multihashmap_iterate(addresses, 467 GNUNET_CONTAINER_multihashmap_iterate (addresses, &free_address_it, NULL);
503 &free_address_it, NULL);
504 GNUNET_assert (active_addr_count == 0); 468 GNUNET_assert (active_addr_count == 0);
505} 469}
506 470