- moved timeout handling responsibility from for nat tests from caller to the library
[oweals/gnunet.git] / src / cadet / gnunet-service-cadet_tunnel.c
index 15883b43eb10c350061b6654413c966591e03e48..6c4d949e3cf9e6f7c2f0661328cd91174daa2b55 100644 (file)
@@ -86,6 +86,12 @@ struct CadetTConnection
  */
 struct CadetTunnelKXCtx
 {
+  /**
+   * Encryption ("our") old key, for encrypting traffic sent by us
+   * end before the key exchange is finished or times out.
+   */
+  struct GNUNET_CRYPTO_SymmetricSessionKey e_key_old;
+
   /**
    * Decryption ("their") old key, for decrypting traffic sent by the
    * other end before the key exchange started.
@@ -96,12 +102,23 @@ struct CadetTunnelKXCtx
    * Challenge to send in a ping and expect in the pong.
    */
   uint32_t challenge;
+
+  /**
+   * When the rekey started. One minute after this the new key will be used.
+   */
+  struct GNUNET_TIME_Absolute rekey_start_time;
+
+  /**
+   * Task for delayed destruction of the Key eXchange context, to allow delayed
+   * messages with the old key to be decrypted successfully.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier finish_task;
 };
 
 /**
  * Struct containing all information regarding a tunnel to a peer.
  */
-struct CadetTunnel3
+struct CadetTunnel
 {
     /**
      * Endpoint of the tunnel.
@@ -111,18 +128,24 @@ struct CadetTunnel3
     /**
      * State of the tunnel connectivity.
      */
-  enum CadetTunnel3CState cstate;
+  enum CadetTunnelCState cstate;
 
   /**
    * State of the tunnel encryption.
    */
-  enum CadetTunnel3EState estate;
+  enum CadetTunnelEState estate;
 
   /**
    * Key eXchange context.
    */
   struct CadetTunnelKXCtx *kx_ctx;
 
+  /**
+   * Peer's ephemeral key, to recreate @c e_key and @c d_key when own ephemeral
+   * key changes.
+   */
+  struct GNUNET_CRYPTO_EcdhePublicKey peers_ephemeral_key;
+
   /**
    * Encryption ("our") key.
    */
@@ -187,12 +210,12 @@ struct CadetTunnelDelayed
   /**
    * Tunnel.
    */
-  struct CadetTunnel3 *t;
+  struct CadetTunnel *t;
 
   /**
    * Tunnel queue given to the channel to cancel request. Update on send_queued.
    */
-  struct CadetTunnel3Queue *tq;
+  struct CadetTunnelQueue *tq;
 
   /**
    * Message to send.
@@ -204,7 +227,7 @@ struct CadetTunnelDelayed
 /**
  * Handle for messages queued but not yet sent.
  */
-struct CadetTunnel3Queue
+struct CadetTunnelQueue
 {
   /**
    * Connection queue handle, to cancel if necessary.
@@ -219,7 +242,7 @@ struct CadetTunnel3Queue
   /**
    * Continuation to call once sent.
    */
-  GMT_sent cont;
+  GCT_sent cont;
 
   /**
    * Closure for @c cont.
@@ -302,7 +325,7 @@ static struct GNUNET_TIME_Relative rekey_period;
  * @return String representation.
  */
 static const char *
-cstate2s (enum CadetTunnel3CState cs)
+cstate2s (enum CadetTunnelCState cs)
 {
   static char buf[128];
 
@@ -333,7 +356,7 @@ cstate2s (enum CadetTunnel3CState cs)
  * @return String representation.
  */
 static const char *
-estate2s (enum CadetTunnel3EState es)
+estate2s (enum CadetTunnelEState es)
 {
   static char buf[128];
 
@@ -366,13 +389,13 @@ estate2s (enum CadetTunnel3EState es)
  * @return #GNUNET_YES if ready, #GNUNET_NO otherwise
  */
 static int
-is_ready (struct CadetTunnel3 *t)
+is_ready (struct CadetTunnel *t)
 {
   int ready;
 
-  GMT_debug (t);
+  GCT_debug (t);
   ready = (CADET_TUNNEL3_READY == t->cstate && CADET_TUNNEL3_KEY_OK == t->estate);
-  ready = ready || GMT_is_loopback (t);
+  ready = ready || GCT_is_loopback (t);
   return ready;
 }
 
@@ -418,9 +441,9 @@ get_channel_buffer (const struct CadetTChannel *tch)
   int fwd;
 
   /* If channel is outgoing, is origin in the FWD direction and fwd is YES */
-  fwd = GMCH_is_origin (tch->ch, GNUNET_YES);
+  fwd = GCCH_is_origin (tch->ch, GNUNET_YES);
 
-  return GMCH_get_buffer (tch->ch, fwd);
+  return GCCH_get_buffer (tch->ch, fwd);
 }
 
 
@@ -437,9 +460,9 @@ get_channel_allowed (const struct CadetTChannel *tch)
   int fwd;
 
   /* If channel is outgoing, is origin in the FWD direction and fwd is YES */
-  fwd = GMCH_is_origin (tch->ch, GNUNET_YES);
+  fwd = GCCH_is_origin (tch->ch, GNUNET_YES);
 
-  return GMCH_get_allowed (tch->ch, fwd);
+  return GCCH_get_allowed (tch->ch, fwd);
 }
 
 
@@ -456,9 +479,9 @@ get_connection_buffer (const struct CadetTConnection *tc)
   int fwd;
 
   /* If connection is outgoing, is origin in the FWD direction and fwd is YES */
-  fwd = GMC_is_origin (tc->c, GNUNET_YES);
+  fwd = GCC_is_origin (tc->c, GNUNET_YES);
 
-  return GMC_get_buffer (tc->c, fwd);
+  return GCC_get_buffer (tc->c, fwd);
 }
 
 
@@ -475,9 +498,9 @@ get_connection_allowed (const struct CadetTConnection *tc)
   int fwd;
 
   /* If connection is outgoing, is origin in the FWD direction and fwd is YES */
-  fwd = GMC_is_origin (tc->c, GNUNET_YES);
+  fwd = GCC_is_origin (tc->c, GNUNET_YES);
 
-  return GMC_get_allowed (tc->c, fwd);
+  return GCC_get_allowed (tc->c, fwd);
 }
 
 
@@ -490,7 +513,7 @@ get_connection_allowed (const struct CadetTConnection *tc)
  * @return GNUNET_OK if message is fine, GNUNET_SYSERR otherwise.
  */
 int
-check_ephemeral (struct CadetTunnel3 *t,
+check_ephemeral (struct CadetTunnel *t,
                  const struct GNUNET_CADET_KX_Ephemeral *msg)
 {
   /* Check message size */
@@ -503,7 +526,7 @@ check_ephemeral (struct CadetTunnel3 *t,
 
   /* Check origin */
   if (0 != memcmp (&msg->origin_identity,
-                   GMP_get_id (t->peer),
+                   GCP_get_id (t->peer),
                    sizeof (struct GNUNET_PeerIdentity)))
     return GNUNET_SYSERR;
 
@@ -519,6 +542,36 @@ check_ephemeral (struct CadetTunnel3 *t,
 }
 
 
+/**
+ * Calculate HMAC.
+ *
+ * @param t Tunnel to get keys from.
+ * @param plaintext Content to HMAC.
+ * @param size Size of @c plaintext.
+ * @param iv Initialization vector for the message.
+ * @param outgoing Is this an outgoing message that we encrypted?
+ * @param hmac Destination to store the HMAC.
+ */
+static void
+t_hmac (struct CadetTunnel *t, const void *plaintext, size_t size, uint32_t iv,
+        int outgoing, struct GNUNET_CADET_Hash *hmac)
+{
+  struct GNUNET_CRYPTO_AuthKey auth_key;
+  static const char ctx[] = "cadet authentication key";
+  struct GNUNET_CRYPTO_SymmetricSessionKey *key;
+  struct GNUNET_HashCode hash;
+
+  key = outgoing ? &t->e_key : &t->d_key;
+  GNUNET_CRYPTO_hmac_derive_key (&auth_key, key,
+                                 &iv, sizeof (iv),
+                                 key, sizeof (*key),
+                                 ctx, sizeof (ctx),
+                                 NULL);
+  GNUNET_CRYPTO_hmac (&auth_key, plaintext, size, &hash);
+  memcpy (hmac, &hash, sizeof (*hmac));
+}
+
+
 /**
  * Encrypt data with the tunnel key.
  *
@@ -527,19 +580,48 @@ check_ephemeral (struct CadetTunnel3 *t,
  * @param src Source of the plaintext. Can overlap with @c dst.
  * @param size Size of the plaintext.
  * @param iv Initialization Vector to use.
+ * @param force_newest_key Force the use of the newest key, otherwise
+ *                         CADET will use the old key when allowed.
+ *                         This can happen in the case when a KX is going on
+ *                         and the old one hasn't expired.
  */
 static int
-t_encrypt (struct CadetTunnel3 *t,
-           void *dst, const void *src,
-           size_t size, uint32_t iv)
+t_encrypt (struct CadetTunnel *t, void *dst, const void *src,
+           size_t size, uint32_t iv, int force_newest_key)
 {
   struct GNUNET_CRYPTO_SymmetricInitializationVector siv;
+  struct GNUNET_CRYPTO_SymmetricSessionKey *e_key;
   size_t out_size;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  t_encrypt start\n");
-  GNUNET_CRYPTO_symmetric_derive_iv (&siv, &t->e_key, &iv, sizeof (iv), NULL);
+  if (GNUNET_NO == force_newest_key
+      && NULL != t->kx_ctx
+      && GNUNET_SCHEDULER_NO_TASK == t->kx_ctx->finish_task)
+  {
+    struct GNUNET_TIME_Relative age;
+
+    age = GNUNET_TIME_absolute_get_duration (t->kx_ctx->rekey_start_time);
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "  key exchange in progress, started %s ago\n",
+         GNUNET_STRINGS_relative_time_to_string (age, GNUNET_YES));
+    if (age.rel_value_us < GNUNET_TIME_UNIT_MINUTES.rel_value_us)
+    {
+      LOG (GNUNET_ERROR_TYPE_DEBUG, "  using old key\n");
+      e_key = &t->kx_ctx->e_key_old;
+    }
+    else
+    {
+      LOG (GNUNET_ERROR_TYPE_DEBUG, "  using new key\n");
+      e_key = &t->e_key;
+    }
+  }
+  else
+  {
+    e_key = &t->e_key;
+  }
+  GNUNET_CRYPTO_symmetric_derive_iv (&siv, e_key, &iv, sizeof (iv), NULL);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  t_encrypt IV derived\n");
-  out_size = GNUNET_CRYPTO_symmetric_encrypt (src, size, &t->e_key, &siv, dst);
+  out_size = GNUNET_CRYPTO_symmetric_encrypt (src, size, e_key, &siv, dst);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  t_encrypt end\n");
 
   return out_size;
@@ -547,20 +629,49 @@ t_encrypt (struct CadetTunnel3 *t,
 
 
 /**
- * Decrypt data with the tunnel key.
+ * Decrypt and verify data with the appropriate tunnel key.
+ *
+ * @param key Key to use.
+ * @param dst Destination for the plaintext.
+ * @param src Source of the encrypted data. Can overlap with @c dst.
+ * @param size Size of the encrypted data.
+ * @param iv Initialization Vector to use.
+ *
+ * @return Size of the decrypted data, -1 if an error was encountered.
+ */
+static int
+decrypt (const struct GNUNET_CRYPTO_SymmetricSessionKey *key,
+         void *dst, const void *src, size_t size, uint32_t iv)
+{
+  struct GNUNET_CRYPTO_SymmetricInitializationVector siv;
+  size_t out_size;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "  decrypt start\n");
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "  decrypt iv\n");
+  GNUNET_CRYPTO_symmetric_derive_iv (&siv, key, &iv, sizeof (iv), NULL);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "  decrypt iv done\n");
+  out_size = GNUNET_CRYPTO_symmetric_decrypt (src, size, key, &siv, dst);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "  decrypt end\n");
+
+  return out_size;
+}
+
+
+/**
+ * Decrypt and verify data with the most recent tunnel key.
  *
  * @param t Tunnel whose key to use.
  * @param dst Destination for the plaintext.
  * @param src Source of the encrypted data. Can overlap with @c dst.
  * @param size Size of the encrypted data.
  * @param iv Initialization Vector to use.
+ *
+ * @return Size of the decrypted data, -1 if an error was encountered.
  */
 static int
-t_decrypt (struct CadetTunnel3 *t,
-           void *dst, const void *src,
+t_decrypt (struct CadetTunnel *t, void *dst, const void *src,
            size_t size, uint32_t iv)
 {
-  struct GNUNET_CRYPTO_SymmetricInitializationVector siv;
   struct GNUNET_CRYPTO_SymmetricSessionKey *key;
   size_t out_size;
 
@@ -569,30 +680,77 @@ t_decrypt (struct CadetTunnel3 *t,
   {
     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;
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "got data on %s without a valid key\n",
+         GCT_2s (t));
+    GCT_debug (t);
+    return -1;
   }
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "  t_decrypt iv\n");
-  GNUNET_CRYPTO_symmetric_derive_iv (&siv, key, &iv, sizeof (iv), NULL);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "  t_decrypt iv done\n");
-  out_size = GNUNET_CRYPTO_symmetric_decrypt (src, size, key, &siv, dst);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "  t_decrypt end\n");
+  out_size = decrypt (key, dst, src, size, iv);
 
   return out_size;
 }
 
 
+/**
+ * Decrypt and verify data with the appropriate tunnel key and verify that the
+ * data has not been altered since it was sent by the remote peer.
+ *
+ * @param t Tunnel whose key to use.
+ * @param dst Destination for the plaintext.
+ * @param src Source of the encrypted data. Can overlap with @c dst.
+ * @param size Size of the encrypted data.
+ * @param iv Initialization Vector to use.
+ * @param msg_hmac HMAC of the message, cannot be NULL.
+ *
+ * @return Size of the decrypted data, -1 if an error was encountered.
+ */
+static int
+t_decrypt_and_validate (struct CadetTunnel *t,
+                        void *dst, const void *src,
+                        size_t size, uint32_t iv,
+                        const struct GNUNET_CADET_Hash *msg_hmac)
+{
+  struct GNUNET_CRYPTO_SymmetricSessionKey *key;
+  struct GNUNET_CADET_Hash hmac;
+  int decrypted_size;
+
+  /* Try primary (newest) key */
+  key = &t->d_key;
+  decrypted_size = decrypt (key, dst, src, size, iv);
+  t_hmac (t, src, size, iv, GNUNET_NO, &hmac);
+  if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac)))
+    return decrypted_size;
+
+  /* If no key exchange is going on, we just failed */
+  if (NULL == t->kx_ctx)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Failed checksum validation on tunnel %s with no KX\n",
+                GCT_2s (t));
+    GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO);
+    return -1;
+  }
+
+  /* Try secondary (from previous KX period) key */
+  key = &t->kx_ctx->d_key_old;
+  decrypted_size = decrypt (key, dst, src, size, iv);
+  t_hmac (t, src, size, iv, GNUNET_NO, &hmac);
+  if (0 == memcmp (msg_hmac, &hmac, sizeof (hmac)))
+    return decrypted_size;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+              "Failed checksum validation on tunnel %s with KX\n",
+              GCT_2s (t));
+  GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO);
+  return -1;
+}
+
+
 /**
  * Create key material by doing ECDH on the local and remote ephemeral keys.
  *
@@ -612,6 +770,7 @@ derive_key_material (struct GNUNET_HashCode *key_material,
   }
 }
 
+
 /**
  * Create a symmetic key from the identities of both ends and the key material
  * from ECDH.
@@ -637,6 +796,23 @@ derive_symmertic (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
                      NULL);
 }
 
+
+/**
+ * Derive the tunnel's keys using our own and the peer's ephemeral keys.
+ *
+ * @param t Tunnel for which to create the keys.
+ */
+static void
+create_keys (struct CadetTunnel *t)
+{
+  struct GNUNET_HashCode km;
+
+  derive_key_material (&km, &t->peers_ephemeral_key);
+  derive_symmertic (&t->e_key, &my_full_id, GCP_get_id (t->peer), &km);
+  derive_symmertic (&t->d_key, GCP_get_id (t->peer), &my_full_id, &km);
+}
+
+
 /**
  * Pick a connection on which send the next data message.
  *
@@ -645,23 +821,23 @@ derive_symmertic (struct GNUNET_CRYPTO_SymmetricSessionKey *key,
  * @return The connection on which to send the next message.
  */
 static struct CadetConnection *
-tunnel_get_connection (struct CadetTunnel3 *t)
+tunnel_get_connection (struct CadetTunnel *t)
 {
   struct CadetTConnection *iter;
   struct CadetConnection *best;
   unsigned int qn;
   unsigned int lowest_q;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel_get_connection %s\n", GCT_2s (t));
   best = NULL;
   lowest_q = UINT_MAX;
   for (iter = t->connection_head; NULL != iter; iter = iter->next)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  connection %s: %u\n",
-         GMC_2s (iter->c), GMC_get_state (iter->c));
-    if (CADET_CONNECTION_READY == GMC_get_state (iter->c))
+         GCC_2s (iter->c), GCC_get_state (iter->c));
+    if (CADET_CONNECTION_READY == GCC_get_state (iter->c))
     {
-      qn = GMC_get_qn (iter->c, GMC_is_origin (iter->c, GNUNET_YES));
+      qn = GCC_get_qn (iter->c, GCC_is_origin (iter->c, GNUNET_YES));
       LOG (GNUNET_ERROR_TYPE_DEBUG, "    q_n %u, \n", qn);
       if (qn < lowest_q)
       {
@@ -670,7 +846,7 @@ tunnel_get_connection (struct CadetTunnel3 *t)
       }
     }
   }
-  LOG (GNUNET_ERROR_TYPE_DEBUG, " selected: connection %s\n", GMC_2s (best));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, " selected: connection %s\n", GCC_2s (best));
   return best;
 }
 
@@ -693,13 +869,13 @@ tun_message_sent (void *cls,
               struct CadetConnectionQueue *q,
               uint16_t type, int fwd, size_t size)
 {
-  struct CadetTunnel3Queue *qt = cls;
-  struct CadetTunnel3 *t;
+  struct CadetTunnelQueue *qt = cls;
+  struct CadetTunnel *t;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "tun_message_sent\n");
 
   GNUNET_assert (NULL != qt->cont);
-  t = NULL == c ? NULL : GMC_get_tunnel (c);
+  t = NULL == c ? NULL : GCC_get_tunnel (c);
   qt->cont (qt->cont_cls, t, qt, type, size);
   GNUNET_free (qt);
 }
@@ -726,12 +902,12 @@ unqueue_data (struct CadetTunnelDelayed *tqd)
  * @param msg Message itself (copy will be made).
  */
 static struct CadetTunnelDelayed *
-queue_data (struct CadetTunnel3 *t, const struct GNUNET_MessageHeader *msg)
+queue_data (struct CadetTunnel *t, const struct GNUNET_MessageHeader *msg)
 {
   struct CadetTunnelDelayed *tqd;
   uint16_t size = ntohs (msg->size);
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "queue data on Tunnel %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "queue data on Tunnel %s\n", GCT_2s (t));
 
   if (GNUNET_YES == is_ready (t))
   {
@@ -748,36 +924,6 @@ queue_data (struct CadetTunnel3 *t, const struct GNUNET_MessageHeader *msg)
 }
 
 
-/**
- * Calculate HMAC.
- *
- * @param t Tunnel to get keys from.
- * @param plaintext Content to HMAC.
- * @param size Size of @c plaintext.
- * @param iv Initialization vector for the message.
- * @param outgoing Is this an outgoing message that we encrypted?
- * @param hmac Destination to store the HMAC.
- */
-static void
-t_hmac (struct CadetTunnel3 *t, const void *plaintext, size_t size, uint32_t iv,
-        int outgoing, struct GNUNET_CADET_Hash *hmac)
-{
-  struct GNUNET_CRYPTO_AuthKey auth_key;
-  static const char ctx[] = "cadet authentication key";
-  struct GNUNET_CRYPTO_SymmetricSessionKey *key;
-  struct GNUNET_HashCode hash;
-
-  key = outgoing ? &t->e_key : &t->d_key;
-  GNUNET_CRYPTO_hmac_derive_key (&auth_key, key,
-                                 &iv, sizeof (iv),
-                                 key, sizeof (*key),
-                                 ctx, sizeof (ctx),
-                                 NULL);
-  GNUNET_CRYPTO_hmac (&auth_key, plaintext, size, &hash);
-  memcpy (hmac, &hash, sizeof (*hmac));
-}
-
-
 /**
  * Sends an already built message on a tunnel, encrypting it and
  * choosing the best connection.
@@ -794,13 +940,13 @@ t_hmac (struct CadetTunnel3 *t, const void *plaintext, size_t size, uint32_t iv,
  *
  * @return Handle to cancel message. NULL if @c cont is NULL.
  */
-static struct CadetTunnel3Queue *
+static struct CadetTunnelQueue *
 send_prebuilt_message (const struct GNUNET_MessageHeader *message,
-                       struct CadetTunnel3 *t, struct CadetConnection *c,
-                       int force, GMT_sent cont, void *cont_cls,
-                       struct CadetTunnel3Queue *existing_q)
+                       struct CadetTunnel *t, struct CadetConnection *c,
+                       int force, GCT_sent cont, void *cont_cls,
+                       struct CadetTunnelQueue *existing_q)
 {
-  struct CadetTunnel3Queue *tq;
+  struct CadetTunnelQueue *tq;
   struct GNUNET_CADET_Encrypted *msg;
   size_t size = ntohs (message->size);
   char cbuf[sizeof (struct GNUNET_CADET_Encrypted) + size];
@@ -809,7 +955,7 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message,
   uint16_t type;
   int fwd;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT Send on Tunnel %s\n", GCT_2s (t));
 
   if (GNUNET_NO == is_ready (t))
   {
@@ -821,7 +967,7 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message,
     tqd = queue_data (t, message);
     if (NULL == cont)
       return NULL;
-    tq = GNUNET_new (struct CadetTunnel3Queue);
+    tq = GNUNET_new (struct CadetTunnelQueue);
     tq->tqd = tqd;
     tqd->tq = tq;
     tq->cont = cont;
@@ -829,13 +975,13 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message,
     return tq;
   }
 
-  GNUNET_assert (GNUNET_NO == GMT_is_loopback (t));
+  GNUNET_assert (GNUNET_NO == GCT_is_loopback (t));
 
   iv = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
   msg = (struct GNUNET_CADET_Encrypted *) cbuf;
   msg->header.type = htons (GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED);
   msg->iv = iv;
-  GNUNET_assert (t_encrypt (t, &msg[1], message, size, iv) == size);
+  GNUNET_assert (t_encrypt (t, &msg[1], message, size, iv, GNUNET_NO) == size);
   t_hmac (t, &msg[1], size, iv, GNUNET_YES, &msg->hmac);
   msg->header.size = htons (sizeof (struct GNUNET_CADET_Encrypted) + size);
 
@@ -847,7 +993,7 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message,
         || CADET_TUNNEL3_SEARCHING != t->cstate)
     {
       GNUNET_break (0);
-      GMT_debug (t);
+      GCT_debug (t);
     }
     return NULL;
   }
@@ -868,33 +1014,33 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message,
     case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
     case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_ACK:
     case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_NACK:
-      msg->cid = *GMC_get_id (c);
+      msg->cid = *GCC_get_id (c);
       msg->ttl = htonl (default_ttl);
       break;
     default:
       GNUNET_break (0);
   }
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "type %s\n", GM_m2s (type));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "type %s\n", GC_m2s (type));
 
-  fwd = GMC_is_origin (c, GNUNET_YES);
+  fwd = GCC_is_origin (c, GNUNET_YES);
 
   if (NULL == cont)
   {
     GNUNET_break (NULL ==
-                  GMC_send_prebuilt_message (&msg->header, type, mid,
+                  GCC_send_prebuilt_message (&msg->header, type, mid,
                                              c, fwd, force, NULL, NULL));
     return NULL;
   }
   if (NULL == existing_q)
   {
-    tq = GNUNET_new (struct CadetTunnel3Queue); /* FIXME valgrind: leak*/
+    tq = GNUNET_new (struct CadetTunnelQueue); /* FIXME valgrind: leak*/
   }
   else
   {
     tq = existing_q;
     tq->tqd = NULL;
   }
-  tq->cq = GMC_send_prebuilt_message (&msg->header, type, mid, c, fwd, force,
+  tq->cq = GCC_send_prebuilt_message (&msg->header, type, mid, c, fwd, force,
                                       &tun_message_sent, tq);
   tq->cont = cont;
   tq->cont_cls = cont_cls;
@@ -909,17 +1055,17 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message,
  * @param t Tunnel that holds the messages. Cannot be loopback.
  */
 static void
-send_queued_data (struct CadetTunnel3 *t)
+send_queued_data (struct CadetTunnel *t)
 {
   struct CadetTunnelDelayed *tqd;
   struct CadetTunnelDelayed *next;
   unsigned int room;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "GMT_send_queued_data on tunnel %s\n",
-       GMT_2s (t));
+       "GCT_send_queued_data on tunnel %s\n",
+       GCT_2s (t));
 
-  if (GMT_is_loopback (t))
+  if (GCT_is_loopback (t))
   {
     GNUNET_break (0);
     return;
@@ -932,7 +1078,7 @@ send_queued_data (struct CadetTunnel3 *t)
     return;
   }
 
-  room = GMT_get_connections_buffer (t);
+  room = GCT_get_connections_buffer (t);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  buffer space: %u\n", room);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  tq head: %p\n", t->tq_head);
   for (tqd = t->tq_head; NULL != tqd && room > 0; tqd = next)
@@ -947,7 +1093,7 @@ send_queued_data (struct CadetTunnel3 *t)
                            tqd->tq);
     unqueue_data (tqd);
   }
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT_send_queued_data end\n", GMP_2s (t->peer));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "GCT_send_queued_data end\n", GCP_2s (t->peer));
 }
 
 
@@ -959,7 +1105,7 @@ send_queued_data (struct CadetTunnel3 *t)
  * @param message Message to send. Function modifies it.
  */
 static void
-send_kx (struct CadetTunnel3 *t,
+send_kx (struct CadetTunnel *t,
          const struct GNUNET_MessageHeader *message)
 {
   struct CadetConnection *c;
@@ -969,10 +1115,10 @@ send_kx (struct CadetTunnel3 *t,
   uint16_t type;
   int fwd;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT KX on Tunnel %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT KX on Tunnel %s\n", GCT_2s (t));
 
   /* Avoid loopback. */
-  if (GMT_is_loopback (t))
+  if (GCT_is_loopback (t))
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  loopback!\n");
     GNUNET_break (0);
@@ -988,7 +1134,7 @@ send_kx (struct CadetTunnel3 *t,
   if (NULL == t->connection_head)
   {
     GNUNET_break (CADET_TUNNEL3_SEARCHING == t->cstate);
-    GMT_debug (t);
+    GCT_debug (t);
     return;
   }
 
@@ -1000,7 +1146,7 @@ send_kx (struct CadetTunnel3 *t,
   {
     GNUNET_break (GNUNET_SCHEDULER_NO_TASK != t->destroy_task
                   || CADET_TUNNEL3_READY != t->cstate);
-    GMT_debug (t);
+    GCT_debug (t);
     return;
   }
   type = ntohs (message->type);
@@ -1013,13 +1159,13 @@ send_kx (struct CadetTunnel3 *t,
       break;
     default:
       LOG (GNUNET_ERROR_TYPE_DEBUG, "unkown type %s\n",
-           GM_m2s (type));
+           GC_m2s (type));
       GNUNET_break (0);
   }
 
-  fwd = GMC_is_origin (t->connection_head->c, GNUNET_YES);
+  fwd = GCC_is_origin (t->connection_head->c, GNUNET_YES);
   /* TODO save handle and cancel in case of a unneeded retransmission */
-  GMC_send_prebuilt_message (&msg->header, GNUNET_MESSAGE_TYPE_CADET_KX,
+  GCC_send_prebuilt_message (&msg->header, GNUNET_MESSAGE_TYPE_CADET_KX,
                              message->type, c, fwd, GNUNET_YES, NULL, NULL);
 }
 
@@ -1030,9 +1176,9 @@ send_kx (struct CadetTunnel3 *t,
  * @param t Tunnel on which to send the key.
  */
 static void
-send_ephemeral (struct CadetTunnel3 *t)
+send_ephemeral (struct CadetTunnel *t)
 {
-  LOG (GNUNET_ERROR_TYPE_INFO, "=> EPHM for %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_INFO, "===> EPHM for %s\n", GCT_2s (t));
 
   kx_msg.sender_status = htonl (t->estate);
   send_kx (t, &kx_msg.header);
@@ -1044,20 +1190,21 @@ send_ephemeral (struct CadetTunnel3 *t)
  * @param t Tunnel on which to send the ping.
  */
 static void
-send_ping (struct CadetTunnel3 *t)
+send_ping (struct CadetTunnel *t)
 {
   struct GNUNET_CADET_KX_Ping msg;
 
-  LOG (GNUNET_ERROR_TYPE_INFO, "=> PING for %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_INFO, "===> PING for %s\n", GCT_2s (t));
   msg.header.size = htons (sizeof (msg));
   msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_KX_PING);
   msg.iv = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
-  msg.target = *GMP_get_id (t->peer);
+  msg.target = *GCP_get_id (t->peer);
   msg.nonce = t->kx_ctx->challenge;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  sending %u\n", msg.nonce);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  towards %s\n", GNUNET_i2s (&msg.target));
-  t_encrypt (t, &msg.target, &msg.target, ping_encryption_size(), msg.iv);
+  t_encrypt (t, &msg.target, &msg.target,
+             ping_encryption_size(), msg.iv, GNUNET_YES);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  e sending %u\n", msg.nonce);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  e towards %s\n", GNUNET_i2s (&msg.target));
 
@@ -1067,22 +1214,23 @@ send_ping (struct CadetTunnel3 *t)
 
 /**
  * Send a pong message on a tunnel.
- *
+ *d_
  * @param t Tunnel on which to send the pong.
  * @param challenge Value sent in the ping that we have to send back.
  */
 static void
-send_pong (struct CadetTunnel3 *t, uint32_t challenge)
+send_pong (struct CadetTunnel *t, uint32_t challenge)
 {
   struct GNUNET_CADET_KX_Pong msg;
 
-  LOG (GNUNET_ERROR_TYPE_INFO, "=> PONG for %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_INFO, "===> PONG for %s\n", GCT_2s (t));
   msg.header.size = htons (sizeof (msg));
   msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_KX_PONG);
   msg.iv = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
   msg.nonce = challenge;
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  sending %u\n", msg.nonce);
-  t_encrypt (t, &msg.nonce, &msg.nonce, sizeof (msg.nonce), msg.iv);
+  t_encrypt (t, &msg.nonce, &msg.nonce,
+             sizeof (msg.nonce), msg.iv, GNUNET_YES);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  e sending %u\n", msg.nonce);
 
   send_kx (t, &msg.header);
@@ -1098,11 +1246,11 @@ send_pong (struct CadetTunnel3 *t, uint32_t challenge)
 static void
 rekey_tunnel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  struct CadetTunnel3 *t = cls;
+  struct CadetTunnel *t = cls;
 
   t->rekey_task = GNUNET_SCHEDULER_NO_TASK;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Re-key Tunnel %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Re-key Tunnel %s\n", GCT_2s (t));
   if (NULL != tc && 0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
     return;
 
@@ -1113,10 +1261,15 @@ rekey_tunnel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     t->kx_ctx->challenge =
         GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
     t->kx_ctx->d_key_old = t->d_key;
+    t->kx_ctx->e_key_old = t->e_key;
+    create_keys (t);
+    t->kx_ctx->rekey_start_time = GNUNET_TIME_absolute_get ();
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  new challenge for %s: %u\n",
-         GMT_2s (t), t->kx_ctx->challenge);
+         GCT_2s (t), t->kx_ctx->challenge);
   }
+
   send_ephemeral (t);
+
   switch (t->estate)
   {
     case CADET_TUNNEL3_KEY_UNINITIALIZED:
@@ -1133,6 +1286,7 @@ rekey_tunnel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       LOG (GNUNET_ERROR_TYPE_DEBUG, "Unexpected state %u\n", t->estate);
   }
 
+  // FIXME exponential backoff
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  next call in %s\n",
        GNUNET_STRINGS_relative_time_to_string (REKEY_WAIT, GNUNET_YES));
   t->rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_WAIT, &rekey_tunnel, t);
@@ -1140,7 +1294,11 @@ rekey_tunnel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
 
 /**
- * Out ephemeral key has changed, create new session key on all tunnels.
+ * Our ephemeral key has changed, create new session key on all tunnels.
+ *
+ * Each tunnel will start the Key Exchange with a random delay between
+ * 0 and number_of_tunnels*100 milliseconds, so there are 10 key exchanges
+ * per second, on average.
  *
  * @param cls Closure (size of the hashmap).
  * @param key Current public key.
@@ -1153,7 +1311,7 @@ rekey_iterator (void *cls,
                 const struct GNUNET_PeerIdentity *key,
                 void *value)
 {
-  struct CadetTunnel3 *t = value;
+  struct CadetTunnel *t = value;
   struct GNUNET_TIME_Relative delay;
   long n = (long) cls;
   uint32_t r;
@@ -1161,7 +1319,7 @@ rekey_iterator (void *cls,
   if (GNUNET_SCHEDULER_NO_TASK != t->rekey_task)
     return GNUNET_YES;
 
-  if (GNUNET_YES == GMT_is_loopback (t))
+  if (GNUNET_YES == GCT_is_loopback (t))
     return GNUNET_YES;
 
   r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, (uint32_t) n * 100);
@@ -1225,10 +1383,10 @@ destroy_iterator (void *cls,
                 const struct GNUNET_PeerIdentity *key,
                 void *value)
 {
-  struct CadetTunnel3 *t = value;
+  struct CadetTunnel *t = value;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT_shutdown destroying tunnel at %p\n", t);
-  GMT_destroy (t);
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "GCT_shutdown destroying tunnel at %p\n", t);
+  GCT_destroy (t);
   return GNUNET_YES;
 }
 
@@ -1241,7 +1399,7 @@ destroy_iterator (void *cls,
  * @param gid ID of the channel.
  */
 static void
-send_channel_destroy (struct CadetTunnel3 *t, unsigned int gid)
+send_channel_destroy (struct CadetTunnel *t, unsigned int gid)
 {
   struct GNUNET_CADET_ChannelManage msg;
 
@@ -1251,7 +1409,7 @@ send_channel_destroy (struct CadetTunnel3 *t, unsigned int gid)
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "WARNING destroying unknown channel %u on tunnel %s\n",
-       gid, GMT_2s (t));
+       gid, GCT_2s (t));
   send_prebuilt_message (&msg.header, t, NULL, GNUNET_YES, NULL, NULL, NULL);
 }
 
@@ -1267,7 +1425,7 @@ send_channel_destroy (struct CadetTunnel3 *t, unsigned int gid)
  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
  */
 static void
-handle_data (struct CadetTunnel3 *t,
+handle_data (struct CadetTunnel *t,
              const struct GNUNET_CADET_Data *msg,
              int fwd)
 {
@@ -1284,10 +1442,10 @@ handle_data (struct CadetTunnel3 *t,
     return;
   }
   LOG (GNUNET_ERROR_TYPE_DEBUG, " payload of type %s\n",
-              GM_m2s (ntohs (msg[1].header.type)));
+              GC_m2s (ntohs (msg[1].header.type)));
 
   /* Check channel */
-  ch = GMT_get_channel (t, ntohl (msg->chid));
+  ch = GCT_get_channel (t, ntohl (msg->chid));
   if (NULL == ch)
   {
     GNUNET_STATISTICS_update (stats, "# data on unknown channel",
@@ -1298,7 +1456,7 @@ handle_data (struct CadetTunnel3 *t,
     return;
   }
 
-  GMCH_handle_data (ch, msg, fwd);
+  GCCH_handle_data (ch, msg, fwd);
 }
 
 
@@ -1313,7 +1471,7 @@ handle_data (struct CadetTunnel3 *t,
  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
  */
 static void
-handle_data_ack (struct CadetTunnel3 *t,
+handle_data_ack (struct CadetTunnel *t,
                  const struct GNUNET_CADET_DataACK *msg,
                  int fwd)
 {
@@ -1329,7 +1487,7 @@ handle_data_ack (struct CadetTunnel3 *t,
   }
 
   /* Check channel */
-  ch = GMT_get_channel (t, ntohl (msg->chid));
+  ch = GCT_get_channel (t, ntohl (msg->chid));
   if (NULL == ch)
   {
     GNUNET_STATISTICS_update (stats, "# data ack on unknown channel",
@@ -1339,7 +1497,7 @@ handle_data_ack (struct CadetTunnel3 *t,
     return;
   }
 
-  GMCH_handle_data_ack (ch, msg, fwd);
+  GCCH_handle_data_ack (ch, msg, fwd);
 }
 
 
@@ -1350,7 +1508,7 @@ handle_data_ack (struct CadetTunnel3 *t,
  * @param msg Data message.
  */
 static void
-handle_ch_create (struct CadetTunnel3 *t,
+handle_ch_create (struct CadetTunnel *t,
                   const struct GNUNET_CADET_ChannelCreate *msg)
 {
   struct CadetChannel *ch;
@@ -1365,15 +1523,15 @@ handle_ch_create (struct CadetTunnel3 *t,
   }
 
   /* Check channel */
-  ch = GMT_get_channel (t, ntohl (msg->chid));
-  if (NULL != ch && ! GMT_is_loopback (t))
+  ch = GCT_get_channel (t, ntohl (msg->chid));
+  if (NULL != ch && ! GCT_is_loopback (t))
   {
     /* Probably a retransmission, safe to ignore */
     LOG (GNUNET_ERROR_TYPE_DEBUG, "   already exists...\n");
   }
-  ch = GMCH_handle_create (t, msg);
+  ch = GCCH_handle_create (t, msg);
   if (NULL != ch)
-    GMT_add_channel (t, ch);
+    GCT_add_channel (t, ch);
 }
 
 
@@ -1385,7 +1543,7 @@ handle_ch_create (struct CadetTunnel3 *t,
  * @param msg NACK message.
  */
 static void
-handle_ch_nack (struct CadetTunnel3 *t,
+handle_ch_nack (struct CadetTunnel *t,
                 const struct GNUNET_CADET_ChannelManage *msg)
 {
   struct CadetChannel *ch;
@@ -1400,7 +1558,7 @@ handle_ch_nack (struct CadetTunnel3 *t,
   }
 
   /* Check channel */
-  ch = GMT_get_channel (t, ntohl (msg->chid));
+  ch = GCT_get_channel (t, ntohl (msg->chid));
   if (NULL == ch)
   {
     GNUNET_STATISTICS_update (stats, "# channel NACK on unknown channel",
@@ -1410,7 +1568,7 @@ handle_ch_nack (struct CadetTunnel3 *t,
     return;
   }
 
-  GMCH_handle_nack (ch);
+  GCCH_handle_nack (ch);
 }
 
 
@@ -1425,7 +1583,7 @@ handle_ch_nack (struct CadetTunnel3 *t,
  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
  */
 static void
-handle_ch_ack (struct CadetTunnel3 *t,
+handle_ch_ack (struct CadetTunnel *t,
                const struct GNUNET_CADET_ChannelManage *msg,
                int fwd)
 {
@@ -1441,7 +1599,7 @@ handle_ch_ack (struct CadetTunnel3 *t,
   }
 
   /* Check channel */
-  ch = GMT_get_channel (t, ntohl (msg->chid));
+  ch = GCT_get_channel (t, ntohl (msg->chid));
   if (NULL == ch)
   {
     GNUNET_STATISTICS_update (stats, "# channel ack on unknown channel",
@@ -1451,11 +1609,10 @@ handle_ch_ack (struct CadetTunnel3 *t,
     return;
   }
 
-  GMCH_handle_ack (ch, msg, fwd);
+  GCCH_handle_ack (ch, msg, fwd);
 }
 
 
-
 /**
  * Handle a channel destruction message.
  *
@@ -1467,7 +1624,7 @@ handle_ch_ack (struct CadetTunnel3 *t,
  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
  */
 static void
-handle_ch_destroy (struct CadetTunnel3 *t,
+handle_ch_destroy (struct CadetTunnel *t,
                    const struct GNUNET_CADET_ChannelManage *msg,
                    int fwd)
 {
@@ -1483,14 +1640,14 @@ handle_ch_destroy (struct CadetTunnel3 *t,
   }
 
   /* Check channel */
-  ch = GMT_get_channel (t, ntohl (msg->chid));
+  ch = GCT_get_channel (t, ntohl (msg->chid));
   if (NULL == ch)
   {
     /* Probably a retransmission, safe to ignore */
     return;
   }
 
-  GMCH_handle_destroy (ch, msg, fwd);
+  GCCH_handle_destroy (ch, msg, fwd);
 }
 
 
@@ -1501,24 +1658,21 @@ handle_ch_destroy (struct CadetTunnel3 *t,
  * @param msg Key eXchange message.
  */
 static void
-handle_ephemeral (struct CadetTunnel3 *t,
+handle_ephemeral (struct CadetTunnel *t,
                   const struct GNUNET_CADET_KX_Ephemeral *msg)
 {
-  struct GNUNET_HashCode km;
-  LOG (GNUNET_ERROR_TYPE_INFO, "<=== EPHM for %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_INFO, "<=== EPHM for %s\n", GCT_2s (t));
 
   if (GNUNET_OK != check_ephemeral (t, msg))
   {
     GNUNET_break_op (0);
     return;
   }
-  derive_key_material (&km, &msg->ephemeral_key);
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "  km is %s\n", GNUNET_h2s (&km));
-  derive_symmertic (&t->e_key, &my_full_id, GMP_get_id (t->peer), &km);
-  derive_symmertic (&t->d_key, GMP_get_id (t->peer), &my_full_id, &km);
+  t->peers_ephemeral_key = msg->ephemeral_key;
+  create_keys (t);
   if (CADET_TUNNEL3_KEY_SENT == t->estate)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "  our key was sent, send ping\n");
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "  our key was sent, sending ping\n");
     send_ping (t);
     t->estate = CADET_TUNNEL3_KEY_PING;
   }
@@ -1533,7 +1687,7 @@ handle_ephemeral (struct CadetTunnel3 *t,
  * @param msg Key eXchange Ping message.
  */
 static void
-handle_ping (struct CadetTunnel3 *t,
+handle_ping (struct CadetTunnel *t,
              const struct GNUNET_CADET_KX_Ping *msg)
 {
   struct GNUNET_CADET_KX_Ping res;
@@ -1544,12 +1698,12 @@ handle_ping (struct CadetTunnel3 *t,
     return;
   }
 
-  LOG (GNUNET_ERROR_TYPE_INFO, "<=== PING for %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_INFO, "<=== PING for %s\n", GCT_2s (t));
   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_STATISTICS_update (stats, "# malformed PINGs", 1, GNUNET_NO);
-    LOG (GNUNET_ERROR_TYPE_WARNING, "  malformed PING on %s\n", GMT_2s (t));
+    LOG (GNUNET_ERROR_TYPE_WARNING, "  malformed PING on %s\n", GCT_2s (t));
     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);
@@ -1561,6 +1715,23 @@ handle_ping (struct CadetTunnel3 *t,
 
   send_pong (t, res.nonce);
 }
+/**
+ * @brief Finish the Key eXchange and destory the old keys.
+ *
+ * @param cls Closure (Tunnel for which to finish the KX).
+ * @param tc Task context.
+ */
+static void
+finish_kx (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct CadetTunnel *t = cls;
+
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
+
+  GNUNET_free (t->kx_ctx);
+  t->kx_ctx = NULL;
+}
 
 
 /**
@@ -1572,12 +1743,12 @@ handle_ping (struct CadetTunnel3 *t,
  * @param msg Key eXchange Pong message.
  */
 static void
-handle_pong (struct CadetTunnel3 *t,
+handle_pong (struct CadetTunnel *t,
              const struct GNUNET_CADET_KX_Pong *msg)
 {
   uint32_t challenge;
 
-  LOG (GNUNET_ERROR_TYPE_INFO, "<=== PONG for %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_INFO, "<=== PONG for %s\n", GCT_2s (t));
   if (GNUNET_SCHEDULER_NO_TASK == t->rekey_task)
   {
     GNUNET_STATISTICS_update (stats, "# duplicate PONG messages", 1, GNUNET_NO);
@@ -1587,7 +1758,7 @@ handle_pong (struct CadetTunnel3 *t,
 
   if (challenge != t->kx_ctx->challenge)
   {
-    LOG (GNUNET_ERROR_TYPE_WARNING, "Wrong PONG challenge on %s\n", GMT_2s (t));
+    LOG (GNUNET_ERROR_TYPE_WARNING, "Wrong PONG challenge on %s\n", GCT_2s (t));
     LOG (GNUNET_ERROR_TYPE_DEBUG, "PONG: %u (e: %u). Expected: %u.\n",
          challenge, msg->nonce, t->kx_ctx->challenge);
     send_ephemeral (t);
@@ -1596,9 +1767,18 @@ handle_pong (struct CadetTunnel3 *t,
   }
   GNUNET_SCHEDULER_cancel (t->rekey_task);
   t->rekey_task = GNUNET_SCHEDULER_NO_TASK;
-  GNUNET_free (t->kx_ctx);
-  t->kx_ctx = NULL;
-  GMT_change_estate (t, CADET_TUNNEL3_KEY_OK);
+
+  /* Don't free the old keys right away, but after a delay.
+   * Rationale: the KX could have happened over a very fast connection,
+   * with payload traffic still signed with the old key stuck in a slower
+   * connection.
+   */
+  if (GNUNET_SCHEDULER_NO_TASK == t->kx_ctx->finish_task)
+  {
+    t->kx_ctx->finish_task =
+      GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_MINUTES, finish_kx, t);
+  }
+  GCT_change_estate (t, CADET_TUNNEL3_KEY_OK);
 }
 
 
@@ -1614,14 +1794,14 @@ handle_pong (struct CadetTunnel3 *t,
  *            #GNUNET_SYSERR if message on a one-ended channel (remote)
  */
 static void
-handle_decrypted (struct CadetTunnel3 *t,
+handle_decrypted (struct CadetTunnel *t,
                   const struct GNUNET_MessageHeader *msgh,
                   int fwd)
 {
   uint16_t type;
 
   type = ntohs (msgh->type);
-  LOG (GNUNET_ERROR_TYPE_INFO, "<=== %s on %s\n", GM_m2s (type), GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_INFO, "<=== %s on %s\n", GC_m2s (type), GCT_2s (t));
 
   switch (type)
   {
@@ -1666,7 +1846,7 @@ handle_decrypted (struct CadetTunnel3 *t,
       LOG (GNUNET_ERROR_TYPE_WARNING,
            "end-to-end message not known (%u)\n",
            ntohs (msgh->type));
-      GMT_debug (t);
+      GCT_debug (t);
   }
 }
 
@@ -1682,28 +1862,19 @@ handle_decrypted (struct CadetTunnel3 *t,
  * @param msg Encrypted message.
  */
 void
-GMT_handle_encrypted (struct CadetTunnel3 *t,
+GCT_handle_encrypted (struct CadetTunnel *t,
                       const struct GNUNET_CADET_Encrypted *msg)
 {
   size_t size = ntohs (msg->header.size);
   size_t payload_size = size - sizeof (struct GNUNET_CADET_Encrypted);
-  size_t decrypted_size;
+  int decrypted_size;
   char cbuf [payload_size];
   struct GNUNET_MessageHeader *msgh;
   unsigned int off;
-  struct GNUNET_CADET_Hash hmac;
 
-  decrypted_size = t_decrypt (t, cbuf, &msg[1], payload_size, msg->iv);
-  t_hmac (t, &msg[1], payload_size, msg->iv, GNUNET_NO, &hmac);
-  if (0 != memcmp (&hmac, &msg->hmac, sizeof (hmac)))
-  {
-    /* checksum failed */
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed checksum validation for a message on tunnel `%s'\n",
-                GMT_2s (t));
-    GNUNET_STATISTICS_update (stats, "# wrong HMAC", 1, GNUNET_NO);
-    return;
-  }
+  decrypted_size = t_decrypt_and_validate (t, cbuf, &msg[1], payload_size,
+                                           msg->iv, &msg->hmac);
+
   off = 0;
   while (off < decrypted_size)
   {
@@ -1721,7 +1892,7 @@ GMT_handle_encrypted (struct CadetTunnel3 *t,
  * @param message Payload of KX message.
  */
 void
-GMT_handle_kx (struct CadetTunnel3 *t,
+GCT_handle_kx (struct CadetTunnel *t,
                const struct GNUNET_MessageHeader *message)
 {
   uint16_t type;
@@ -1756,7 +1927,7 @@ GMT_handle_kx (struct CadetTunnel3 *t,
  * @param key ECC private key, to derive all other keys and do crypto.
  */
 void
-GMT_init (const struct GNUNET_CONFIGURATION_Handle *c,
+GCT_init (const struct GNUNET_CONFIGURATION_Handle *c,
           const struct GNUNET_CRYPTO_EddsaPrivateKey *key)
 {
   LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
@@ -1791,7 +1962,7 @@ GMT_init (const struct GNUNET_CONFIGURATION_Handle *c,
  * Shut down the tunnel subsystem.
  */
 void
-GMT_shutdown (void)
+GCT_shutdown (void)
 {
   if (GNUNET_SCHEDULER_NO_TASK != rekey_task)
   {
@@ -1808,17 +1979,17 @@ GMT_shutdown (void)
  *
  * @param destination Peer this tunnel is towards.
  */
-struct CadetTunnel3 *
-GMT_new (struct CadetPeer *destination)
+struct CadetTunnel *
+GCT_new (struct CadetPeer *destination)
 {
-  struct CadetTunnel3 *t;
+  struct CadetTunnel *t;
 
-  t = GNUNET_new (struct CadetTunnel3);
+  t = GNUNET_new (struct CadetTunnel);
   t->next_chid = 0;
   t->peer = destination;
 
   if (GNUNET_OK !=
-      GNUNET_CONTAINER_multipeermap_put (tunnels, GMP_get_id (destination), t,
+      GNUNET_CONTAINER_multipeermap_put (tunnels, GCP_get_id (destination), t,
                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
   {
     GNUNET_break (0);
@@ -1836,13 +2007,13 @@ GMT_new (struct CadetPeer *destination)
  * @param cstate New connection state.
  */
 void
-GMT_change_cstate (struct CadetTunnel3* t, enum CadetTunnel3CState cstate)
+GCT_change_cstate (struct CadetTunnel* t, enum CadetTunnelCState cstate)
 {
   if (NULL == t)
     return;
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s cstate %s => %s\n",
-       GMP_2s (t->peer), cstate2s (t->cstate), cstate2s (cstate));
-  if (myid != GMP_get_short_id (t->peer) &&
+       GCP_2s (t->peer), cstate2s (t->cstate), cstate2s (cstate));
+  if (myid != GCP_get_short_id (t->peer) &&
       CADET_TUNNEL3_READY != t->cstate &&
       CADET_TUNNEL3_READY == cstate)
   {
@@ -1861,10 +2032,10 @@ GMT_change_cstate (struct CadetTunnel3* t, enum CadetTunnel3CState cstate)
   t->cstate = cstate;
 
   if (CADET_TUNNEL3_READY == cstate
-      && CONNECTIONS_PER_TUNNEL <= GMT_count_connections (t))
+      && CONNECTIONS_PER_TUNNEL <= GCT_count_connections (t))
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  cstate triggered stop dht\n");
-    GMP_stop_search (t->peer);
+    GCP_stop_search (t->peer);
   }
 }
 
@@ -1875,17 +2046,17 @@ GMT_change_cstate (struct CadetTunnel3* t, enum CadetTunnel3CState cstate)
  * @param state New encryption state.
  */
 void
-GMT_change_estate (struct CadetTunnel3* t, enum CadetTunnel3EState state)
+GCT_change_estate (struct CadetTunnel* t, enum CadetTunnelEState state)
 {
   if (NULL == t)
     return;
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Tunnel %s estate was %s\n",
-       GMP_2s (t->peer), estate2s (t->estate));
+       GCP_2s (t->peer), estate2s (t->estate));
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Tunnel %s estate is now %s\n",
-       GMP_2s (t->peer), estate2s (state));
-  if (myid != GMP_get_short_id (t->peer) &&
+       GCP_2s (t->peer), estate2s (state));
+  if (myid != GCP_get_short_id (t->peer) &&
       CADET_TUNNEL3_KEY_OK != t->estate && CADET_TUNNEL3_KEY_OK == state)
   {
     t->estate = state;
@@ -1909,12 +2080,12 @@ GMT_change_estate (struct CadetTunnel3* t, enum CadetTunnel3EState state)
 static void
 trim_connections (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  struct CadetTunnel3 *t = cls;
+  struct CadetTunnel *t = cls;
 
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
     return;
 
-  if (GMT_count_connections (t) > 2 * CONNECTIONS_PER_TUNNEL)
+  if (GCT_count_connections (t) > 2 * CONNECTIONS_PER_TUNNEL)
   {
     struct CadetTConnection *iter;
     struct CadetTConnection *c;
@@ -1922,7 +2093,7 @@ trim_connections (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     for (c = iter = t->connection_head; NULL != iter; iter = iter->next)
     {
       if ((NULL == c || iter->created.abs_value_us > c->created.abs_value_us)
-          && GNUNET_NO == GMC_is_direct (iter->c))
+          && GNUNET_NO == GCC_is_direct (iter->c))
       {
         c = iter;
       }
@@ -1930,10 +2101,10 @@ trim_connections (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
     if (NULL != c)
     {
       LOG (GNUNET_ERROR_TYPE_DEBUG, "Too many connections on tunnel %s\n",
-           GMT_2s (t));
+           GCT_2s (t));
       LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying connection %s\n",
-           GMC_2s (c->c));
-      GMC_destroy (c->c);
+           GCC_2s (c->c));
+      GCC_destroy (c->c);
     }
     else
     {
@@ -1950,14 +2121,14 @@ trim_connections (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * @param c Connection.
  */
 void
-GMT_add_connection (struct CadetTunnel3 *t, struct CadetConnection *c)
+GCT_add_connection (struct CadetTunnel *t, struct CadetConnection *c)
 {
   struct CadetTConnection *aux;
 
   GNUNET_assert (NULL != c);
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "add connection %s\n", GMC_2s (c));
-  LOG (GNUNET_ERROR_TYPE_DEBUG, " to tunnel %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "add connection %s\n", GCC_2s (c));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, " to tunnel %s\n", GCT_2s (t));
   for (aux = t->connection_head; aux != NULL; aux = aux->next)
     if (aux->c == c)
       return;
@@ -1979,9 +2150,9 @@ GMT_add_connection (struct CadetTunnel3 *t, struct CadetConnection *c)
  * @param path Invalid path to remove. Is destroyed after removal.
  */
 void
-GMT_remove_path (struct CadetTunnel3 *t, struct CadetPeerPath *path)
+GCT_remove_path (struct CadetTunnel *t, struct CadetPeerPath *path)
 {
-  GMP_remove_path (t->peer, path);
+  GCP_remove_path (t->peer, path);
 }
 
 
@@ -1992,14 +2163,14 @@ GMT_remove_path (struct CadetTunnel3 *t, struct CadetPeerPath *path)
  * @param c Connection.
  */
 void
-GMT_remove_connection (struct CadetTunnel3 *t,
+GCT_remove_connection (struct CadetTunnel *t,
                        struct CadetConnection *c)
 {
   struct CadetTConnection *aux;
   struct CadetTConnection *next;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Removing connection %s from tunnel %s\n",
-       GMC_2s (c), GMT_2s (t));
+       GCC_2s (c), GCT_2s (t));
   for (aux = t->connection_head; aux != NULL; aux = next)
   {
     next = aux->next;
@@ -2011,14 +2182,14 @@ GMT_remove_connection (struct CadetTunnel3 *t,
   }
 
   /* Start new connections if needed */
-  if (CONNECTIONS_PER_TUNNEL < GMT_count_connections (t)
+  if (CONNECTIONS_PER_TUNNEL < GCT_count_connections (t)
       && GNUNET_SCHEDULER_NO_TASK == t->destroy_task
       && CADET_TUNNEL3_SHUTDOWN != t->cstate
       && GNUNET_NO == shutting_down)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "  no more connections, getting new ones\n");
     t->cstate = CADET_TUNNEL3_SEARCHING;
-    GMP_connect (t->peer);
+    GCP_connect (t->peer);
     return;
   }
 
@@ -2028,7 +2199,7 @@ GMT_remove_connection (struct CadetTunnel3 *t,
 
   /* Check if any connection is ready to maintaing cstate */
   for (aux = t->connection_head; aux != NULL; aux = aux->next)
-    if (CADET_CONNECTION_READY == GMC_get_state (aux->c))
+    if (CADET_CONNECTION_READY == GCC_get_state (aux->c))
       return;
 
   t->cstate = CADET_TUNNEL3_WAITING;
@@ -2042,7 +2213,7 @@ GMT_remove_connection (struct CadetTunnel3 *t,
  * @param ch Channel.
  */
 void
-GMT_add_channel (struct CadetTunnel3 *t, struct CadetChannel *ch)
+GCT_add_channel (struct CadetTunnel *t, struct CadetChannel *ch)
 {
   struct CadetTChannel *aux;
 
@@ -2078,7 +2249,7 @@ GMT_add_channel (struct CadetTunnel3 *t, struct CadetChannel *ch)
  * @param ch Channel.
  */
 void
-GMT_remove_channel (struct CadetTunnel3 *t, struct CadetChannel *ch)
+GCT_remove_channel (struct CadetTunnel *t, struct CadetChannel *ch)
 {
   struct CadetTChannel *aux;
 
@@ -2087,7 +2258,7 @@ GMT_remove_channel (struct CadetTunnel3 *t, struct CadetChannel *ch)
   {
     if (aux->ch == ch)
     {
-      LOG (GNUNET_ERROR_TYPE_DEBUG, " found! %s\n", GMCH_2s (ch));
+      LOG (GNUNET_ERROR_TYPE_DEBUG, " found! %s\n", GCCH_2s (ch));
       GNUNET_CONTAINER_DLL_remove (t->channel_head, t->channel_tail, aux);
       GNUNET_free (aux);
       return;
@@ -2105,7 +2276,7 @@ GMT_remove_channel (struct CadetTunnel3 *t, struct CadetChannel *ch)
  * @return channel handler, NULL if doesn't exist
  */
 struct CadetChannel *
-GMT_get_channel (struct CadetTunnel3 *t, CADET_ChannelNumber chid)
+GCT_get_channel (struct CadetTunnel *t, CADET_ChannelNumber chid)
 {
   struct CadetTChannel *iter;
 
@@ -2114,7 +2285,7 @@ GMT_get_channel (struct CadetTunnel3 *t, CADET_ChannelNumber chid)
 
   for (iter = t->channel_head; NULL != iter; iter = iter->next)
   {
-    if (GMCH_get_id (iter->ch) == chid)
+    if (GCCH_get_id (iter->ch) == chid)
       break;
   }
 
@@ -2135,7 +2306,7 @@ GMT_get_channel (struct CadetTunnel3 *t, CADET_ChannelNumber chid)
 static void
 delayed_destroy (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  struct CadetTunnel3 *t = cls;
+  struct CadetTunnel *t = cls;
   struct CadetTConnection *iter;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "delayed destroying tunnel %p\n", t);
@@ -2143,7 +2314,7 @@ delayed_destroy (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   {
     LOG (GNUNET_ERROR_TYPE_WARNING,
          "Not destroying tunnel, due to shutdown. "
-         "Tunnel at %p should have been freed by GMT_shutdown\n", t);
+         "Tunnel at %p should have been freed by GCT_shutdown\n", t);
     return;
   }
   t->destroy_task = GNUNET_SCHEDULER_NO_TASK;
@@ -2151,9 +2322,9 @@ delayed_destroy (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
   for (iter = t->connection_head; NULL != iter; iter = iter->next)
   {
-    GMC_send_destroy (iter->c);
+    GCC_send_destroy (iter->c);
   }
-  GMT_destroy (t);
+  GCT_destroy (t);
 }
 
 
@@ -2165,7 +2336,7 @@ delayed_destroy (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * @param t Tunnel to destroy.
  */
 void
-GMT_destroy_empty (struct CadetTunnel3 *t)
+GCT_destroy_empty (struct CadetTunnel *t)
 {
   if (GNUNET_YES == shutting_down)
     return; /* Will be destroyed immediately anyway */
@@ -2174,7 +2345,7 @@ GMT_destroy_empty (struct CadetTunnel3 *t)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Tunnel %s is already scheduled for destruction\n",
-         GMT_2s (t));
+         GCT_2s (t));
     GNUNET_break (0);
     /* should never happen, tunnel can only become empty once, and the
      * task identifier should be NO_TASK (cleaned when the tunnel was created
@@ -2184,7 +2355,7 @@ GMT_destroy_empty (struct CadetTunnel3 *t)
   }
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s empty: destroying scheduled\n",
-       GMT_2s (t));
+       GCT_2s (t));
 
   t->destroy_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
                                                   &delayed_destroy, t);
@@ -2199,13 +2370,13 @@ GMT_destroy_empty (struct CadetTunnel3 *t)
  * @param t Tunnel to destroy if empty.
  */
 void
-GMT_destroy_if_empty (struct CadetTunnel3 *t)
+GCT_destroy_if_empty (struct CadetTunnel *t)
 {
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s destroy if empty\n", GMT_2s (t));
-  if (1 < GMT_count_channels (t))
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel %s destroy if empty\n", GCT_2s (t));
+  if (1 < GCT_count_channels (t))
     return;
 
-  GMT_destroy_empty (t);
+  GCT_destroy_empty (t);
 }
 
 
@@ -2221,7 +2392,7 @@ GMT_destroy_if_empty (struct CadetTunnel3 *t)
  * @param t The tunnel to destroy.
  */
 void
-GMT_destroy (struct CadetTunnel3 *t)
+GCT_destroy (struct CadetTunnel *t)
 {
   struct CadetTConnection *iter_c;
   struct CadetTConnection *next_c;
@@ -2231,21 +2402,21 @@ GMT_destroy (struct CadetTunnel3 *t)
   if (NULL == t)
     return;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", GMP_2s (t->peer));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s\n", GCP_2s (t->peer));
 
   GNUNET_break (GNUNET_YES ==
                 GNUNET_CONTAINER_multipeermap_remove (tunnels,
-                                                      GMP_get_id (t->peer), t));
+                                                      GCP_get_id (t->peer), t));
 
   for (iter_c = t->connection_head; NULL != iter_c; iter_c = next_c)
   {
     next_c = iter_c->next;
-    GMC_destroy (iter_c->c);
+    GCC_destroy (iter_c->c);
   }
   for (iter_ch = t->channel_head; NULL != iter_ch; iter_ch = next_ch)
   {
     next_ch = iter_ch->next;
-    GMCH_destroy (iter_ch->ch);
+    GCCH_destroy (iter_ch->ch);
     /* Should only happen on shutdown, but it's ok. */
   }
 
@@ -2257,18 +2428,19 @@ GMT_destroy (struct CadetTunnel3 *t)
   }
 
   GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
-  GMP_set_tunnel (t->peer, NULL);
+  GCP_set_tunnel (t->peer, NULL);
 
   if (GNUNET_SCHEDULER_NO_TASK != t->rekey_task)
   {
     GNUNET_SCHEDULER_cancel (t->rekey_task);
     t->rekey_task = GNUNET_SCHEDULER_NO_TASK;
-    if (NULL != t->kx_ctx)
-      GNUNET_free (t->kx_ctx);
-    else
-      GNUNET_break (0);
   }
-
+  if (NULL != t->kx_ctx)
+  {
+    if (GNUNET_SCHEDULER_NO_TASK != t->kx_ctx->finish_task)
+      GNUNET_SCHEDULER_cancel (t->kx_ctx->finish_task);
+    GNUNET_free (t->kx_ctx);
+  }
   GNUNET_free (t);
 }
 
@@ -2284,7 +2456,7 @@ GMT_destroy (struct CadetTunnel3 *t)
  * @return Connection created.
  */
 struct CadetConnection *
-GMT_use_path (struct CadetTunnel3 *t, struct CadetPeerPath *p)
+GCT_use_path (struct CadetTunnel *t, struct CadetPeerPath *p)
 {
   struct CadetConnection *c;
   struct GNUNET_CADET_Hash cid;
@@ -2314,13 +2486,13 @@ GMT_use_path (struct CadetTunnel3 *t, struct CadetPeerPath *p)
   }
 
   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, &cid, sizeof (cid));
-  c = GMC_new (&cid, t, p, own_pos);
+  c = GCC_new (&cid, t, p, own_pos);
   if (NULL == c)
   {
     /* Path was flawed */
     return NULL;
   }
-  GMT_add_connection (t, c);
+  GCT_add_connection (t, c);
   return c;
 }
 
@@ -2333,7 +2505,7 @@ GMT_use_path (struct CadetTunnel3 *t, struct CadetPeerPath *p)
  * @return Number of connections.
  */
 unsigned int
-GMT_count_connections (struct CadetTunnel3 *t)
+GCT_count_connections (struct CadetTunnel *t)
 {
   struct CadetTConnection *iter;
   unsigned int count;
@@ -2342,7 +2514,7 @@ GMT_count_connections (struct CadetTunnel3 *t)
     return 0;
 
   for (count = 0, iter = t->connection_head; NULL != iter; iter = iter->next)
-    if (CADET_CONNECTION_DESTROYED != GMC_get_state (iter->c))
+    if (CADET_CONNECTION_DESTROYED != GCC_get_state (iter->c))
       count++;
 
   return count;
@@ -2356,7 +2528,7 @@ GMT_count_connections (struct CadetTunnel3 *t)
  * @return Number of channels.
  */
 unsigned int
-GMT_count_channels (struct CadetTunnel3 *t)
+GCT_count_channels (struct CadetTunnel *t)
 {
   struct CadetTChannel *iter;
   unsigned int count;
@@ -2376,13 +2548,13 @@ GMT_count_channels (struct CadetTunnel3 *t)
  *
  * @return Tunnel's connectivity state.
  */
-enum CadetTunnel3CState
-GMT_get_cstate (struct CadetTunnel3 *t)
+enum CadetTunnelCState
+GCT_get_cstate (struct CadetTunnel *t)
 {
   if (NULL == t)
   {
     GNUNET_assert (0);
-    return (enum CadetTunnel3CState) -1;
+    return (enum CadetTunnelCState) -1;
   }
   return t->cstate;
 }
@@ -2395,13 +2567,13 @@ GMT_get_cstate (struct CadetTunnel3 *t)
  *
  * @return Tunnel's encryption state.
  */
-enum CadetTunnel3EState
-GMT_get_estate (struct CadetTunnel3 *t)
+enum CadetTunnelEState
+GCT_get_estate (struct CadetTunnel *t)
 {
   if (NULL == t)
   {
     GNUNET_assert (0);
-    return (enum CadetTunnel3EState) -1;
+    return (enum CadetTunnelEState) -1;
   }
   return t->estate;
 }
@@ -2414,7 +2586,7 @@ GMT_get_estate (struct CadetTunnel3 *t)
  * @return Biggest buffer space offered by any channel in the tunnel.
  */
 unsigned int
-GMT_get_channels_buffer (struct CadetTunnel3 *t)
+GCT_get_channels_buffer (struct CadetTunnel *t)
 {
   struct CadetTChannel *iter;
   unsigned int buffer;
@@ -2445,7 +2617,7 @@ GMT_get_channels_buffer (struct CadetTunnel3 *t)
  * @return Buffer space offered by all connections in the tunnel.
  */
 unsigned int
-GMT_get_connections_buffer (struct CadetTunnel3 *t)
+GCT_get_connections_buffer (struct CadetTunnel *t)
 {
   struct CadetTConnection *iter;
   unsigned int buffer;
@@ -2453,7 +2625,7 @@ GMT_get_connections_buffer (struct CadetTunnel3 *t)
   buffer = 0;
   for (iter = t->connection_head; NULL != iter; iter = iter->next)
   {
-    if (GMC_get_state (iter->c) != CADET_CONNECTION_READY)
+    if (GCC_get_state (iter->c) != CADET_CONNECTION_READY)
     {
       continue;
     }
@@ -2472,9 +2644,9 @@ GMT_get_connections_buffer (struct CadetTunnel3 *t)
  * @return ID of the destination peer.
  */
 const struct GNUNET_PeerIdentity *
-GMT_get_destination (struct CadetTunnel3 *t)
+GCT_get_destination (struct CadetTunnel *t)
 {
-  return GMP_get_id (t->peer);
+  return GCP_get_id (t->peer);
 }
 
 
@@ -2486,7 +2658,7 @@ GMT_get_destination (struct CadetTunnel3 *t)
  * @return GID of a channel free to use.
  */
 CADET_ChannelNumber
-GMT_get_next_chid (struct CadetTunnel3 *t)
+GCT_get_next_chid (struct CadetTunnel *t)
 {
   CADET_ChannelNumber chid;
   CADET_ChannelNumber mask;
@@ -2496,14 +2668,14 @@ GMT_get_next_chid (struct CadetTunnel3 *t)
    * If our ID is bigger or loopback tunnel, start at 0, bit 30 = 0
    * If peer's ID is bigger, start at 0x4... bit 30 = 1
    */
-  result = GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, GMP_get_id (t->peer));
+  result = GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, GCP_get_id (t->peer));
   if (0 > result)
     mask = 0x40000000;
   else
     mask = 0x0;
   t->next_chid |= mask;
 
-  while (NULL != GMT_get_channel (t, t->next_chid))
+  while (NULL != GCT_get_channel (t, t->next_chid))
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Channel %u exists...\n", t->next_chid);
     t->next_chid = (t->next_chid + 1) & ~GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
@@ -2523,21 +2695,21 @@ GMT_get_next_chid (struct CadetTunnel3 *t)
  * @param t Channel which has some free buffer space.
  */
 void
-GMT_unchoke_channels (struct CadetTunnel3 *t)
+GCT_unchoke_channels (struct CadetTunnel *t)
 {
   struct CadetTChannel *iter;
   unsigned int buffer;
-  unsigned int channels = GMT_count_channels (t);
+  unsigned int channels = GCT_count_channels (t);
   unsigned int choked_n;
   struct CadetChannel *choked[channels];
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "GMT_unchoke_channels on %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "GCT_unchoke_channels on %s\n", GCT_2s (t));
   LOG (GNUNET_ERROR_TYPE_DEBUG, " head: %p\n", t->channel_head);
   if (NULL != t->channel_head)
     LOG (GNUNET_ERROR_TYPE_DEBUG, " head ch: %p\n", t->channel_head->ch);
 
   /* Get buffer space */
-  buffer = GMT_get_connections_buffer (t);
+  buffer = GCT_get_connections_buffer (t);
   if (0 == buffer)
   {
     return;
@@ -2558,7 +2730,7 @@ GMT_unchoke_channels (struct CadetTunnel3 *t)
   {
     unsigned int r = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                                choked_n);
-    GMCH_allow_client (choked[r], GMCH_is_origin (choked[r], GNUNET_YES));
+    GCCH_allow_client (choked[r], GCCH_is_origin (choked[r], GNUNET_YES));
     choked_n--;
     buffer--;
     choked[r] = choked[choked_n];
@@ -2574,7 +2746,7 @@ GMT_unchoke_channels (struct CadetTunnel3 *t)
  * @param t Tunnel.
  */
 void
-GMT_send_connection_acks (struct CadetTunnel3 *t)
+GCT_send_connection_acks (struct CadetTunnel *t)
 {
   struct CadetTConnection *iter;
   uint32_t allowed;
@@ -2584,7 +2756,7 @@ GMT_send_connection_acks (struct CadetTunnel3 *t)
   unsigned int buffer;
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "Tunnel send connection ACKs on %s\n",
-       GMT_2s (t));
+       GCT_2s (t));
 
   if (NULL == t)
   {
@@ -2592,11 +2764,11 @@ GMT_send_connection_acks (struct CadetTunnel3 *t)
     return;
   }
 
-  buffer = GMT_get_channels_buffer (t);
+  buffer = GCT_get_channels_buffer (t);
   LOG (GNUNET_ERROR_TYPE_DEBUG, "  buffer %u\n", buffer);
 
   /* Count connections, how many messages are already allowed */
-  cs = GMT_count_connections (t);
+  cs = GCT_count_connections (t);
   for (allowed = 0, iter = t->connection_head; NULL != iter; iter = iter->next)
   {
     allowed += get_connection_allowed (iter);
@@ -2623,8 +2795,8 @@ GMT_send_connection_acks (struct CadetTunnel3 *t)
     {
       continue;
     }
-    GMC_allow (iter->c, allow_per_connection,
-               GMC_is_origin (iter->c, GNUNET_NO));
+    GCC_allow (iter->c, allow_per_connection,
+               GCC_is_origin (iter->c, GNUNET_NO));
   }
 
   GNUNET_break (to_allow == 0);
@@ -2641,11 +2813,11 @@ GMT_send_connection_acks (struct CadetTunnel3 *t)
  * @param q Handle to the queue.
  */
 void
-GMT_cancel (struct CadetTunnel3Queue *q)
+GCT_cancel (struct CadetTunnelQueue *q)
 {
   if (NULL != q->cq)
   {
-    GMC_cancel (q->cq);
+    GCC_cancel (q->cq);
     /* tun_message_sent() will be called and free q */
   }
   else if (NULL != q->tqd)
@@ -2676,10 +2848,10 @@ GMT_cancel (struct CadetTunnel3Queue *q)
  *
  * @return Handle to cancel message. NULL if @c cont is NULL.
  */
-struct CadetTunnel3Queue *
-GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
-                           struct CadetTunnel3 *t, struct CadetConnection *c,
-                           int force, GMT_sent cont, void *cont_cls)
+struct CadetTunnelQueue *
+GCT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
+                           struct CadetTunnel *t, struct CadetConnection *c,
+                           int force, GCT_sent cont, void *cont_cls)
 {
   return send_prebuilt_message (message, t, c, force, cont, cont_cls, NULL);
 }
@@ -2693,9 +2865,9 @@ GMT_send_prebuilt_message (const struct GNUNET_MessageHeader *message,
  * @return #GNUNET_YES if it is loopback.
  */
 int
-GMT_is_loopback (const struct CadetTunnel3 *t)
+GCT_is_loopback (const struct CadetTunnel *t)
 {
-  return (myid == GMP_get_short_id (t->peer));
+  return (myid == GCP_get_short_id (t->peer));
 }
 
 
@@ -2708,12 +2880,12 @@ GMT_is_loopback (const struct CadetTunnel3 *t)
  * @return #GNUNET_YES a connection uses this path.
  */
 int
-GMT_is_path_used (const struct CadetTunnel3 *t, const struct CadetPeerPath *p)
+GCT_is_path_used (const struct CadetTunnel *t, const struct CadetPeerPath *p)
 {
   struct CadetTConnection *iter;
 
   for (iter = t->connection_head; NULL != iter; iter = iter->next)
-    if (GMC_get_path (iter->c) == p)
+    if (GCC_get_path (iter->c) == p)
       return GNUNET_YES;
 
   return GNUNET_NO;
@@ -2729,7 +2901,7 @@ GMT_is_path_used (const struct CadetTunnel3 *t, const struct CadetPeerPath *p)
  * @return Cost of the path (path length + number of overlapping nodes)
  */
 unsigned int
-GMT_get_path_cost (const struct CadetTunnel3 *t,
+GCT_get_path_cost (const struct CadetTunnel *t,
                    const struct CadetPeerPath *path)
 {
   struct CadetTConnection *iter;
@@ -2748,7 +2920,7 @@ GMT_get_path_cost (const struct CadetTunnel3 *t,
   {
     for (iter = t->connection_head; NULL != iter; iter = iter->next)
     {
-      aux = GMC_get_path (iter->c);
+      aux = GCC_get_path (iter->c);
       if (NULL == aux)
         continue;
 
@@ -2774,12 +2946,12 @@ GMT_get_path_cost (const struct CadetTunnel3 *t,
  * @return Static string the destination peer's ID.
  */
 const char *
-GMT_2s (const struct CadetTunnel3 *t)
+GCT_2s (const struct CadetTunnel *t)
 {
   if (NULL == t)
     return "(NULL)";
 
-  return GMP_2s (t->peer);
+  return GCP_2s (t->peer);
 }
 
 
@@ -2794,12 +2966,12 @@ GMT_2s (const struct CadetTunnel3 *t)
  * @param t Tunnel to debug.
  */
 void
-GMT_debug (const struct CadetTunnel3 *t)
+GCT_debug (const struct CadetTunnel *t)
 {
   struct CadetTChannel *iterch;
   struct CadetTConnection *iterc;
 
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT DEBUG TUNNEL TOWARDS %s\n", GMT_2s (t));
+  LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT DEBUG TUNNEL TOWARDS %s\n", GCT_2s (t));
   LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT  cstate %s, estate %s\n",
        cstate2s (t->cstate), estate2s (t->estate));
   LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT  kx_ctx %p, rekey_task %u\n",
@@ -2811,18 +2983,18 @@ GMT_debug (const struct CadetTunnel3 *t)
   LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT  channels:\n");
   for (iterch = t->channel_head; NULL != iterch; iterch = iterch->next)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT  - %s\n", GMCH_2s (iterch->ch));
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT  - %s\n", GCCH_2s (iterch->ch));
   }
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT  connections:\n");
   for (iterc = t->connection_head; NULL != iterc; iterc = iterc->next)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT  - %s [%u] buf: %u/%u (qn %u/%u)\n",
-         GMC_2s (iterc->c), GMC_get_state (iterc->c),
-         GMC_get_buffer (iterc->c, GNUNET_YES),
-         GMC_get_buffer (iterc->c, GNUNET_NO),
-         GMC_get_qn (iterc->c, GNUNET_YES),
-         GMC_get_qn (iterc->c, GNUNET_NO));
+         GCC_2s (iterc->c), GCC_get_state (iterc->c),
+         GCC_get_buffer (iterc->c, GNUNET_YES),
+         GCC_get_buffer (iterc->c, GNUNET_NO),
+         GCC_get_qn (iterc->c, GNUNET_YES),
+         GCC_get_qn (iterc->c, GNUNET_NO));
   }
 
   LOG (GNUNET_ERROR_TYPE_DEBUG, "TTT DEBUG TUNNEL END\n");
@@ -2836,7 +3008,7 @@ GMT_debug (const struct CadetTunnel3 *t)
  * @param cls Closure for @c iter.
  */
 void
-GMT_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls)
+GCT_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls)
 {
   GNUNET_CONTAINER_multipeermap_iterate (tunnels, iter, cls);
 }
@@ -2848,7 +3020,7 @@ GMT_iterate_all (GNUNET_CONTAINER_PeerMapIterator iter, void *cls)
  * @return Number of tunnels to remote peers kept by this peer.
  */
 unsigned int
-GMT_count_all (void)
+GCT_count_all (void)
 {
   return GNUNET_CONTAINER_multipeermap_size (tunnels);
 }
@@ -2862,7 +3034,7 @@ GMT_count_all (void)
  * @param cls Closure for @c iter.
  */
 void
-GMT_iterate_connections (struct CadetTunnel3 *t, GMT_conn_iter iter, void *cls)
+GCT_iterate_connections (struct CadetTunnel *t, GCT_conn_iter iter, void *cls)
 {
   struct CadetTConnection *ct;
 
@@ -2879,7 +3051,7 @@ GMT_iterate_connections (struct CadetTunnel3 *t, GMT_conn_iter iter, void *cls)
  * @param cls Closure for @c iter.
  */
 void
-GMT_iterate_channels (struct CadetTunnel3 *t, GMT_chan_iter iter, void *cls)
+GCT_iterate_channels (struct CadetTunnel *t, GCT_chan_iter iter, void *cls)
 {
   struct CadetTChannel *cht;