aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-05-10 08:55:48 +0000
committerChristian Grothoff <christian@grothoff.org>2012-05-10 08:55:48 +0000
commitaed525e2b6886224fd427ff33e5342338506d53a (patch)
tree9879b669fe44526fcab4fc776da28e5fe75dcb2d /src/transport
parentd57d341091a48f394d215cb35c17fec53ee32b51 (diff)
downloadgnunet-aed525e2b6886224fd427ff33e5342338506d53a.tar.gz
gnunet-aed525e2b6886224fd427ff33e5342338506d53a.zip
-improved fix for #2336
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/plugin_transport_udp.c78
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
88struct Session 89struct 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 */
623static void
624free_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
775static int session_cmp_it (void *cls, 787
776 const GNUNET_HashCode * key, 788static int
777 void *value) 789session_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
914static void enqueue (struct Plugin *plugin, struct UDPMessageWrapper * udpw) 928
929static void
930enqueue (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
1698size_t 1707
1708static size_t
1699udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock) 1709udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock)
1700{ 1710{
1701 ssize_t sent; 1711 ssize_t sent;