[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r15962 - gnunet/src/transport
From: |
gnunet |
Subject: |
[GNUnet-SVN] r15962 - gnunet/src/transport |
Date: |
Thu, 14 Jul 2011 18:44:45 +0200 |
Author: grothoff
Date: 2011-07-14 18:44:45 +0200 (Thu, 14 Jul 2011)
New Revision: 15962
Modified:
gnunet/src/transport/gnunet-service-transport.c
Log:
fixing use-after free and/or possible bad recursion on disconnect
Modified: gnunet/src/transport/gnunet-service-transport.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport.c 2011-07-14 15:52:52 UTC
(rev 15961)
+++ gnunet/src/transport/gnunet-service-transport.c 2011-07-14 16:44:45 UTC
(rev 15962)
@@ -566,6 +566,11 @@
int public_key_valid;
/**
+ * Are we already in the process of disconnecting this neighbour?
+ */
+ int in_disconnect;
+
+ /**
* Performance data for the peer.
*/
struct GNUNET_TRANSPORT_ATS_Information *ats;
@@ -1614,21 +1619,16 @@
n = find_neighbour (&mq->neighbour_id);
if (mq->client != NULL)
transmit_send_ok (mq->client, n, target, result);
- if (n != NULL)
- {
- GNUNET_CONTAINER_DLL_remove (n->cont_head,
- n->cont_tail,
- mq);
- }
+ GNUNET_assert (n != NULL);
+ GNUNET_CONTAINER_DLL_remove (n->cont_head,
+ n->cont_tail,
+ mq);
GNUNET_free (mq);
- if (n != NULL)
- {
- if (result == GNUNET_OK)
- try_transmission_to_peer (n);
- else if (GNUNET_SCHEDULER_NO_TASK == n->retry_task)
- n->retry_task = GNUNET_SCHEDULER_add_now (&retry_transmission_task,
- n);
- }
+ if (result == GNUNET_OK)
+ try_transmission_to_peer (n);
+ else if (GNUNET_SCHEDULER_NO_TASK == n->retry_task)
+ n->retry_task = GNUNET_SCHEDULER_add_now (&retry_transmission_task,
+ n);
}
@@ -4853,6 +4853,8 @@
struct ForeignAddressList *peer_addresses;
struct ForeignAddressList *peer_pos;
+ if (GNUNET_YES == n->in_disconnect)
+ return;
if (GNUNET_YES == check)
{
rpos = n->plugins;
@@ -4861,7 +4863,7 @@
peer_addresses = rpos->addresses;
while (peer_addresses != NULL)
{
- // Do not disconnect if: an address is connected or an inbound
address exists
+ /* Do not disconnect if: an address is connected or an inbound
address exists */
if ((GNUNET_YES == peer_addresses->connected) ||
(peer_addresses->addrlen == 0))
{
#if DEBUG_TRANSPORT
@@ -4884,21 +4886,8 @@
"Disconnecting from `%4s'\n",
GNUNET_i2s (&n->id));
#endif
+ n->in_disconnect = GNUNET_YES; /* prevent recursive entry */
- /* remove n from neighbours list */
- nprev = NULL;
- npos = neighbours;
- while ((npos != NULL) && (npos != n))
- {
- nprev = npos;
- npos = npos->next;
- }
- GNUNET_assert (npos != NULL);
- if (nprev == NULL)
- neighbours = n->next;
- else
- nprev->next = n->next;
-
/* notify all clients about disconnect */
if (GNUNET_YES == n->received_pong)
notify_clients_disconnect (&n->id);
@@ -4989,6 +4978,21 @@
GNUNET_NO);
n->piter = NULL;
}
+
+ /* remove n from neighbours list */
+ nprev = NULL;
+ npos = neighbours;
+ while ((npos != NULL) && (npos != n))
+ {
+ nprev = npos;
+ npos = npos->next;
+ }
+ GNUNET_assert (npos != NULL);
+ if (nprev == NULL)
+ neighbours = n->next;
+ else
+ nprev->next = n->next;
+
/* finally, free n itself */
GNUNET_STATISTICS_update (stats,
gettext_noop ("# active neighbours"),
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r15962 - gnunet/src/transport,
gnunet <=