aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-05-24 11:44:13 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-05-24 11:44:13 +0000
commitd4295e8047e97026135c6a188274f64ae0549100 (patch)
treec5b65d5b98ce1caa47aa698ba85b43a2a2af3400
parentd0f6a7bb13abbe5c4a93ff09ead83c7e91bf5a11 (diff)
downloadgnunet-d4295e8047e97026135c6a188274f64ae0549100.tar.gz
gnunet-d4295e8047e97026135c6a188274f64ae0549100.zip
- fix memory corruption, various mantis bugs: 0002374 0002368 0002367 0002369
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index e0e19ab3d..6f1c4efa5 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -842,6 +842,61 @@ set_address (struct NeighbourAddress *na,
842 } 842 }
843} 843}
844 844
845/**
846 * Free a neighbour map entry.
847 *
848 * @param n entry to free
849 */
850static void
851free_neighbour_without_terminating_sessions (struct NeighbourMapEntry *n)
852{
853 struct MessageQueue *mq;
854 n->is_active = NULL; /* always free'd by its own continuation! */
855
856 /* fail messages currently in the queue */
857 while (NULL != (mq = n->messages_head))
858 {
859 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq);
860 if (NULL != mq->cont)
861 mq->cont (mq->cont_cls, GNUNET_SYSERR);
862 GNUNET_free (mq);
863 }
864 /* It is too late to send other peer disconnect notifications, but at
865 least internally we need to get clean... */
866 if (GNUNET_YES == test_connected (n))
867 {
868 GNUNET_STATISTICS_set (GST_stats,
869 gettext_noop ("# peers connected"),
870 --neighbours_connected,
871 GNUNET_NO);
872 disconnect_notify_cb (callback_cls, &n->id);
873 }
874
875 n->state = S_DISCONNECT_FINISHED;
876
877 GNUNET_assert (GNUNET_YES ==
878 GNUNET_CONTAINER_multihashmap_remove (neighbours,
879 &n->id.hashPubKey, n));
880
881 /* cut transport-level connection */
882 free_address (&n->primary_address);
883 free_address (&n->alternative_address);
884
885 // FIXME-ATS-API: we might want to be more specific about
886 // which states we do this from in the future (ATS should
887 // have given us a 'suggest_address' handle, and if we have
888 // such a handle, we should cancel the operation here!
889 GNUNET_ATS_suggest_address_cancel (GST_ats, &n->id);
890
891 if (GNUNET_SCHEDULER_NO_TASK != n->task)
892 {
893 GNUNET_SCHEDULER_cancel (n->task);
894 n->task = GNUNET_SCHEDULER_NO_TASK;
895 }
896 /* free rest of memory */
897 GNUNET_free (n);
898}
899
845 900
846/** 901/**
847 * Free a neighbour map entry. 902 * Free a neighbour map entry.
@@ -2055,13 +2110,12 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message,
2055 check_blacklist (peer, ts, address, session, ats, ats_count); 2110 check_blacklist (peer, ts, address, session, ats, ats_count);
2056 break; 2111 break;
2057 case S_DISCONNECT: 2112 case S_DISCONNECT:
2058 /* get rid of remains, ready to re-try */ 2113 /* get rid of remains without terminating sessions, ready to re-try */
2059 free_neighbour (n); 2114 free_neighbour_without_terminating_sessions (n);
2060 n = setup_neighbour (peer); 2115 n = setup_neighbour (peer);
2061 n->state = S_CONNECT_RECV_ATS; 2116 n->state = S_CONNECT_RECV_ATS;
2062 GNUNET_ATS_reset_backoff (GST_ats, peer); 2117 GNUNET_ATS_reset_backoff (GST_ats, peer);
2063 GNUNET_ATS_suggest_address (GST_ats, peer); 2118 GNUNET_ATS_suggest_address (GST_ats, peer);
2064 check_blacklist (peer, ts, address, session, ats, ats_count);
2065 break; 2119 break;
2066 case S_DISCONNECT_FINISHED: 2120 case S_DISCONNECT_FINISHED:
2067 /* should not be possible */ 2121 /* should not be possible */