aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ats/ats_api_scheduling.c1
-rw-r--r--src/transport/gnunet-service-transport_ats.c114
2 files changed, 62 insertions, 53 deletions
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index 355a279ba..c37032f35 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -790,7 +790,6 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
790} 790}
791 791
792 792
793
794/** 793/**
795 * An address got destroyed, stop using it as a valid address. 794 * An address got destroyed, stop using it as a valid address.
796 * 795 *
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c
index 5124cd578..b41ce8987 100644
--- a/src/transport/gnunet-service-transport_ats.c
+++ b/src/transport/gnunet-service-transport_ats.c
@@ -199,7 +199,8 @@ find_ai (const struct GNUNET_HELLO_Address *address,
199 199
200 200
201/** 201/**
202 * Find matching address info, ignoring sessions. 202 * Find matching address info, ignoring sessions and expired
203 * addresses.
203 * 204 *
204 * @param cls the `struct FindClosure` 205 * @param cls the `struct FindClosure`
205 * @param key which peer is this about 206 * @param key which peer is this about
@@ -214,6 +215,8 @@ find_ai_no_session_cb (void *cls,
214 struct FindClosure *fc = cls; 215 struct FindClosure *fc = cls;
215 struct AddressInfo *ai = value; 216 struct AddressInfo *ai = value;
216 217
218 if (ai->expired)
219 return GNUNET_YES; /* expired do not count here */
217 if (0 == 220 if (0 ==
218 GNUNET_HELLO_address_cmp (fc->address, 221 GNUNET_HELLO_address_cmp (fc->address,
219 ai->address)) 222 ai->address))
@@ -272,7 +275,11 @@ GST_ats_is_known (const struct GNUNET_HELLO_Address *address,
272int 275int
273GST_ats_is_known_no_session (const struct GNUNET_HELLO_Address *address) 276GST_ats_is_known_no_session (const struct GNUNET_HELLO_Address *address)
274{ 277{
275 return (NULL != find_ai_no_session (address)) ? GNUNET_YES : GNUNET_NO; 278 struct AddressInfo *ai;
279
280 return (NULL != find_ai_no_session (address))
281 ? GNUNET_YES
282 : GNUNET_NO;
276} 283}
277 284
278 285
@@ -538,6 +545,34 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
538 545
539 546
540/** 547/**
548 * Release memory used by the given address data.
549 *
550 * @param ai the `struct AddressInfo`
551 */
552static void
553destroy_ai (struct AddressInfo *ai)
554{
555 GNUNET_assert (NULL == ai->session);
556 GNUNET_assert (NULL == ai->unblock_task);
557 GNUNET_assert (GNUNET_YES ==
558 GNUNET_CONTAINER_multipeermap_remove (p2a,
559 &ai->address->peer,
560 ai));
561 LOG (GNUNET_ERROR_TYPE_DEBUG,
562 "Telling ATS to destroy address from peer %s\n",
563 GNUNET_i2s (&ai->address->peer));
564 if (NULL != ai->ar)
565 {
566 GNUNET_ATS_address_destroy (ai->ar);
567 ai->ar = NULL;
568 }
569 publish_p2a_stat_update ();
570 GNUNET_HELLO_address_free (ai->address);
571 GNUNET_free (ai);
572}
573
574
575/**
541 * Notify ATS that the session (but not the address) of 576 * Notify ATS that the session (but not the address) of
542 * a given address is no longer relevant. 577 * a given address is no longer relevant.
543 * 578 *
@@ -575,16 +610,28 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
575 "Telling ATS to destroy session %p from peer %s\n", 610 "Telling ATS to destroy session %p from peer %s\n",
576 session, 611 session,
577 GNUNET_i2s (&address->peer)); 612 GNUNET_i2s (&address->peer));
613 if (GNUNET_YES == ai->expired)
614 {
615 /* last reason to keep this 'ai' around is now gone, the
616 session is dead as well, clean up */
617 if (NULL != ai->ar)
618 {
619 GNUNET_break (GNUNET_YES ==
620 GNUNET_ATS_address_del_session (ai->ar,
621 session));
622 }
623 destroy_ai (ai);
624 return;
625 }
578 if (NULL == ai->ar) 626 if (NULL == ai->ar)
579 { 627 {
580 /* If ATS doesn't know about the address/session, and this was an 628 /* If ATS doesn't know about the address/session, and this was an
581 inbound session or one that expired, then we must forget about 629 inbound session, so we must forget about the address as well.
582 the address as well. Otherwise, we are done as we have set 630 Otherwise, we are done as we have set `ai->session` to NULL
583 `ai->session` to NULL already. */ 631 already. */
584 if ( (GNUNET_YES == ai->expired) || 632 if (GNUNET_YES ==
585 (GNUNET_YES == 633 GNUNET_HELLO_address_check_option (address,
586 GNUNET_HELLO_address_check_option (address, 634 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
587 GNUNET_HELLO_ADDRESS_INFO_INBOUND)) )
588 GST_ats_expire_address (address); 635 GST_ats_expire_address (address);
589 return; 636 return;
590 } 637 }
@@ -722,36 +769,9 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address)
722 if (NULL != ai->session) 769 if (NULL != ai->session)
723 { 770 {
724 ai->expired = GNUNET_YES; 771 ai->expired = GNUNET_YES;
725 if (NULL != ai->ar)
726 {
727 GNUNET_ATS_address_destroy (ai->ar);
728 ai->ar = NULL;
729 }
730 return; 772 return;
731 } 773 }
732 GNUNET_assert (GNUNET_YES == 774 destroy_ai (ai);
733 GNUNET_CONTAINER_multipeermap_remove (p2a,
734 &address->peer,
735 ai));
736 LOG (GNUNET_ERROR_TYPE_DEBUG,
737 "Telling ATS to destroy address from peer %s\n",
738 GNUNET_i2s (&address->peer));
739 if (NULL != ai->ar)
740 {
741 /* We usually should not have a session here when we
742 expire an address, but during shutdown a session
743 may be active while validation causes the address
744 to 'expire'. So clean up both if necessary. */
745 if ( (NULL == ai->session) ||
746 (GNUNET_NO ==
747 GNUNET_ATS_address_del_session (ai->ar,
748 ai->session)) )
749 GNUNET_ATS_address_destroy (ai->ar);
750 ai->ar = NULL;
751 }
752 publish_p2a_stat_update ();
753 GNUNET_HELLO_address_free (ai->address);
754 GNUNET_free (ai);
755} 775}
756 776
757 777
@@ -774,29 +794,19 @@ GST_ats_init ()
774 * @return #GNUNET_OK (continue to iterate) 794 * @return #GNUNET_OK (continue to iterate)
775 */ 795 */
776static int 796static int
777destroy_ai (void *cls, 797destroy_ai_cb (void *cls,
778 const struct GNUNET_PeerIdentity *key, 798 const struct GNUNET_PeerIdentity *key,
779 void *value) 799 void *value)
780{ 800{
781 struct AddressInfo *ai = value; 801 struct AddressInfo *ai = value;
782 802
783 GNUNET_assert (GNUNET_YES ==
784 GNUNET_CONTAINER_multipeermap_remove (p2a,
785 key,
786 ai));
787 if (NULL != ai->unblock_task) 803 if (NULL != ai->unblock_task)
788 { 804 {
789 GNUNET_SCHEDULER_cancel (ai->unblock_task); 805 GNUNET_SCHEDULER_cancel (ai->unblock_task);
790 ai->unblock_task = NULL; 806 ai->unblock_task = NULL;
791 num_blocked--; 807 num_blocked--;
792 } 808 }
793 if (NULL != ai->ar) 809 destroy_ai (ai);
794 {
795 GNUNET_ATS_address_destroy (ai->ar);
796 ai->ar = NULL;
797 }
798 GNUNET_HELLO_address_free (ai->address);
799 GNUNET_free (ai);
800 return GNUNET_OK; 810 return GNUNET_OK;
801} 811}
802 812
@@ -808,7 +818,7 @@ void
808GST_ats_done () 818GST_ats_done ()
809{ 819{
810 GNUNET_CONTAINER_multipeermap_iterate (p2a, 820 GNUNET_CONTAINER_multipeermap_iterate (p2a,
811 &destroy_ai, 821 &destroy_ai_cb,
812 NULL); 822 NULL);
813 publish_p2a_stat_update (); 823 publish_p2a_stat_update ();
814 GNUNET_CONTAINER_multipeermap_destroy (p2a); 824 GNUNET_CONTAINER_multipeermap_destroy (p2a);