aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/gnunet-service-transport.c3
-rw-r--r--src/transport/gnunet-service-transport_ats.c176
-rw-r--r--src/transport/gnunet-service-transport_ats.h40
3 files changed, 155 insertions, 64 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 9cf4bdcac..8e2a135f2 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -582,7 +582,8 @@ plugin_env_session_end (void *cls,
582 GST_plugins_a2s (address)); 582 GST_plugins_a2s (address));
583 583
584 GST_neighbours_session_terminated (&address->peer, session); 584 GST_neighbours_session_terminated (&address->peer, session);
585 GST_ats_del_session (address, session); 585 GST_ats_del_session (address,
586 session);
586 GST_blacklist_abort_matching (address, session); 587 GST_blacklist_abort_matching (address, session);
587 588
588 for (sk = sk_head; NULL != sk; sk = sk->next) 589 for (sk = sk_head; NULL != sk; sk = sk->next)
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c
index 8eb829875..c866eadd9 100644
--- a/src/transport/gnunet-service-transport_ats.c
+++ b/src/transport/gnunet-service-transport_ats.c
@@ -18,7 +18,7 @@
18 Boston, MA 02110-1301, USA. 18 Boston, MA 02110-1301, USA.
19*/ 19*/
20/** 20/**
21 * @file transport/gnunet-service-transport_ats.h 21 * @file transport/gnunet-service-transport_ats.c
22 * @brief interfacing between transport and ATS service 22 * @brief interfacing between transport and ATS service
23 * @author Christian Grothoff 23 * @author Christian Grothoff
24 */ 24 */
@@ -29,6 +29,9 @@
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/**
33 * Log convenience function.
34 */
32#define LOG(kind,...) GNUNET_log_from(kind, "transport-ats", __VA_ARGS__) 35#define LOG(kind,...) GNUNET_log_from(kind, "transport-ats", __VA_ARGS__)
33 36
34 37
@@ -39,7 +42,8 @@ struct AddressInfo
39{ 42{
40 43
41 /** 44 /**
42 * The address (with peer identity). 45 * The address (with peer identity). Must never change
46 * while this struct is in the #p2a map.
43 */ 47 */
44 struct GNUNET_HELLO_Address *address; 48 struct GNUNET_HELLO_Address *address;
45 49
@@ -100,8 +104,9 @@ static struct GNUNET_CONTAINER_MultiPeerMap *p2a;
100 */ 104 */
101static unsigned int num_blocked; 105static unsigned int num_blocked;
102 106
107
103/** 108/**
104 * Closure for #find_ai(). 109 * Closure for #find_ai_cb() and #find_ai_no_session_cb().
105 */ 110 */
106struct FindClosure 111struct FindClosure
107{ 112{
@@ -144,7 +149,9 @@ publish_p2a_stat_update ()
144 149
145 150
146/** 151/**
147 * Find matching address info. 152 * Find matching address info. Both the address and the session
153 * must match; note that expired addresses are still found (as
154 * the session kind-of keeps those alive).
148 * 155 *
149 * @param cls the `struct FindClosure` 156 * @param cls the `struct FindClosure`
150 * @param key which peer is this about 157 * @param key which peer is this about
@@ -167,15 +174,13 @@ find_ai_cb (void *cls,
167 fc->ret = ai; 174 fc->ret = ai;
168 return GNUNET_NO; 175 return GNUNET_NO;
169 } 176 }
170 GNUNET_assert ( (fc->session != ai->session) ||
171 (NULL == ai->session) );
172 return GNUNET_YES; 177 return GNUNET_YES;
173} 178}
174 179
175 180
176/** 181/**
177 * Find the address information struct for the 182 * Find the address information struct for the
178 * given address and session. 183 * given @a address and @a session.
179 * 184 *
180 * @param address address to look for 185 * @param address address to look for
181 * @param session session to match for inbound connections 186 * @param session session to match for inbound connections
@@ -253,6 +258,8 @@ find_ai_no_session (const struct GNUNET_HELLO_Address *address)
253 258
254/** 259/**
255 * Test if ATS knows about this @a address and @a session. 260 * Test if ATS knows about this @a address and @a session.
261 * Note that even if the address is expired, we return
262 * #GNUNET_YES if the respective session matches.
256 * 263 *
257 * @param address the address 264 * @param address the address
258 * @param session the session 265 * @param session the session
@@ -267,7 +274,8 @@ GST_ats_is_known (const struct GNUNET_HELLO_Address *address,
267 274
268 275
269/** 276/**
270 * Test if ATS knows about this @a address. 277 * Test if ATS knows about this @a address. Note that
278 * expired addresses do not count.
271 * 279 *
272 * @param address the address 280 * @param address the address
273 * @return #GNUNET_YES if @a address is known, #GNUNET_NO if not. 281 * @return #GNUNET_YES if @a address is known, #GNUNET_NO if not.
@@ -324,7 +332,8 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
324{ 332{
325 struct AddressInfo *ai; 333 struct AddressInfo *ai;
326 334
327 ai = find_ai (address, session); 335 ai = find_ai (address,
336 session);
328 if (NULL == ai) 337 if (NULL == ai)
329 { 338 {
330 GNUNET_assert (0); 339 GNUNET_assert (0);
@@ -356,7 +365,14 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
356 (GNUNET_NO == 365 (GNUNET_NO ==
357 GNUNET_ATS_address_del_session (ai->ar, 366 GNUNET_ATS_address_del_session (ai->ar,
358 session)) ) 367 session)) )
368 {
359 GNUNET_ATS_address_destroy (ai->ar); 369 GNUNET_ATS_address_destroy (ai->ar);
370 }
371 /* "ar" has been freed, regardless how the branch
372 above played out: it was either freed in
373 #GNUNET_ATS_address_del_session() because it was
374 incoming, or explicitly in
375 #GNUNET_ATS_address_del_session(). */
360 ai->ar = NULL; 376 ai->ar = NULL;
361 377
362 /* determine when the address should come back to life */ 378 /* determine when the address should come back to life */
@@ -371,7 +387,7 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
371 387
372/** 388/**
373 * Reset address blocking time. Resets the exponential 389 * Reset address blocking time. Resets the exponential
374 * back-off timer for this address to zero. Done when 390 * back-off timer for this address to zero. Called when
375 * an address was used to create a successful connection. 391 * an address was used to create a successful connection.
376 * 392 *
377 * @param address the address to reset the blocking timer 393 * @param address the address to reset the blocking timer
@@ -396,10 +412,10 @@ GST_ats_block_reset (const struct GNUNET_HELLO_Address *address,
396 412
397 413
398/** 414/**
399 * Notify ATS about the a new inbound address. We may already 415 * Notify ATS about a new inbound @a address. The @a address in
400 * know the address (as this is called each time we receive 416 * combination with the @a session must be new, but this function will
401 * a message from an inbound connection). If the address is 417 * perform a santiy check. If the @a address is indeed new, make it
402 * indeed new, make it available to ATS. 418 * available to ATS.
403 * 419 *
404 * @param address the address 420 * @param address the address
405 * @param session the session 421 * @param session the session
@@ -413,12 +429,13 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
413 struct GNUNET_ATS_AddressRecord *ar; 429 struct GNUNET_ATS_AddressRecord *ar;
414 struct AddressInfo *ai; 430 struct AddressInfo *ai;
415 431
416 /* valid new address, let ATS know! */ 432 /* Sanity checks for a valid inbound address */
417 if (NULL == address->transport_name) 433 if (NULL == address->transport_name)
418 { 434 {
419 GNUNET_break(0); 435 GNUNET_break(0);
420 return; 436 return;
421 } 437 }
438 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope);
422 GNUNET_assert (GNUNET_YES == 439 GNUNET_assert (GNUNET_YES ==
423 GNUNET_HELLO_address_check_option (address, 440 GNUNET_HELLO_address_check_option (address,
424 GNUNET_HELLO_ADDRESS_INFO_INBOUND)); 441 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
@@ -431,20 +448,18 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
431 GNUNET_break (0); 448 GNUNET_break (0);
432 return; 449 return;
433 } 450 }
434 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); 451 /* Is indeed new, let's tell ATS */
435 LOG (GNUNET_ERROR_TYPE_DEBUG, 452 LOG (GNUNET_ERROR_TYPE_DEBUG,
436 "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n", 453 "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n",
437 GNUNET_i2s (&address->peer), 454 GNUNET_i2s (&address->peer),
438 (0 == address->address_length) 455 GST_plugins_a2s (address),
439 ? "<inbound>"
440 : GST_plugins_a2s (address),
441 session, 456 session,
442 GNUNET_ATS_print_network_type (prop->scope)); 457 GNUNET_ATS_print_network_type (prop->scope));
443 ar = GNUNET_ATS_address_add (GST_ats, 458 ar = GNUNET_ATS_address_add (GST_ats,
444 address, 459 address,
445 session, 460 session,
446 prop); 461 prop);
447 GNUNET_break (NULL != ar); 462 GNUNET_assert (NULL != ar);
448 ai = GNUNET_new (struct AddressInfo); 463 ai = GNUNET_new (struct AddressInfo);
449 ai->address = GNUNET_HELLO_address_copy (address); 464 ai->address = GNUNET_HELLO_address_copy (address);
450 ai->session = session; 465 ai->session = session;
@@ -472,7 +487,7 @@ GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
472 struct GNUNET_ATS_AddressRecord *ar; 487 struct GNUNET_ATS_AddressRecord *ar;
473 struct AddressInfo *ai; 488 struct AddressInfo *ai;
474 489
475 /* valid new address, let ATS know! */ 490 /* validadte address */
476 if (NULL == address->transport_name) 491 if (NULL == address->transport_name)
477 { 492 {
478 GNUNET_break(0); 493 GNUNET_break(0);
@@ -484,17 +499,17 @@ GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
484 ai = find_ai_no_session (address); 499 ai = find_ai_no_session (address);
485 GNUNET_assert (NULL == ai); 500 GNUNET_assert (NULL == ai);
486 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); 501 GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope);
502
503 /* address seems sane, let's tell ATS */
487 LOG (GNUNET_ERROR_TYPE_INFO, 504 LOG (GNUNET_ERROR_TYPE_INFO,
488 "Notifying ATS about peer `%s''s new address `%s'\n", 505 "Notifying ATS about peer %s's new address `%s'\n",
489 GNUNET_i2s (&address->peer), 506 GNUNET_i2s (&address->peer),
490 (0 == address->address_length) 507 GST_plugins_a2s (address));
491 ? "<inbound>"
492 : GST_plugins_a2s (address));
493 ar = GNUNET_ATS_address_add (GST_ats, 508 ar = GNUNET_ATS_address_add (GST_ats,
494 address, 509 address,
495 NULL, 510 NULL,
496 prop); 511 prop);
497 GNUNET_break (NULL != ar); 512 GNUNET_assert (NULL != ar);
498 ai = GNUNET_new (struct AddressInfo); 513 ai = GNUNET_new (struct AddressInfo);
499 ai->address = GNUNET_HELLO_address_copy (address); 514 ai->address = GNUNET_HELLO_address_copy (address);
500 ai->ar = ar; 515 ai->ar = ar;
@@ -508,8 +523,10 @@ GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
508 523
509 524
510/** 525/**
511 * Notify ATS about a new session now existing for the given 526 * Notify ATS about a new @a session now existing for the given
512 * address. 527 * @a address. Essentially, an outbound @a address was used
528 * to establish a @a session. It is safe to call this function
529 * repeatedly for the same @a address and @a session pair.
513 * 530 *
514 * @param address the address 531 * @param address the address
515 * @param session the session 532 * @param session the session
@@ -523,22 +540,28 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
523 ai = find_ai (address, NULL); 540 ai = find_ai (address, NULL);
524 if (NULL == ai) 541 if (NULL == ai)
525 { 542 {
526 /* We may already be aware of the session, even if some other part 543 /* We may simply already be aware of the session, even if some
527 of the code could not tell if it just created a new session or 544 other part of the code could not tell if it just created a new
528 just got one recycled from the plugin; hence, we may be called 545 session or just got one recycled from the plugin; hence, we may
529 with "new" session even for an "old" session; in that case, 546 be called with "new" session even for an "old" session; in that
530 check that this is the case, but just ignore it. */ 547 case, check that this is the case, but just ignore it. */
531 GNUNET_assert (NULL != (find_ai (address, session))); 548 GNUNET_assert (NULL != (find_ai (address, session)));
532 return; 549 return;
533 } 550 }
534 GNUNET_break (NULL == ai->session); 551 GNUNET_assert (NULL == ai->session);
535 ai->session = session; 552 ai->session = session;
536 LOG (GNUNET_ERROR_TYPE_DEBUG, 553 LOG (GNUNET_ERROR_TYPE_DEBUG,
537 "Telling ATS about new session for peer %s\n", 554 "Telling ATS about new session for peer %s\n",
538 GNUNET_i2s (&address->peer)); 555 GNUNET_i2s (&address->peer));
556 /* Note that the address might currently be blocked; we only
557 tell ATS about the session if the address is currently not
558 blocked; otherwise, ATS will be told about the session on
559 unblock. */
539 if (NULL != ai->ar) 560 if (NULL != ai->ar)
540 GNUNET_ATS_address_add_session (ai->ar, 561 GNUNET_ATS_address_add_session (ai->ar,
541 session); 562 session);
563 else
564 GNUNET_assert (NULL != ai->unblock_task);
542} 565}
543 566
544 567
@@ -576,8 +599,12 @@ destroy_ai (struct AddressInfo *ai)
576 599
577 600
578/** 601/**
579 * Notify ATS that the session (but not the address) of 602 * Notify ATS that the @a session (but not the @a address) of
580 * a given address is no longer relevant. 603 * a given @a address is no longer relevant. (The @a session
604 * went down.) This function may be called even if for the
605 * respective outbound address #GST_ats_new_session() was
606 * never called and thus the pair is unknown to ATS. In this
607 * case, the call is simply ignored.
581 * 608 *
582 * @param address the address 609 * @param address the address
583 * @param session the session 610 * @param session the session
@@ -604,7 +631,6 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
604 GNUNET_break (GNUNET_YES != 631 GNUNET_break (GNUNET_YES !=
605 GNUNET_HELLO_address_check_option (address, 632 GNUNET_HELLO_address_check_option (address,
606 GNUNET_HELLO_ADDRESS_INFO_INBOUND)); 633 GNUNET_HELLO_ADDRESS_INFO_INBOUND));
607
608 return; 634 return;
609 } 635 }
610 GNUNET_assert (session == ai->session); 636 GNUNET_assert (session == ai->session);
@@ -619,37 +645,66 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
619 session is dead as well, clean up */ 645 session is dead as well, clean up */
620 if (NULL != ai->ar) 646 if (NULL != ai->ar)
621 { 647 {
622 GNUNET_break (GNUNET_YES == 648 /* Address expired but not blocked, and thus 'ar' was still
623 GNUNET_ATS_address_del_session (ai->ar, 649 live because of the session; deleting just the session
624 session)); 650 will do for an inbound session, but for an outbound we
651 then also need to destroy the address with ATS. */
652 if (GNUNET_NO ==
653 GNUNET_ATS_address_del_session (ai->ar,
654 session))
655 {
656 GNUNET_ATS_address_destroy (ai->ar);
657 }
658 /* "ar" has been freed, regardless how the branch
659 above played out: it was either freed in
660 #GNUNET_ATS_address_del_session() because it was
661 incoming, or explicitly in
662 #GNUNET_ATS_address_del_session(). */
663 ai->ar = NULL;
625 } 664 }
626 destroy_ai (ai); 665 destroy_ai (ai);
627 return; 666 return;
628 } 667 }
668
629 if (NULL == ai->ar) 669 if (NULL == ai->ar)
630 { 670 {
631 /* If ATS doesn't know about the address/session, and this was an 671 /* If ATS doesn't know about the address/session, this means
632 inbound session, so we must forget about the address as well. 672 this address was blocked. */
633 Otherwise, we are done as we have set `ai->session` to NULL
634 already. */
635 if (GNUNET_YES == 673 if (GNUNET_YES ==
636 GNUNET_HELLO_address_check_option (address, 674 GNUNET_HELLO_address_check_option (address,
637 GNUNET_HELLO_ADDRESS_INFO_INBOUND)) 675 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
638 GST_ats_expire_address (address); 676 {
677 /* This was a blocked inbound session, which now lost the
678 session. But inbound addresses are by themselves useless,
679 so we must forget about the address as well. */
680 destroy_ai (ai);
681 return;
682 }
683 /* Otherwise, we are done as we have set `ai->session` to NULL
684 already and ATS will simply not be told about the session when
685 the connection is unblocked and the outbound address becomes
686 available again. . */
639 return; 687 return;
640 } 688 }
689
690 /* This is the "simple" case where ATS knows about the session and
691 the address is neither blocked nor expired. Delete the session,
692 and if it was inbound, free the address as well. */
641 if (GNUNET_YES == 693 if (GNUNET_YES ==
642 GNUNET_ATS_address_del_session (ai->ar, 694 GNUNET_ATS_address_del_session (ai->ar,
643 session)) 695 session))
644 { 696 {
697 /* This was an inbound address, the session is now gone, so we
698 need to also forget about the address itself. */
645 ai->ar = NULL; 699 ai->ar = NULL;
646 GST_ats_expire_address (address); 700 destroy_ai (address);
647 } 701 }
648} 702}
649 703
650 704
651/** 705/**
652 * Notify ATS about DV distance change to an address's. 706 * Notify ATS about DV @a distance change to an @a address.
707 * Does nothing if the @a address is not known to us.
653 * 708 *
654 * @param address the address 709 * @param address the address
655 * @param distance new distance value 710 * @param distance new distance value
@@ -662,15 +717,21 @@ GST_ats_update_distance (const struct GNUNET_HELLO_Address *address,
662 717
663 ai = find_ai_no_session (address); 718 ai = find_ai_no_session (address);
664 if (NULL == ai) 719 if (NULL == ai)
720 {
721 /* We do not know about this address, do nothing. */
665 return; 722 return;
723 }
666 LOG (GNUNET_ERROR_TYPE_DEBUG, 724 LOG (GNUNET_ERROR_TYPE_DEBUG,
667 "Updated distance for peer `%s' to %u\n", 725 "Updated distance for peer `%s' to %u\n",
668 GNUNET_i2s (&address->peer), 726 GNUNET_i2s (&address->peer),
669 distance); 727 distance);
670 ai->properties.distance = distance; 728 ai->properties.distance = distance;
729 /* Give manipulation its chance to change metrics */
671 GST_manipulation_manipulate_metrics (address, 730 GST_manipulation_manipulate_metrics (address,
672 ai->session, 731 ai->session,
673 &ai->properties); 732 &ai->properties);
733 /* Address may be blocked, only give ATS if address is
734 currently active. */
674 if (NULL != ai->ar) 735 if (NULL != ai->ar)
675 GNUNET_ATS_address_update (ai->ar, 736 GNUNET_ATS_address_update (ai->ar,
676 &ai->properties); 737 &ai->properties);
@@ -678,7 +739,8 @@ GST_ats_update_distance (const struct GNUNET_HELLO_Address *address,
678 739
679 740
680/** 741/**
681 * Notify ATS about property changes to an address's properties. 742 * Notify ATS about @a delay changes to properties of an @a address.
743 * Does nothing if the @a address is not known to us.
682 * 744 *
683 * @param address the address 745 * @param address the address
684 * @param delay new delay value 746 * @param delay new delay value
@@ -691,16 +753,22 @@ GST_ats_update_delay (const struct GNUNET_HELLO_Address *address,
691 753
692 ai = find_ai_no_session (address); 754 ai = find_ai_no_session (address);
693 if (NULL == ai) 755 if (NULL == ai)
756 {
757 /* We do not know about this address, do nothing. */
694 return; 758 return;
759 }
695 LOG (GNUNET_ERROR_TYPE_DEBUG, 760 LOG (GNUNET_ERROR_TYPE_DEBUG,
696 "Updated latency for peer `%s' to %s\n", 761 "Updated latency for peer `%s' to %s\n",
697 GNUNET_i2s (&address->peer), 762 GNUNET_i2s (&address->peer),
698 GNUNET_STRINGS_relative_time_to_string (delay, 763 GNUNET_STRINGS_relative_time_to_string (delay,
699 GNUNET_YES)); 764 GNUNET_YES));
700 ai->properties.delay = delay; 765 ai->properties.delay = delay;
766 /* Give manipulation its chance to change metrics */
701 GST_manipulation_manipulate_metrics (address, 767 GST_manipulation_manipulate_metrics (address,
702 ai->session, 768 ai->session,
703 &ai->properties); 769 &ai->properties);
770 /* Address may be blocked, only give ATS if address is
771 currently active. */
704 if (NULL != ai->ar) 772 if (NULL != ai->ar)
705 GNUNET_ATS_address_update (ai->ar, 773 GNUNET_ATS_address_update (ai->ar,
706 &ai->properties); 774 &ai->properties);
@@ -708,7 +776,8 @@ GST_ats_update_delay (const struct GNUNET_HELLO_Address *address,
708 776
709 777
710/** 778/**
711 * Notify ATS about utilization changes to an address. 779 * Notify ATS about utilization changes to an @a address.
780 * Does nothing if the @a address is not known to us.
712 * 781 *
713 * @param address our information about the address 782 * @param address our information about the address
714 * @param bps_in new utilization inbound 783 * @param bps_in new utilization inbound
@@ -723,7 +792,10 @@ GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address,
723 792
724 ai = find_ai_no_session (address); 793 ai = find_ai_no_session (address);
725 if (NULL == ai) 794 if (NULL == ai)
795 {
796 /* We do not know about this address, do nothing. */
726 return; 797 return;
798 }
727 LOG (GNUNET_ERROR_TYPE_DEBUG, 799 LOG (GNUNET_ERROR_TYPE_DEBUG,
728 "Updating utilization for peer `%s' address %s: %u/%u\n", 800 "Updating utilization for peer `%s' address %s: %u/%u\n",
729 GNUNET_i2s (&address->peer), 801 GNUNET_i2s (&address->peer),
@@ -732,9 +804,12 @@ GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address,
732 (unsigned int) bps_out); 804 (unsigned int) bps_out);
733 ai->properties.utilization_in = bps_in; 805 ai->properties.utilization_in = bps_in;
734 ai->properties.utilization_out = bps_out; 806 ai->properties.utilization_out = bps_out;
807 /* Give manipulation its chance to change metrics */
735 GST_manipulation_manipulate_metrics (address, 808 GST_manipulation_manipulate_metrics (address,
736 ai->session, 809 ai->session,
737 &ai->properties); 810 &ai->properties);
811 /* Address may be blocked, only give ATS if address is
812 currently active. */
738 if (NULL != ai->ar) 813 if (NULL != ai->ar)
739 GNUNET_ATS_address_update (ai->ar, 814 GNUNET_ATS_address_update (ai->ar,
740 &ai->properties); 815 &ai->properties);
@@ -765,9 +840,12 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address)
765 } 840 }
766 if (NULL != ai->session) 841 if (NULL != ai->session)
767 { 842 {
843 /* Got an active session, just remember the expiration
844 and act upon it when the session goes down. */
768 ai->expired = GNUNET_YES; 845 ai->expired = GNUNET_YES;
769 return; 846 return;
770 } 847 }
848 /* Address expired, no session, free resources */
771 destroy_ai (ai); 849 destroy_ai (ai);
772} 850}
773 851
diff --git a/src/transport/gnunet-service-transport_ats.h b/src/transport/gnunet-service-transport_ats.h
index de0800d0a..75743606a 100644
--- a/src/transport/gnunet-service-transport_ats.h
+++ b/src/transport/gnunet-service-transport_ats.h
@@ -43,6 +43,8 @@ GST_ats_done (void);
43 43
44/** 44/**
45 * Test if ATS knows about this @a address and @a session. 45 * Test if ATS knows about this @a address and @a session.
46 * Note that even if the address is expired, we return
47 * #GNUNET_YES if the respective session matches.
46 * 48 *
47 * @param address the address 49 * @param address the address
48 * @param session the session 50 * @param session the session
@@ -54,7 +56,8 @@ GST_ats_is_known (const struct GNUNET_HELLO_Address *address,
54 56
55 57
56/** 58/**
57 * Test if ATS knows about this @a address. 59 * Test if ATS knows about this @a address. Note that
60 * expired addresses do not count.
58 * 61 *
59 * @param address the address 62 * @param address the address
60 * @return #GNUNET_YES if @a address is known, #GNUNET_NO if not. 63 * @return #GNUNET_YES if @a address is known, #GNUNET_NO if not.
@@ -79,7 +82,7 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
79 82
80/** 83/**
81 * Reset address blocking time. Resets the exponential 84 * Reset address blocking time. Resets the exponential
82 * back-off timer for this address to zero. Done when 85 * back-off timer for this address to zero. Called when
83 * an address was used to create a successful connection. 86 * an address was used to create a successful connection.
84 * 87 *
85 * @param address the address to reset the blocking timer 88 * @param address the address to reset the blocking timer
@@ -91,10 +94,10 @@ GST_ats_block_reset (const struct GNUNET_HELLO_Address *address,
91 94
92 95
93/** 96/**
94 * Notify ATS about the a new inbound address. We may already 97 * Notify ATS about a new inbound @a address. The @a address in
95 * know the address (as this is called each time we receive 98 * combination with the @a session must be new, but this function will
96 * a message from an inbound connection). If the address is 99 * perform a santiy check. If the @a address is indeed new, make it
97 * indeed new, make it available to ATS. 100 * available to ATS.
98 * 101 *
99 * @param address the address 102 * @param address the address
100 * @param session the session 103 * @param session the session
@@ -107,7 +110,7 @@ GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
107 110
108 111
109/** 112/**
110 * Notify ATS about the new address including the network this address is 113 * Notify ATS about a new address including the network this address is
111 * located in. The address must NOT be inbound and must be new to ATS. 114 * located in. The address must NOT be inbound and must be new to ATS.
112 * 115 *
113 * @param address the address 116 * @param address the address
@@ -119,8 +122,10 @@ GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
119 122
120 123
121/** 124/**
122 * Notify ATS about a new session now existing for the given 125 * Notify ATS about a new @a session now existing for the given
123 * address. 126 * @a address. Essentially, an outbound @a address was used
127 * to establish a @a session. It is safe to call this function
128 * repeatedly for the same @a address and @a session pair.
124 * 129 *
125 * @param address the address 130 * @param address the address
126 * @param session the session 131 * @param session the session
@@ -146,7 +151,8 @@ GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address,
146 151
147 152
148/** 153/**
149 * Notify ATS about utilization changes to an address. 154 * Notify ATS about utilization changes to an @a address.
155 * Does nothing if the @a address is not known to us.
150 * 156 *
151 * @param address our information about the address 157 * @param address our information about the address
152 * @param bps_in new utilization inbound 158 * @param bps_in new utilization inbound
@@ -159,7 +165,8 @@ GST_ats_update_utilization (const struct GNUNET_HELLO_Address *address,
159 165
160 166
161/** 167/**
162 * Notify ATS about property changes to an address's properties. 168 * Notify ATS about @a delay changes to properties of an @a address.
169 * Does nothing if the @a address is not known to us.
163 * 170 *
164 * @param address the address 171 * @param address the address
165 * @param session the session 172 * @param session the session
@@ -171,7 +178,8 @@ GST_ats_update_delay (const struct GNUNET_HELLO_Address *address,
171 178
172 179
173/** 180/**
174 * Notify ATS about property changes to an address's properties. 181 * Notify ATS about DV @a distance change to an @a address.
182 * Does nothing if the @a address is not known to us.
175 * 183 *
176 * @param address the address 184 * @param address the address
177 * @param distance new distance value 185 * @param distance new distance value
@@ -182,8 +190,12 @@ GST_ats_update_distance (const struct GNUNET_HELLO_Address *address,
182 190
183 191
184/** 192/**
185 * Notify ATS that the session (but not the address) of 193 * Notify ATS that the @a session (but not the @a address) of
186 * a given address is no longer relevant. 194 * a given @a address is no longer relevant. (The @a session
195 * went down.) This function may be called even if for the
196 * respective outbound address #GST_ats_new_session() was
197 * never called and thus the pair is unknown to ATS. In this
198 * case, the call is simply ignored.
187 * 199 *
188 * @param address the address 200 * @param address the address
189 * @param session the session 201 * @param session the session