struct MeshTunnelDelayed *next;
struct MeshTunnelDelayed *prev;
+ /**
+ * Tunnel.
+ */
+ struct MeshTunnel3 *t;
+
/**
* Channel.
*/
*/
struct MeshConnectionQueue *q;
+ /**
+ * Handle in case message hasn't been given to a connection yet.
+ */
+ struct MeshTunnelDelayed *tq;
+
/**
* Continuation to call once sent.
*/
}
+
+/**
+ * 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.
*
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",
}
-
-
/**
* Cache a message to be sent once tunnel is online.
*
* @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)
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;
}
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);
+ }
}
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));