gnunet-svn
[Top][All Lists]
Advanced

[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"),




reply via email to

[Prev in Thread] Current Thread [Next in Thread]