diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-10-14 14:55:42 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-10-14 14:55:42 +0000 |
commit | 06a0f70d303cbe04544fb3488cd8e2af7c7051dc (patch) | |
tree | ceaf562952f6d9731b453f221f2224a0155d8e8b /src/transport/gnunet-service-transport_ats.c | |
parent | afe603aa0cf7fe51bb671112673f0bdecd1d4ea1 (diff) | |
download | gnunet-06a0f70d303cbe04544fb3488cd8e2af7c7051dc.tar.gz gnunet-06a0f70d303cbe04544fb3488cd8e2af7c7051dc.zip |
trying to fix #4003
Diffstat (limited to 'src/transport/gnunet-service-transport_ats.c')
-rw-r--r-- | src/transport/gnunet-service-transport_ats.c | 114 |
1 files changed, 62 insertions, 52 deletions
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, | |||
272 | int | 275 | int |
273 | GST_ats_is_known_no_session (const struct GNUNET_HELLO_Address *address) | 276 | GST_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 | */ | ||
552 | static void | ||
553 | destroy_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 | */ |
776 | static int | 796 | static int |
777 | destroy_ai (void *cls, | 797 | destroy_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 | |||
808 | GST_ats_done () | 818 | GST_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); |