diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-05-10 08:55:48 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-05-10 08:55:48 +0000 |
commit | aed525e2b6886224fd427ff33e5342338506d53a (patch) | |
tree | 9879b669fe44526fcab4fc776da28e5fe75dcb2d /src/transport | |
parent | d57d341091a48f394d215cb35c17fec53ee32b51 (diff) | |
download | gnunet-aed525e2b6886224fd427ff33e5342338506d53a.tar.gz gnunet-aed525e2b6886224fd427ff33e5342338506d53a.zip |
-improved fix for #2336
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/plugin_transport_udp.c | 78 |
1 files changed, 44 insertions, 34 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 338a9de2b..363af8a43 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -85,6 +85,7 @@ struct PrettyPrinterContext | |||
85 | uint16_t port; | 85 | uint16_t port; |
86 | }; | 86 | }; |
87 | 87 | ||
88 | |||
88 | struct Session | 89 | struct Session |
89 | { | 90 | { |
90 | /** | 91 | /** |
@@ -114,10 +115,11 @@ struct Session | |||
114 | */ | 115 | */ |
115 | struct GNUNET_TIME_Relative last_expected_delay; | 116 | struct GNUNET_TIME_Relative last_expected_delay; |
116 | 117 | ||
117 | |||
118 | struct GNUNET_ATS_Information ats; | 118 | struct GNUNET_ATS_Information ats; |
119 | 119 | ||
120 | struct FragmentationContext * frag_ctx; | 120 | struct FragmentationContext * frag_ctx; |
121 | |||
122 | int in_destroy; | ||
121 | }; | 123 | }; |
122 | 124 | ||
123 | 125 | ||
@@ -613,6 +615,28 @@ udp_plugin_check_address (void *cls, const void *addr, size_t addrlen) | |||
613 | 615 | ||
614 | 616 | ||
615 | /** | 617 | /** |
618 | * Task to free resources associated with a session. | ||
619 | * | ||
620 | * @param cls the 'struct Session' to free | ||
621 | * @param tc scheduler context (unused) | ||
622 | */ | ||
623 | static void | ||
624 | free_session (void *cls, | ||
625 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
626 | { | ||
627 | struct Session *s = cls; | ||
628 | |||
629 | if (s->frag_ctx != NULL) | ||
630 | { | ||
631 | GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag); | ||
632 | GNUNET_free (s->frag_ctx); | ||
633 | s->frag_ctx = NULL; | ||
634 | } | ||
635 | GNUNET_free (s); | ||
636 | } | ||
637 | |||
638 | |||
639 | /** | ||
616 | * Destroy a session, plugin is being unloaded. | 640 | * Destroy a session, plugin is being unloaded. |
617 | * | 641 | * |
618 | * @param cls unused | 642 | * @param cls unused |
@@ -628,35 +652,26 @@ disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value) | |||
628 | struct UDPMessageWrapper *udpw; | 652 | struct UDPMessageWrapper *udpw; |
629 | struct UDPMessageWrapper *next; | 653 | struct UDPMessageWrapper *next; |
630 | 654 | ||
655 | GNUNET_assert (GNUNET_YES != s->in_destroy); | ||
631 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 656 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
632 | "Session %p to peer `%s' address ended \n", | 657 | "Session %p to peer `%s' address ended \n", |
633 | s, | 658 | s, |
634 | GNUNET_i2s (&s->target), | 659 | GNUNET_i2s (&s->target), |
635 | GNUNET_a2s (s->sock_addr, s->addrlen)); | 660 | GNUNET_a2s (s->sock_addr, s->addrlen)); |
636 | if (s->frag_ctx != NULL) | 661 | next = plugin->ipv4_queue_head; |
637 | { | 662 | while (NULL != (udpw = next)) |
638 | GNUNET_FRAGMENT_context_destroy(s->frag_ctx->frag); | ||
639 | GNUNET_free (s->frag_ctx); | ||
640 | s->frag_ctx = NULL; | ||
641 | } | ||
642 | |||
643 | udpw = plugin->ipv4_queue_head; | ||
644 | while (udpw != NULL) | ||
645 | { | 663 | { |
646 | next = udpw->next; | 664 | next = udpw->next; |
647 | if (udpw->session == s) | 665 | if (udpw->session == s) |
648 | { | 666 | { |
649 | GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw); | 667 | GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw); |
650 | |||
651 | if (udpw->cont != NULL) | 668 | if (udpw->cont != NULL) |
652 | udpw->cont (udpw->cont_cls, &s->target, GNUNET_SYSERR); | 669 | udpw->cont (udpw->cont_cls, &s->target, GNUNET_SYSERR); |
653 | GNUNET_free (udpw); | 670 | GNUNET_free (udpw); |
654 | } | 671 | } |
655 | udpw = next; | ||
656 | } | 672 | } |
657 | 673 | next = plugin->ipv6_queue_head; | |
658 | udpw = plugin->ipv6_queue_head; | 674 | while (NULL != (udpw = next)) |
659 | while (udpw != NULL) | ||
660 | { | 675 | { |
661 | next = udpw->next; | 676 | next = udpw->next; |
662 | if (udpw->session == s) | 677 | if (udpw->session == s) |
@@ -669,20 +684,17 @@ disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value) | |||
669 | } | 684 | } |
670 | udpw = next; | 685 | udpw = next; |
671 | } | 686 | } |
672 | |||
673 | plugin->env->session_end (plugin->env->cls, &s->target, s); | 687 | plugin->env->session_end (plugin->env->cls, &s->target, s); |
674 | |||
675 | GNUNET_assert (GNUNET_YES == | 688 | GNUNET_assert (GNUNET_YES == |
676 | GNUNET_CONTAINER_multihashmap_remove (plugin->sessions, | 689 | GNUNET_CONTAINER_multihashmap_remove (plugin->sessions, |
677 | &s->target.hashPubKey, | 690 | &s->target.hashPubKey, |
678 | s)); | 691 | s)); |
679 | |||
680 | GNUNET_STATISTICS_set(plugin->env->stats, | 692 | GNUNET_STATISTICS_set(plugin->env->stats, |
681 | "# UDP sessions active", | 693 | "# UDP sessions active", |
682 | GNUNET_CONTAINER_multihashmap_size(plugin->sessions), | 694 | GNUNET_CONTAINER_multihashmap_size(plugin->sessions), |
683 | GNUNET_NO); | 695 | GNUNET_NO); |
684 | 696 | GNUNET_SCHEDULER_add_now (&free_session, s); | |
685 | GNUNET_free (s); | 697 | s->in_destroy = GNUNET_YES; |
686 | return GNUNET_OK; | 698 | return GNUNET_OK; |
687 | } | 699 | } |
688 | 700 | ||
@@ -772,9 +784,11 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, | |||
772 | return s; | 784 | return s; |
773 | } | 785 | } |
774 | 786 | ||
775 | static int session_cmp_it (void *cls, | 787 | |
776 | const GNUNET_HashCode * key, | 788 | static int |
777 | void *value) | 789 | session_cmp_it (void *cls, |
790 | const GNUNET_HashCode * key, | ||
791 | void *value) | ||
778 | { | 792 | { |
779 | struct SessionCompareContext * cctx = cls; | 793 | struct SessionCompareContext * cctx = cls; |
780 | const struct GNUNET_HELLO_Address *address = cctx->addr; | 794 | const struct GNUNET_HELLO_Address *address = cctx->addr; |
@@ -911,7 +925,9 @@ udp_plugin_get_session (void *cls, | |||
911 | return s; | 925 | return s; |
912 | } | 926 | } |
913 | 927 | ||
914 | static void enqueue (struct Plugin *plugin, struct UDPMessageWrapper * udpw) | 928 | |
929 | static void | ||
930 | enqueue (struct Plugin *plugin, struct UDPMessageWrapper * udpw) | ||
915 | { | 931 | { |
916 | 932 | ||
917 | if (udpw->session->addrlen == sizeof (struct sockaddr_in)) | 933 | if (udpw->session->addrlen == sizeof (struct sockaddr_in)) |
@@ -991,12 +1007,9 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg) | |||
991 | plugin->with_v6_ws = GNUNET_YES; | 1007 | plugin->with_v6_ws = GNUNET_YES; |
992 | } | 1008 | } |
993 | } | 1009 | } |
994 | |||
995 | } | 1010 | } |
996 | 1011 | ||
997 | 1012 | ||
998 | |||
999 | |||
1000 | /** | 1013 | /** |
1001 | * Function that can be used by the transport service to transmit | 1014 | * Function that can be used by the transport service to transmit |
1002 | * a message using the plugin. Note that in the case of a | 1015 | * a message using the plugin. Note that in the case of a |
@@ -1219,12 +1232,8 @@ process_inbound_tokenized_messages (void *cls, void *client, | |||
1219 | struct GNUNET_TIME_Relative delay; | 1232 | struct GNUNET_TIME_Relative delay; |
1220 | 1233 | ||
1221 | GNUNET_assert (si->session != NULL); | 1234 | GNUNET_assert (si->session != NULL); |
1222 | 1235 | if (GNUNET_YES == si->session->in_destroy) | |
1223 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains_value(plugin->sessions, | 1236 | return; |
1224 | &si->sender.hashPubKey, | ||
1225 | si->session)) | ||
1226 | return; | ||
1227 | |||
1228 | /* setup ATS */ | 1237 | /* setup ATS */ |
1229 | ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); | 1238 | ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); |
1230 | ats[0].value = htonl (1); | 1239 | ats[0].value = htonl (1); |
@@ -1695,7 +1704,8 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) | |||
1695 | } | 1704 | } |
1696 | } | 1705 | } |
1697 | 1706 | ||
1698 | size_t | 1707 | |
1708 | static size_t | ||
1699 | udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) | 1709 | udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) |
1700 | { | 1710 | { |
1701 | ssize_t sent; | 1711 | ssize_t sent; |