- fix handle for tunnel queueing during KX
authorBart Polot <bart@net.in.tum.de>
Mon, 9 Dec 2013 19:13:00 +0000 (19:13 +0000)
committerBart Polot <bart@net.in.tum.de>
Mon, 9 Dec 2013 19:13:00 +0000 (19:13 +0000)
src/mesh/gnunet-service-mesh_channel.c
src/mesh/gnunet-service-mesh_tunnel.c

index ee85977732d9282855e5e2b0660bd896880ce420..a385fdca2147f788dbe4a5393b54801a692a245a 100644 (file)
@@ -1285,6 +1285,9 @@ GMCH_destroy (struct MeshChannel *ch)
 
   if (NULL == ch)
     return;
+  if (2 == ch->destroy)
+    return; /* recursive call */
+  ch->destroy = 2;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying channel %s:%u\n",
               GMT_2s (ch->t), ch->gid);
index 4cd1f4713a924d8b0ba1e7085674c2bf2a8497a5..f03607409ec199a9c4f675583630ba7c1139ffd5 100644 (file)
@@ -157,6 +157,11 @@ struct MeshTunnelDelayed
   struct MeshTunnelDelayed *next;
   struct MeshTunnelDelayed *prev;
 
+  /**
+   * Tunnel.
+   */
+  struct MeshTunnel3 *t;
+
   /**
    * Channel.
    */
@@ -179,6 +184,11 @@ struct MeshTunnel3Queue
    */
   struct MeshConnectionQueue *q;
 
+  /**
+   * Handle in case message hasn't been given to a connection yet.
+   */
+  struct MeshTunnelDelayed *tq;
+
   /**
    * Continuation to call once sent.
    */
@@ -597,6 +607,21 @@ tunnel_get_connection (struct MeshTunnel3 *t)
 }
 
 
+
+/**
+ * Delete a queued message: most probably channel was destroyed before the
+ * tunnel's key exchange had a chance to finish.
+ *
+ * @param tq Queue handle.
+ */
+static void
+unqueue_data (struct MeshTunnelDelayed *tq)
+{
+  GNUNET_CONTAINER_DLL_remove (tq->t->tq_head, tq->t->tq_tail, tq);
+  GNUNET_free (tq);
+}
+
+
 /**
  * Send all cached messages that we can, tunnel is online.
  *
@@ -634,12 +659,10 @@ send_queued_data (struct MeshTunnel3 *t)
     LOG (GNUNET_ERROR_TYPE_DEBUG, " data on channel %s\n", GMCH_2s (tq->ch));
     next = tq->next;
     room--;
-    GNUNET_CONTAINER_DLL_remove (t->tq_head, t->tq_tail, tq);
     GMCH_send_prebuilt_message ((struct GNUNET_MessageHeader *) &tq[1],
                                 tq->ch, GMCH_is_origin (tq->ch, GNUNET_YES),
                                 NULL);
-
-    GNUNET_free (tq);
+    unqueue_data (tq);
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "GMT_send_queued_data end\n",
@@ -647,8 +670,6 @@ send_queued_data (struct MeshTunnel3 *t)
 }
 
 
-
-
 /**
  * Cache a message to be sent once tunnel is online.
  *
@@ -656,7 +677,7 @@ send_queued_data (struct MeshTunnel3 *t)
  * @param ch Channel the message is about.
  * @param msg Message itself (copy will be made).
  */
-static void
+static struct MeshTunnelDelayed *
 queue_data (struct MeshTunnel3 *t,
             struct MeshChannel *ch,
             const struct GNUNET_MessageHeader *msg)
@@ -669,14 +690,16 @@ queue_data (struct MeshTunnel3 *t,
   if (GNUNET_YES == is_ready (t))
   {
     GNUNET_break (0);
-    return;
+    return NULL;
   }
 
   tq = GNUNET_malloc (sizeof (struct MeshTunnelDelayed) + size);
 
   tq->ch = ch;
+  tq->t = t;
   memcpy (&tq[1], msg, size);
   GNUNET_CONTAINER_DLL_insert_tail (t->tq_head, t->tq_tail, tq);
+  return tq;
 }
 
 
@@ -2157,8 +2180,19 @@ message_sent (void *cls,
 void
 GMT_cancel (struct MeshTunnel3Queue *q)
 {
-  GMC_cancel (q->q);
-  /* message_sent() will be called and free q */
+  if (NULL != q->q)
+  {
+    GMC_cancel (q->q);
+    /* message_sent() will be called and free q */
+  }
+  else if (NULL != q->tq)
+  {
+    unqueue_data (q->tq);
+  }
+  else
+  {
+    GNUNET_break (0);
+  }
 }
 
 
@@ -2195,9 +2229,9 @@ GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
 
   if (GNUNET_NO == is_ready (t))
   {
-    queue_data (t, ch, message);
-    /* FIXME */
-    return NULL;
+    q = GNUNET_new (struct MeshTunnel3Queue);
+    q->tq = queue_data (t, ch, message);
+    return q;
   }
 
   GNUNET_assert (GNUNET_NO == GMT_is_loopback (t));