aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_ats.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-transport_ats.c')
-rw-r--r--src/transport/gnunet-service-transport_ats.c248
1 files changed, 135 insertions, 113 deletions
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c
index 613f35ec2..3976ae3d9 100644
--- a/src/transport/gnunet-service-transport_ats.c
+++ b/src/transport/gnunet-service-transport_ats.c
@@ -29,6 +29,8 @@
29#include "gnunet-service-transport_plugins.h" 29#include "gnunet-service-transport_plugins.h"
30#include "gnunet_ats_service.h" 30#include "gnunet_ats_service.h"
31 31
32#define LOG(kind,...) GNUNET_log_from(kind, "transport-ats", __VA_ARGS__)
33
32 34
33/** 35/**
34 * Information we track for each address known to ATS. 36 * Information we track for each address known to ATS.
@@ -52,6 +54,11 @@ struct AddressInfo
52 struct GNUNET_ATS_AddressRecord *ar; 54 struct GNUNET_ATS_AddressRecord *ar;
53 55
54 /** 56 /**
57 * Performance properties of this address.
58 */
59 struct GNUNET_ATS_Properties properties;
60
61 /**
55 * Time until when this address is blocked and should thus not be 62 * Time until when this address is blocked and should thus not be
56 * made available to ATS (@e ar should be NULL until this time). 63 * made available to ATS (@e ar should be NULL until this time).
57 * Used when transport determines that for some reason it 64 * Used when transport determines that for some reason it
@@ -256,16 +263,15 @@ unblock_address (void *cls,
256 struct AddressInfo *ai = cls; 263 struct AddressInfo *ai = cls;
257 264
258 ai->unblock_task = NULL; 265 ai->unblock_task = NULL;
259 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 266 LOG (GNUNET_ERROR_TYPE_DEBUG,
260 "Unblocking address %s of peer %s\n", 267 "Unblocking address %s of peer %s\n",
261 GST_plugins_a2s (ai->address), 268 GST_plugins_a2s (ai->address),
262 GNUNET_i2s (&ai->address->peer)); 269 GNUNET_i2s (&ai->address->peer));
263 ai->ar = GNUNET_ATS_address_add (GST_ats, 270 ai->ar = GNUNET_ATS_address_add (GST_ats,
264 ai->address, 271 ai->address,
265 ai->session, 272 ai->session,
266 NULL, 0); 273 &ai->properties);
267 GNUNET_break (NULL != ai->ar); 274 GNUNET_break (NULL != ai->ar);
268 /* FIXME: should pass ATS information here! */
269} 275}
270 276
271 277
@@ -299,15 +305,15 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
299 if (GNUNET_YES == 305 if (GNUNET_YES ==
300 GNUNET_HELLO_address_check_option (address, 306 GNUNET_HELLO_address_check_option (address,
301 GNUNET_HELLO_ADDRESS_INFO_INBOUND)) 307 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 308 LOG (GNUNET_ERROR_TYPE_DEBUG,
303 "Removing address %s of peer %s from use (inbound died)\n", 309 "Removing address %s of peer %s from use (inbound died)\n",
304 GST_plugins_a2s (address), 310 GST_plugins_a2s (address),
305 GNUNET_i2s (&address->peer)); 311 GNUNET_i2s (&address->peer));
306 else 312 else
307 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 313 LOG (GNUNET_ERROR_TYPE_DEBUG,
308 "Blocking address %s of peer %s from use for a while\n", 314 "Blocking address %s of peer %s from use for a while\n",
309 GST_plugins_a2s (address), 315 GST_plugins_a2s (address),
310 GNUNET_i2s (&address->peer)); 316 GNUNET_i2s (&address->peer));
311 /* destroy session and address */ 317 /* destroy session and address */
312 if ( (NULL == session) || 318 if ( (NULL == session) ||
313 (GNUNET_NO == 319 (GNUNET_NO ==
@@ -332,20 +338,15 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
332 * 338 *
333 * @param address the address 339 * @param address the address
334 * @param session the session 340 * @param session the session
335 * @param ats ats information 341 * @param prop performance information
336 * @param ats_count number of @a ats information
337 */ 342 */
338void 343void
339GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address, 344GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
340 struct Session *session, 345 struct Session *session,
341 const struct GNUNET_ATS_Information *ats, 346 const struct GNUNET_ATS_Properties *prop)
342 uint32_t ats_count)
343{ 347{
344 struct GNUNET_TRANSPORT_PluginFunctions *papi;
345 struct GNUNET_ATS_Information ats2[ats_count + 1];
346 struct GNUNET_ATS_AddressRecord *ar; 348 struct GNUNET_ATS_AddressRecord *ar;
347 struct AddressInfo *ai; 349 struct AddressInfo *ai;
348 uint32_t net;
349 350
350 /* valid new address, let ATS know! */ 351 /* valid new address, let ATS know! */
351 if (NULL == address->transport_name) 352 if (NULL == address->transport_name)
@@ -365,40 +366,24 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
365 GNUNET_break (0); 366 GNUNET_break (0);
366 return; 367 return;
367 } 368 }
368 papi = GST_plugins_find (address->transport_name); 369 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope);
369 GNUNET_assert (NULL != papi); 370 LOG (GNUNET_ERROR_TYPE_DEBUG,
370 net = papi->get_network (papi->cls, session); 371 "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n",
371 if (GNUNET_ATS_NET_UNSPECIFIED == net) 372 GNUNET_i2s (&address->peer),
372 { 373 (0 == address->address_length)
373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 374 ? "<inbound>"
374 _("Could not obtain a valid network for `%s' %s (%s)\n"), 375 : GST_plugins_a2s (address),
375 GNUNET_i2s (&address->peer), 376 session,
376 GST_plugins_a2s (address), 377 GNUNET_ATS_print_network_type (prop->scope));
377 address->transport_name);
378 return;
379 }
380 ats2[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
381 ats2[0].value = htonl (net);
382 memcpy (&ats2[1],
383 ats,
384 sizeof(struct GNUNET_ATS_Information) * ats_count);
385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
386 "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n",
387 GNUNET_i2s (&address->peer),
388 (0 == address->address_length)
389 ? "<inbound>"
390 : GST_plugins_a2s (address),
391 session,
392 GNUNET_ATS_print_network_type (net));
393 ar = GNUNET_ATS_address_add (GST_ats, 378 ar = GNUNET_ATS_address_add (GST_ats,
394 address, 379 address,
395 session, 380 session,
396 (NULL != session) ? ats2 : ats, 381 prop);
397 (NULL != session) ? ats_count + 1 : ats_count);
398 GNUNET_break (NULL != ar); 382 GNUNET_break (NULL != ar);
399 ai = GNUNET_new (struct AddressInfo); 383 ai = GNUNET_new (struct AddressInfo);
400 ai->address = GNUNET_HELLO_address_copy (address); 384 ai->address = GNUNET_HELLO_address_copy (address);
401 ai->session = session; 385 ai->session = session;
386 ai->properties = *prop;
402 ai->ar = ar; 387 ai->ar = ar;
403 (void) GNUNET_CONTAINER_multipeermap_put (p2a, 388 (void) GNUNET_CONTAINER_multipeermap_put (p2a,
404 &ai->address->peer, 389 &ai->address->peer,
@@ -413,13 +398,11 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
413 * located in. The address must NOT be inbound and must be new to ATS. 398 * located in. The address must NOT be inbound and must be new to ATS.
414 * 399 *
415 * @param address the address 400 * @param address the address
416 * @param ats ats information 401 * @param prop performance information
417 * @param ats_count number of @a ats information
418 */ 402 */
419void 403void
420GST_ats_add_address (const struct GNUNET_HELLO_Address *address, 404GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
421 const struct GNUNET_ATS_Information *ats, 405 const struct GNUNET_ATS_Properties *prop)
422 uint32_t ats_count)
423{ 406{
424 struct GNUNET_ATS_AddressRecord *ar; 407 struct GNUNET_ATS_AddressRecord *ar;
425 struct AddressInfo *ai; 408 struct AddressInfo *ai;
@@ -435,21 +418,21 @@ GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
435 GNUNET_HELLO_ADDRESS_INFO_INBOUND)); 418 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
436 ai = find_ai_no_session (address); 419 ai = find_ai_no_session (address);
437 GNUNET_assert (NULL == ai); 420 GNUNET_assert (NULL == ai);
438 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 421 LOG (GNUNET_ERROR_TYPE_INFO,
439 "Notifying ATS about peer `%s''s new address `%s'\n", 422 "Notifying ATS about peer `%s''s new address `%s'\n",
440 GNUNET_i2s (&address->peer), 423 GNUNET_i2s (&address->peer),
441 (0 == address->address_length) 424 (0 == address->address_length)
442 ? "<inbound>" 425 ? "<inbound>"
443 : GST_plugins_a2s (address)); 426 : GST_plugins_a2s (address));
444 ar = GNUNET_ATS_address_add (GST_ats, 427 ar = GNUNET_ATS_address_add (GST_ats,
445 address, 428 address,
446 NULL, 429 NULL,
447 ats, 430 prop);
448 ats_count);
449 GNUNET_break (NULL != ar); 431 GNUNET_break (NULL != ar);
450 ai = GNUNET_new (struct AddressInfo); 432 ai = GNUNET_new (struct AddressInfo);
451 ai->address = GNUNET_HELLO_address_copy (address); 433 ai->address = GNUNET_HELLO_address_copy (address);
452 ai->ar = ar; 434 ai->ar = ar;
435 ai->properties = *prop;
453 (void) GNUNET_CONTAINER_multipeermap_put (p2a, 436 (void) GNUNET_CONTAINER_multipeermap_put (p2a,
454 &ai->address->peer, 437 &ai->address->peer,
455 ai, 438 ai,
@@ -484,11 +467,9 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
484 } 467 }
485 GNUNET_break (NULL == ai->session); 468 GNUNET_break (NULL == ai->session);
486 ai->session = session; 469 ai->session = session;
487 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 470 LOG (GNUNET_ERROR_TYPE_DEBUG,
488 "transport-ats", 471 "Telling ATS about new session for peer %s\n",
489 "Telling ATS about new session %p for peer %s\n", 472 GNUNET_i2s (&address->peer));
490 session,
491 GNUNET_i2s (&address->peer));
492 if (NULL != ai->ar) 473 if (NULL != ai->ar)
493 GNUNET_ATS_address_add_session (ai->ar, 474 GNUNET_ATS_address_add_session (ai->ar,
494 session); 475 session);
@@ -528,11 +509,10 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
528 } 509 }
529 GNUNET_assert (session == ai->session); 510 GNUNET_assert (session == ai->session);
530 ai->session = NULL; 511 ai->session = NULL;
531 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 512 LOG (GNUNET_ERROR_TYPE_DEBUG,
532 "transport-ats", 513 "Telling ATS to destroy session %p from peer %s\n",
533 "Telling ATS to destroy session %p from peer %s\n", 514 session,
534 session, 515 GNUNET_i2s (&address->peer));
535 GNUNET_i2s (&address->peer));
536 if (NULL == ai->ar) 516 if (NULL == ai->ar)
537 { 517 {
538 /* If ATS doesn't know about the address/session, and this 518 /* If ATS doesn't know about the address/session, and this
@@ -555,52 +535,95 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
555 535
556 536
557/** 537/**
558 * Notify ATS about property changes to an address. 538 * Notify ATS about DV distance change to an address's.
559 * 539 *
560 * @param address our information about the address 540 * @param address the address
561 * @param session the session 541 * @param distance new distance value
562 * @param ats performance information
563 * @param ats_count number of elements in @a ats
564 */ 542 */
565void 543void
566GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address, 544GST_ats_update_distance (const struct GNUNET_HELLO_Address *address,
567 struct Session *session, 545 uint32_t distance)
568 const struct GNUNET_ATS_Information *ats,
569 uint32_t ats_count)
570{ 546{
571 struct GNUNET_ATS_Information *ats_new;
572 struct AddressInfo *ai; 547 struct AddressInfo *ai;
573 548
574 ai = find_ai (address, session); 549 ai = find_ai_no_session (address);
575 if (NULL == ai) 550 if (NULL == ai)
576 {
577 /* We sometimes create sessions just for sending a PING,
578 and if we get metrics for those, they were never known to
579 ATS which means we end up here (however, in this
580 case, the address must be an outbound address). */
581 GNUNET_break (GNUNET_YES !=
582 GNUNET_HELLO_address_check_option (address,
583 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
584 return; 551 return;
585 } 552 LOG (GNUNET_ERROR_TYPE_DEBUG,
586 /* Call to manipulation to manipulate ATS information */ 553 "Updated distance for peer `%s' to %u\n",
587 GNUNET_assert (NULL != GST_ats); 554 GNUNET_i2s (&address->peer),
588 if ((NULL == ats) || (0 == ats_count)) 555 distance);
556 ai->properties.distance = distance;
557 GST_manipulation_manipulate_metrics (address,
558 ai->session,
559 &ai->properties);
560 if (NULL != ai->ar)
561 GNUNET_ATS_address_update (ai->ar,
562 &ai->properties);
563}
564
565
566/**
567 * Notify ATS about property changes to an address's properties.
568 *
569 * @param address the address
570 * @param delay new delay value
571 */
572void
573GST_ats_update_delay (const struct GNUNET_HELLO_Address *address,
574 struct GNUNET_TIME_Relative delay)
575{
576 struct AddressInfo *ai;
577
578 ai = find_ai_no_session (address);
579 if (NULL == ai)
580 return;
581 LOG (GNUNET_ERROR_TYPE_DEBUG,
582 "Updated latency for peer `%s' to %s\n",
583 GNUNET_i2s (&address->peer),
584 GNUNET_STRINGS_relative_time_to_string (delay,
585 GNUNET_YES));
586 ai->properties.delay = delay;
587 GST_manipulation_manipulate_metrics (address,
588 ai->session,
589 &ai->properties);
590 if (NULL != ai->ar)
591 GNUNET_ATS_address_update (ai->ar,
592 &ai->properties);
593}
594
595
596/**
597 * Notify ATS about utilization changes to an address.
598 *
599 * @param address our information about the address
600 * @param bps_in new utilization inbound
601 * @param bps_out new utilization outbound
602 */
603void
604GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address,
605 uint32_t bps_in,
606 uint32_t bps_out)
607{
608 struct AddressInfo *ai;
609
610 ai = find_ai_no_session (address);
611 if (NULL == ai)
589 return; 612 return;
590 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 613 LOG (GNUNET_ERROR_TYPE_DEBUG,
591 "Updating metrics for peer `%s' address %s session %p\n", 614 "Updating utilization for peer `%s' address %s: %u/%u\n",
592 GNUNET_i2s (&address->peer), 615 GNUNET_i2s (&address->peer),
593 GST_plugins_a2s (address), 616 GST_plugins_a2s (address),
594 session); 617 (unsigned int) bps_in,
595 ats_new = GST_manipulation_manipulate_metrics (address, 618 (unsigned int) bps_out);
596 session, 619 ai->properties.utilization_in = bps_in;
597 ats, 620 ai->properties.utilization_out = bps_out;
598 ats_count); 621 GST_manipulation_manipulate_metrics (address,
622 ai->session,
623 &ai->properties);
599 if (NULL != ai->ar) 624 if (NULL != ai->ar)
600 GNUNET_ATS_address_update (ai->ar, 625 GNUNET_ATS_address_update (ai->ar,
601 ats_new, 626 &ai->properties);
602 ats_count);
603 GNUNET_free_non_null (ats_new);
604} 627}
605 628
606 629
@@ -616,10 +639,10 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address)
616{ 639{
617 struct AddressInfo *ai; 640 struct AddressInfo *ai;
618 641
619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 642 LOG (GNUNET_ERROR_TYPE_DEBUG,
620 "Address %s of peer %s expired\n", 643 "Address %s of peer %s expired\n",
621 GST_plugins_a2s (address), 644 GST_plugins_a2s (address),
622 GNUNET_i2s (&address->peer)); 645 GNUNET_i2s (&address->peer));
623 ai = find_ai_no_session (address); 646 ai = find_ai_no_session (address);
624 if (NULL == ai) 647 if (NULL == ai)
625 { 648 {
@@ -632,10 +655,9 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address)
632 ai)); 655 ai));
633 publish_p2a_stat_update (); 656 publish_p2a_stat_update ();
634 GNUNET_break (NULL == ai->session); 657 GNUNET_break (NULL == ai->session);
635 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 658 LOG (GNUNET_ERROR_TYPE_DEBUG,
636 "transport-ats", 659 "Telling ATS to destroy address from peer %s\n",
637 "Telling ATS to destroy address from peer %s\n", 660 GNUNET_i2s (&address->peer));
638 GNUNET_i2s (&address->peer));
639 if (NULL != ai->ar) 661 if (NULL != ai->ar)
640 { 662 {
641 /* We usually should not have a session here when we 663 /* We usually should not have a session here when we