fixing misc cleanup issues
authorChristian Grothoff <christian@grothoff.org>
Sun, 22 Jan 2017 19:13:39 +0000 (20:13 +0100)
committerChristian Grothoff <christian@grothoff.org>
Sun, 22 Jan 2017 19:13:39 +0000 (20:13 +0100)
src/cadet/gnunet-service-cadet-new.c
src/cadet/gnunet-service-cadet-new.h
src/cadet/gnunet-service-cadet-new_channel.c
src/cadet/gnunet-service-cadet-new_tunnels.c

index 2e431c034857783e452eb34b5ad1067ac49179c8..3bcf35db3ae00a9323c69a094fa031975666c501 100644 (file)
@@ -1121,6 +1121,33 @@ client_connect_cb (void *cls,
 }
 
 
+/**
+ * A channel was destroyed by the other peer. Tell our client.
+ *
+ * @param c client that lost a channel
+ * @param ccn channel identification number for the client
+ * @param ch the channel object
+ */
+void
+GSC_handle_remote_channel_destroy (struct CadetClient *c,
+                                   struct GNUNET_CADET_ClientChannelNumber ccn,
+                                   struct CadetChannel *ch)
+{
+  struct GNUNET_MQ_Envelope *env;
+  struct GNUNET_CADET_LocalChannelDestroyMessage *tdm;
+
+  env = GNUNET_MQ_msg (tdm,
+                       GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
+  tdm->ccn = ccn;
+  GSC_send_to_client (c,
+                      env);
+  GNUNET_assert (GNUNET_YES ==
+                 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
+                                                         ntohl (ccn.channel_of_client),
+                                                         ch));
+}
+
+
 /**
  * Iterator for deleting each channel whose client endpoint disconnected.
  *
@@ -1137,14 +1164,14 @@ channel_destroy_iterator (void *cls,
   struct CadetClient *c = cls;
   struct CadetChannel *ch = value;
 
-  GNUNET_assert (GNUNET_YES ==
-                 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
-                                                         key,
-                                                         ch));
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Destroying channel %s, due to client %s disconnecting.\n",
        GCCH_2s (ch),
        GSC_2s (c));
+  GNUNET_assert (GNUNET_YES ==
+                 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
+                                                         key,
+                                                         ch));
   if (key < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
     GCCH_channel_local_destroy (ch);
   else
index 25f02bf899ddd0725dfd7c5b22ed6a113cda5696..cb289e9c326edf6849b0433d4f960df086664005 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "gnunet_util_lib.h"
 #define NEW_CADET 1
+#include "cadet_protocol.h"
 
 /**
  * A client to the CADET service.  Each client gets a unique handle.
@@ -236,6 +237,19 @@ GSC_send_to_client (struct CadetClient *c,
                     struct GNUNET_MQ_Envelope *env);
 
 
+/**
+ * A channel was destroyed by the other peer. Tell our client.
+ *
+ * @param c client that lost a channel
+ * @param ccn channel identification number for the client
+ * @param ch the channel object
+ */
+void
+GSC_handle_remote_channel_destroy (struct CadetClient *c,
+                                   struct GNUNET_CADET_ClientChannelNumber ccn,
+                                   struct CadetChannel *ch);
+
+
 /**
  * Bind incoming channel to this client, and notify client
  * about incoming connection.
index f3603d8980c4c2facad05e3c94aa7195010f7f45..425422cb6a96d66eb96eadedc82187d755148993 100644 (file)
@@ -169,14 +169,6 @@ struct CadetChannel
    */
   struct CadetTunnel *t;
 
-  /**
-   * Last entry in the tunnel's queue relating to control messages
-   * (#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN or
-   * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK).  Used to cancel
-   * transmission in case we receive updated information.
-   */
-  struct CadetTunnelQueueEntry *last_control_qe;
-
   /**
    * Client owner of the tunnel, if any.
    * (Used if this channel represends the initiating end of the tunnel.)
@@ -189,6 +181,14 @@ struct CadetChannel
    */
   struct CadetClient *dest;
 
+  /**
+   * Last entry in the tunnel's queue relating to control messages
+   * (#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN or
+   * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK).  Used to cancel
+   * transmission in case we receive updated information.
+   */
+  struct CadetTunnelQueueEntry *last_control_qe;
+
   /**
    * Head of DLL of messages sent and not yet ACK'd.
    */
@@ -417,6 +417,7 @@ channel_open_sent_cb (void *cls)
 {
   struct CadetChannel *ch = cls;
 
+  GNUNET_assert (NULL != ch->last_control_qe);
   ch->last_control_qe = NULL;
   ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time);
   ch->retry_task = GNUNET_SCHEDULER_add_delayed (ch->retry_time,
@@ -620,6 +621,7 @@ send_ack_cb (void *cls)
 {
   struct CadetChannel *ch = cls;
 
+  GNUNET_assert (NULL != ch->last_control_qe);
   ch->last_control_qe = NULL;
 }
 
@@ -1025,18 +1027,13 @@ GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
 void
 GCCH_handle_remote_destroy (struct CadetChannel *ch)
 {
-  struct GNUNET_MQ_Envelope *env;
-  struct GNUNET_CADET_LocalChannelDestroyMessage *tdm;
-
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Received remote channel DESTROY for %s\n",
        GCCH_2s (ch));
   ch->destroy = GNUNET_YES;
-  env = GNUNET_MQ_msg (tdm,
-                       GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
-  tdm->ccn = ch->ccn;
-  GSC_send_to_client ((NULL != ch->owner) ? ch->owner : ch->dest,
-                      env);
+  GSC_handle_remote_channel_destroy ((NULL != ch->owner) ? ch->owner : ch->dest,
+                                     ch->ccn,
+                                     ch);
   channel_destroy (ch);
 }
 
index e5fb91f44a956f32fb05751fea2ca117ef815dc4..9754040cfcb5297a952d3a87345435ec3d007326 100644 (file)
@@ -308,6 +308,11 @@ struct CadetTunnel
    */
   struct GNUNET_SCHEDULER_Task *maintain_connections_task;
 
+  /**
+   * Task to send messages from queue (if possible).
+   */
+  struct GNUNET_SCHEDULER_Task *send_task;
+
   /**
    * Task to trigger KX.
    */
@@ -569,10 +574,10 @@ new_ephemeral (struct CadetTunnel *t)
  * at our message queue and if there is a message, picks a connection
  * to send it on.
  *
- * @param t tunnel to process messages on
+ * @param cls the `struct CadetTunnel` to process messages on
  */
 static void
-trigger_transmissions (struct CadetTunnel *t);
+trigger_transmissions (void *cls);
 
 
 /* ************************************** start core crypto ***************************** */
@@ -1437,7 +1442,10 @@ GCT_handle_kx (struct CadetTConnection *ct,
        we can start transmitting! */
     GCT_change_estate (t,
                        CADET_TUNNEL_KEY_OK);
-    trigger_transmissions (t);
+    if (NULL != t->send_task)
+      GNUNET_SCHEDULER_cancel (t->send_task);
+    t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions,
+                                             t);
     break;
   case CADET_TUNNEL_KEY_PING:
     /* Got a key yet again; need encrypted payload to advance */
@@ -1554,6 +1562,16 @@ destroy_tunnel (void *cls)
     GNUNET_SCHEDULER_cancel (t->maintain_connections_task);
     t->maintain_connections_task = NULL;
   }
+  if (NULL != t->send_task)
+  {
+    GNUNET_SCHEDULER_cancel (t->send_task);
+    t->send_task = NULL;
+  }
+  if (NULL != t->kx_task)
+  {
+    GNUNET_SCHEDULER_cancel (t->kx_task);
+    t->kx_task = NULL;
+  }
   GNUNET_MST_destroy (t->mst);
   GNUNET_MQ_destroy (t->mq);
   while (NULL != t->ax.skipped_head)
@@ -1744,13 +1762,15 @@ connection_ready_cb (void *cls,
  * at our message queue and if there is a message, picks a connection
  * to send it on.
  *
- * @param t tunnel to process messages on
+ * @param cls the `struct CadetTunnel` to process messages on
  */
 static void
-trigger_transmissions (struct CadetTunnel *t)
+trigger_transmissions (void *cls)
 {
+  struct CadetTunnel *t = cls;
   struct CadetTConnection *ct;
 
+  t->send_task = NULL;
   if (NULL == t->tq_head)
     return; /* no messages pending right now */
   ct = get_ready_connection (t);
@@ -2327,7 +2347,10 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
   {
     GCT_change_estate (t,
                        CADET_TUNNEL_KEY_OK);
-    trigger_transmissions (t);
+    if (NULL != t->send_task)
+      GNUNET_SCHEDULER_cancel (t->send_task);
+    t->send_task = GNUNET_SCHEDULER_add_now (&trigger_transmissions,
+                                             t);
   }
   /* The MST will ultimately call #handle_decrypted() on each message. */
   GNUNET_break_op (GNUNET_OK ==
@@ -2393,7 +2416,11 @@ GCT_send (struct CadetTunnel *t,
   GNUNET_CONTAINER_DLL_insert_tail (t->tq_head,
                                     t->tq_tail,
                                     tq);
-  trigger_transmissions (t);
+  if (NULL != t->send_task)
+    GNUNET_SCHEDULER_cancel (t->send_task);
+  t->send_task
+    = GNUNET_SCHEDULER_add_now (&trigger_transmissions,
+                                t);
   return tq;
 }