static int
is_ready (struct MeshTunnel3 *t)
{
- return (MESH_TUNNEL3_READY == t->cstate
- && MESH_TUNNEL3_KEY_OK == t->estate)
- || GMT_is_loopback (t);
+ int ready;
+
+ GMT_debug (t);
+ ready = (MESH_TUNNEL3_READY == t->cstate && MESH_TUNNEL3_KEY_OK == t->estate);
+ ready = ready || GMT_is_loopback (t);
+ return ready;
}
size_t size, uint32_t iv)
{
struct GNUNET_CRYPTO_SymmetricInitializationVector siv;
+ struct GNUNET_CRYPTO_SymmetricSessionKey *key;
+
+ if (t->estate == MESH_TUNNEL3_KEY_OK || t->estate == MESH_TUNNEL3_KEY_PING)
+ {
+ key = &t->d_key;
+ }
+ else if (NULL != t->kx_ctx)
+ {
+ key = &t->kx_ctx->d_key_old;
+ }
+ else
+ {
+ GNUNET_STATISTICS_update (stats, "# non decryptable data", 1, GNUNET_NO);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "WARNING got data on %s without a valid key\n",
+ GMT_2s (t));
+ GMT_debug (t);
+ return 0;
+ }
- GNUNET_CRYPTO_symmetric_derive_iv (&siv, &t->d_key, &iv, sizeof (uint32_t), NULL);
- return GNUNET_CRYPTO_symmetric_decrypt (src, size, &t->d_key, &siv, dst);
+ GNUNET_CRYPTO_symmetric_derive_iv (&siv, key, &iv, sizeof (uint32_t), NULL);
+ return GNUNET_CRYPTO_symmetric_decrypt (src, size, key, &siv, dst);
}
* Delete a queued message: either was sent or the channel was destroyed
* before the tunnel's key exchange had a chance to finish.
*
- * @param tq Queue handle.
+ * @param tqd Delayed queue handle.
*/
static void
-unqueue_data (struct MeshTunnelDelayed *tq)
+unqueue_data (struct MeshTunnelDelayed *tqd)
{
- GNUNET_CONTAINER_DLL_remove (tq->t->tq_head, tq->t->tq_tail, tq);
- GNUNET_free (tq);
+ GNUNET_CONTAINER_DLL_remove (tqd->t->tq_head, tqd->t->tq_tail, tqd);
+ GNUNET_free (tqd);
}
return;
}
+ if (GNUNET_NO != t->destroy)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " being destroyed, why bother\n");
+ return;
+ }
+
/* Must have a connection. */
if (NULL == t->connection_head)
{
}
+/**
+ * Notify remote peer that we don't know a channel he is talking about,
+ * probably CHANNEL_DESTROY was missed.
+ *
+ * @param t Tunnel on which to notify.
+ * @param gid ID of the channel.
+ */
+static void
+send_channel_destroy (struct MeshTunnel3 *t, unsigned int gid)
+{
+ struct GNUNET_MESH_ChannelManage msg;
+
+ msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY);
+ msg.header.size = htons (sizeof (msg));
+ msg.chid = htonl (gid);
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "WARNING destroying unknown channel %u on tunnel %s\n",
+ gid, GMT_2s (t));
+ send_prebuilt_message (&msg.header, t, GNUNET_YES, NULL, NULL, NULL);
+}
+
+
/**
* Demultiplex data per channel and call appropriate channel handler.
*
{
GNUNET_STATISTICS_update (stats, "# data on unknown channel",
1, GNUNET_NO);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel %X unknown\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel 0x%X unknown\n",
ntohl (msg->chid));
+ send_channel_destroy (t, ntohl (msg->chid));
return;
}
t_decrypt (t, &res.target, &msg->target, ping_encryption_size (), msg->iv);
if (0 != memcmp (&my_full_id, &res.target, sizeof (my_full_id)))
{
- GNUNET_break_op (0);
+ GNUNET_STATISTICS_update (stats, "# malformed PINGs", 1, GNUNET_NO);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " WARNING malformed PING\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, " e got %u\n", msg->nonce);
LOG (GNUNET_ERROR_TYPE_DEBUG, " e towards %s\n", GNUNET_i2s (&msg->target));
LOG (GNUNET_ERROR_TYPE_DEBUG, " got %u\n", res.nonce);
LOG (GNUNET_ERROR_TYPE_DEBUG,
"end-to-end message not known (%u)\n",
ntohs (msgh->type));
+ GMT_debug (t);
}
}
struct MeshTConnection *iter;
unsigned int count;
- for (count = 0, iter = t->connection_head;
- NULL != iter;
- iter = iter->next, count++);
+ for (count = 0, iter = t->connection_head; NULL != iter; iter = iter->next)
+ if (MESH_CONNECTION_DESTROYED != GMC_get_state (iter->c))
+ count++;
return count;
}
else if (NULL != q->tqd)
{
unqueue_data (q->tqd);
+ q->tqd = NULL;
+ if (NULL != q->cont)
+ q->cont (q->cont_cls, NULL, q, 0, 0);
+ GNUNET_free (q);
}
else
{