From 94112b38d0c9fe7b9f653720e7a18972526fb46c Mon Sep 17 00:00:00 2001 From: Bart Polot Date: Mon, 9 Dec 2013 19:13:00 +0000 Subject: [PATCH] - fix handle for tunnel queueing during KX --- src/mesh/gnunet-service-mesh_channel.c | 3 ++ src/mesh/gnunet-service-mesh_tunnel.c | 58 ++++++++++++++++++++------ 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/mesh/gnunet-service-mesh_channel.c b/src/mesh/gnunet-service-mesh_channel.c index ee8597773..a385fdca2 100644 --- a/src/mesh/gnunet-service-mesh_channel.c +++ b/src/mesh/gnunet-service-mesh_channel.c @@ -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); diff --git a/src/mesh/gnunet-service-mesh_tunnel.c b/src/mesh/gnunet-service-mesh_tunnel.c index 4cd1f4713..f03607409 100644 --- a/src/mesh/gnunet-service-mesh_tunnel.c +++ b/src/mesh/gnunet-service-mesh_tunnel.c @@ -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)); -- 2.25.1