added drop message func
authort3sserakt <t3ss@posteo.de>
Tue, 17 Sep 2019 18:57:17 +0000 (20:57 +0200)
committert3sserakt <t3ss@posteo.de>
Fri, 3 Jan 2020 11:05:46 +0000 (12:05 +0100)
src/cadet/cadet.h
src/cadet/cadet_api_drop_message.c [new file with mode: 0644]
src/cadet/gnunet-service-cadet.c
src/cadet/gnunet-service-cadet.h
src/cadet/gnunet-service-cadet_channel.c
src/cadet/gnunet-service-cadet_channel.h
src/cadet/gnunet-service-cadet_connection.c
src/cadet/gnunet-service-cadet_tunnels.c
src/cadet/gnunet-service-cadet_tunnels.h
src/cadet/test_cadet.c
src/include/gnunet_protocols.h

index ff3e47d19b1ea25d9a282ca16f535460299a6c94..adb9d356c72af46e16a716ed48225df5301ae1e1 100644 (file)
@@ -252,7 +252,29 @@ struct GNUNET_CADET_LocalInfo
   struct GNUNET_PeerIdentity peer;
 };
 
+/**
+ * Message to drop another message of specific type. Used in test context
+ */
+struct GNUNET_CADET_RequestDropCadetMessage
+{
+
+  /**
+   * Type: #GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE
+   */
+  struct GNUNET_MessageHeader header;
+  
+  /**
+   * Type of the message this handler covers, in host byte order.
+   */
+  uint16_t type;
 
+  /**
+   * ID of the channel we want to drop a message for.
+   */
+  struct GNUNET_CADET_ClientChannelNumber ccn;
+
+};
+  
 /**
  * Message to inform the client about channels in the service.
  */
diff --git a/src/cadet/cadet_api_drop_message.c b/src/cadet/cadet_api_drop_message.c
new file mode 100644 (file)
index 0000000..1d9030a
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2011, 2017, 2019 GNUnet e.V.
+
+     GNUnet is free software: you can redistribute it and/or modify it
+     under the terms of the GNU Affero General Public License as published
+     by the Free Software Foundation, either version 3 of the License,
+     or (at your option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Affero General Public License for more details.
+    
+     You should have received a copy of the GNU Affero General Public License
+     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+     SPDX-License-Identifier: AGPL3.0-or-later
+*/
+/**
+ * @file cadet/cadet_api_drop_message.c
+ * @brief cadet api: client implementation of cadet service
+ * @author t3sserakt
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_constants.h"
+#include "gnunet_cadet_service.h"
+#include "cadet.h"
+#include "cadet_protocol.h"
+
+
+/**
+ * Operation handle.
+ */
+struct GNUNET_CADET_ChannelMonitor
+{
+
+  /**
+   * Channel callback.
+   */
+  GNUNET_CADET_ChannelCB channel_cb;
+
+  /**
+   * Info callback closure for @c channel_cb.
+   */
+  void *channel_cb_cls;
+
+  /**
+   * Configuration we use.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Message queue to talk to CADET service.
+   */
+  struct GNUNET_MQ_Handle *mq;
+  
+  /**
+   * Task to reconnect.
+   */
+  struct GNUNET_SCHEDULER_Task *reconnect_task;
+
+  /**
+   * Backoff for reconnect attempts.
+   */
+  struct GNUNET_TIME_Relative backoff;
+
+  /**
+   * Peer we want information about.
+   */
+  struct GNUNET_PeerIdentity peer;
+
+};
+
+
+/**
+ * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE request.
+ *
+ * @param cls client Identification of the client.
+ * @param message The actual message.
+ */
+static void
+handle_drop_message (void *cls,
+                     const struct GNUNET_CADET_RequestDropCadetMessage *message)
+{
+  struct CadetClient *c = cls;
+  struct CadetChannel *ch;
+
+  ch = lookup_channel (c,
+                       message->ccn);
+
+  GCCH_assign_type_to_drop(ch, message);
+  
+  GNUNET_SERVICE_client_continue (c->client);
+}
+
+/**
+ * Reconnect to the service and try again.
+ *
+ * @param cls a `struct GNUNET_CADET_ChannelMonitor` operation
+ */
+static void
+reconnect (struct GNUNET_CADET_Handle *h);
+
+
+/**
+ * Function called on connection trouble.  Reconnects.
+ *
+ * @param cls a `struct GNUNET_CADET_ChannelMonitor``
+ * @param error error code from MQ
+ */
+static void
+error_handler (void *cls,
+              enum GNUNET_MQ_Error error)
+{
+  struct GNUNET_CADET_ChannelMonitor *cm = cls;
+
+  GNUNET_MQ_destroy (cm->mq);
+  cm->mq = NULL;
+  cm->backoff = GNUNET_TIME_randomized_backoff (cm->backoff,
+                                               GNUNET_TIME_UNIT_MINUTES);
+  cm->reconnect_task = GNUNET_SCHEDULER_add_delayed (cm->backoff,
+                                                    &reconnect,
+                                                    cm);
+}
+
+
+/**
+ * Reconnect to the service and try again.
+ *
+ * @param cls a `struct GNUNET_CADET_ChannelMonitor` operation
+ */
+static void
+reconnect (void *clsstruct GNUNET_CADET_Handle *h)
+{
+  
+  struct GNUNET_MQ_MessageHandler handlers[] = {
+    GNUNET_MQ_hd_fixed_size (drop_message,
+                            GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE,
+                            struct GNUNET_CADET_RequestDropCadetMessage,
+                            NULL),
+    GNUNET_MQ_handler_end ()
+  };
+  GNUNET_assert (NULL == h->mq);
+  h->mq =
+    GNUNET_CLIENT_connect (h->cfg, "cadet", handlers, &error_handler, h);
+}
+
+
+/**
+ * Request information about a specific channel of the running cadet peer.
+ *
+ * @param cfg configuration to use
+ * @param peer ID of the other end of the channel.
+ * @param callback Function to call with the requested data.
+ * @param callback_cls Closure for @c callback.
+ * @return NULL on error
+ */
+struct GNUNET_CADET_ChannelMonitor *
+GNUNET_CADET_get_channel (const struct GNUNET_CONFIGURATION_Handle *cfg,
+                          struct GNUNET_PeerIdentity *peer,
+                          GNUNET_CADET_ChannelCB callback,
+                          void *callback_cls)
+{
+  struct GNUNET_CADET_ChannelMonitor *cm;
+
+  if (NULL == callback)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  cm = GNUNET_new (struct GNUNET_CADET_ChannelMonitor);
+  cm->channel_cb = callback;
+  cm->channel_cb_cls = callback_cls;
+  cm->cfg = cfg;
+  cm->peer = *peer;
+  reconnect (cm);
+  if (NULL == cm->mq)
+  {
+    GNUNET_free (cm);
+    return NULL;
+  }
+  return cm;
+}
+
+
+
+
+/* end of cadet_api_get_channel.c */
index 209f7d3927535b51c9bc4f3a96b95ea6e930db41..979bd05ca06067d79551afffd4dc32365d4f6a4a 100644 (file)
@@ -1003,6 +1003,26 @@ handle_info_tunnels (void *cls,
   GNUNET_SERVICE_client_continue (c->client);
 }
 
+/**
+ * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE request.
+ *
+ * @param cls client Identification of the client.
+ * @param message The actual message.
+ */
+static void
+handle_drop_message (void *cls,
+                     const struct GNUNET_CADET_RequestDropCadetMessage *message)
+{
+  struct CadetClient *c = cls;
+  struct CadetChannel *ch;
+
+  ch = lookup_channel (c,
+                       message->ccn);
+
+  GCCH_assign_type_to_drop(ch, message);
+  
+  GNUNET_SERVICE_client_continue (c->client);
+}
 
 /**
  * Callback called when a client connects to the service.
@@ -1342,6 +1362,10 @@ GNUNET_SERVICE_MAIN
                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_TUNNELS,
                           struct GNUNET_MessageHeader,
                           NULL),
+ GNUNET_MQ_hd_fixed_size (drop_message,
+                          GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE,
+                          struct GNUNET_CADET_RequestDropCadetMessage,
+                          NULL),
  GNUNET_MQ_handler_end ());
 
 /* end of gnunet-service-cadet-new.c */
index 3daeeff74db2ec275c18cc5476d8100a9987b2a7..0953cb00411fbff837a5a041a8ddf0bf3f627a64 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
      This file is part of GNUnet.
      Copyright (C) 2001-2017 GNUnet e.V.
index 664b8a7c1149e906fcef97c2ecbd830bc450611c..be8548c0282519af732200c0bf8466239486c933 100644 (file)
@@ -380,8 +380,44 @@ struct CadetChannel
    * empty.
    */
   int destroy;
+
+  /**
+   * Type of message to be droped. See GCT_send.
+   */
+  uint16_t type GNUNET_PACKED;
+  
 };
 
+/**
+ * Check if type of message is the one to drop.
+ * @param ch CadetChannel to assign type to drop. 
+ * @param message GNUNET_CADET_RequestDropCadetMessage to get the type from.
+ */
+void
+GCCH_assign_type_to_drop(struct CadetChannel *ch, const struct GNUNET_CADET_RequestDropCadetMessage *message)
+{
+
+  ch->type = message->type;
+  
+}
+
+/**
+ * Check if type of message is the one to drop.
+ * @param ch CadetChannel to check for message type to drop. 
+ * @param message GNUNET_MessageHeader to compare the type with.
+ */
+int
+GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message)
+{
+
+  if (ch->type == message->type)
+  {
+    ch->type = 0;
+    return GNUNET_YES;
+  }
+  else
+    return GNUNET_NO;
+}
 
 /**
  * Get the static string for identification of the channel.
@@ -594,7 +630,7 @@ send_channel_open (void *cls)
   if (NULL != ch->last_control_qe)
     GCT_send_cancel (ch->last_control_qe);
   ch->last_control_qe =
-    GCT_send (ch->t, &msgcc.header, &channel_open_sent_cb, ch);
+    GCT_send (ch->t, &msgcc.header, &channel_open_sent_cb, ch, &msgcc.ctn);
   GNUNET_assert (NULL == ch->retry_control_task);
 }
 
@@ -818,7 +854,7 @@ send_channel_data_ack (struct CadetChannel *ch)
        GCCH_2s (ch));
   if (NULL != ch->last_control_qe)
     GCT_send_cancel (ch->last_control_qe);
-  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch);
+  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch, &msg.ctn);
 }
 
 
@@ -845,7 +881,7 @@ send_open_ack (void *cls)
   msg.port = ch->port;
   if (NULL != ch->last_control_qe)
     GCT_send_cancel (ch->last_control_qe);
-  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch);
+  ch->last_control_qe = GCT_send (ch->t, &msg.header, &send_ack_cb, ch, &msg.ctn);
 }
 
 
@@ -1474,7 +1510,7 @@ retry_transmission (void *cls)
        "Retrying transmission on %s of message %u\n",
        GCCH_2s (ch),
        (unsigned int) ntohl (crm->data_message->mid.mid));
-  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm);
+  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm, &crm->data_message->ctn);
   GNUNET_assert (NULL == ch->retry_data_task);
 }
 
@@ -1861,7 +1897,7 @@ GCCH_handle_local_data (struct CadetChannel *ch,
     GNUNET_SCHEDULER_cancel (ch->retry_data_task);
     ch->retry_data_task = NULL;
   }
-  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm);
+  crm->qe = GCT_send (ch->t, &crm->data_message->header, &data_sent_cb, crm, &crm->data_message->ctn);
   GNUNET_assert (NULL == ch->retry_data_task);
   return GNUNET_OK;
 }
index 2eb28262d3169f22f80b9b4f436cc5b42d507864..80fc434773a48e1d1841f49f4113084b1d8f8d58 100644 (file)
@@ -56,7 +56,21 @@ void
 GCCH_hash_port (struct GNUNET_HashCode *h_port,
                const struct GNUNET_HashCode *port,
                const struct GNUNET_PeerIdentity *listener);
+/**
+ * Check if type of message is the one to drop.
+ * @param ch CadetChannel to assign type to drop. 
+ * @param message GNUNET_CADET_RequestDropCadetMessage to get the type from.
+ */
+void
+GCCH_assign_type_to_drop(struct CadetChannel *ch, const struct GNUNET_CADET_RequestDropCadetMessage *message);
 
+/**
+ * Check if type of message is the one to drop.
+ * @param ch CadetChannel to check for message type to drop. 
+ * @param message GNUNET_MessageHeader to compare the type with.
+ */
+int
+GCCH_is_type_to_drop(struct CadetChannel *ch, const struct GNUNET_MessageHeader *message);
 
 /**
  * Get the static string for identification of the channel.
index 8849e563fc833051aa3fe29589eacba6dfed105f..0e6423e1020fb9350ae8bf886805e82bee912d93 100644 (file)
@@ -208,6 +208,14 @@ update_state (struct CadetConnection *cc,
   int old_ready;
   int new_ready;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Trying to update connection state for %s having old state %d to new %d and mqm_ready old %d to mqm_ready new %d\n",
+       GCT_2s (cc->ct->t),
+       cc->state,
+       new_state,
+       cc->mqm_ready,
+       new_mqm_ready);
+  
   if ((new_state == cc->state) && (new_mqm_ready == cc->mqm_ready))
     return; /* no change, nothing to do */
   old_ready =
@@ -216,6 +224,13 @@ update_state (struct CadetConnection *cc,
     ((CADET_CONNECTION_READY == new_state) && (GNUNET_YES == new_mqm_ready));
   cc->state = new_state;
   cc->mqm_ready = new_mqm_ready;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Updating connection state for %s having old_ready %d and new_rady %d\n",
+       GCT_2s (cc->ct->t),
+       old_ready,
+       new_ready);
+  
   if (old_ready != new_ready)
     cc->ready_cb (cc->ready_cb_cls, new_ready);
 }
@@ -394,7 +409,7 @@ send_keepalive (void *cls)
   msg.size = htons (sizeof (msg));
   msg.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE);
 
-  cc->keepalive_qe = GCT_send (cc->ct->t, &msg, &keepalive_done, cc);
+  cc->keepalive_qe = GCT_send (cc->ct->t, &msg, &keepalive_done, cc, NULL);
 }
 
 
index 11be2bce0f5a54037c627e6988e852159ab5a63d..d9e4141ac02c0a3ca9dead9c325ac13264ba8cee 100644 (file)
@@ -9,7 +9,7 @@
 
      GNUnet is distributed in the hope that it will be useful, but
      WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     MERCHsendANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      Affero General Public License for more details.
     
      You should have received a copy of the GNU Affero General Public License
@@ -1343,8 +1343,20 @@ send_kx (struct CadetTunnel *t,
   struct GNUNET_CADET_TunnelKeyExchangeMessage *msg;
   enum GNUNET_CADET_KX_Flags flags;
 
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Will we ever send a KX message?\n");
+  
   if (GNUNET_YES != alice_or_betty (GCP_get_id (t->destination)))
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+        "Only Alice may send KX to %s!\n",
+         GCT_2s (t));
     return; /* only Alice may send KX */
+  }
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "It is Alice!\n");
+  
   if ( (NULL == ct) ||
        (GNUNET_NO == ct->is_ready) )
     ct = get_ready_connection (t);
@@ -2116,9 +2128,10 @@ GCT_add_channel (struct CadetTunnel *t,
                                                       ch,
                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Adding %s to %s\n",
+       "Adding %s to %s with state %d\n",
        GCCH_2s (ch),
-       GCT_2s (t));
+       GCT_2s (t),
+       t->estate);
   switch (t->estate)
   {
   case CADET_TUNNEL_KEY_UNINITIALIZED:
@@ -2419,11 +2432,20 @@ connection_ready_cb (void *cls,
   switch (t->estate)
   {
   case CADET_TUNNEL_KEY_UNINITIALIZED:
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+        "Do not begin KX for %s if WE have no channels waiting. Retrying after %d\n",
+        GCT_2s (t),
+        GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt).rel_value_us);
     /* Do not begin KX if WE have no channels waiting! */
     if (0 != GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt).rel_value_us)
       return; /* wait for timeout before retrying */
     /* We are uninitialized, just transmit immediately,
        without undue delay. */
+
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+        "Why for %s \n",
+        GCT_2s (t));
+    
     if (NULL != t->kx_task)
     {
       GNUNET_SCHEDULER_cancel (t->kx_task);
@@ -3015,7 +3037,8 @@ GCT_send_channel_destroy (struct CadetTunnel *t,
   GCT_send (t,
             &msg.header,
             NULL,
-            NULL);
+            NULL,
+           &ctn);
 }
 
 
@@ -3434,13 +3457,26 @@ struct CadetTunnelQueueEntry *
 GCT_send (struct CadetTunnel *t,
           const struct GNUNET_MessageHeader *message,
           GCT_SendContinuation cont,
-          void *cont_cls)
+          void *cont_cls,
+         struct GNUNET_CADET_ChannelTunnelNumber *ctn)
 {
   struct CadetTunnelQueueEntry *tq;
   uint16_t payload_size;
   struct GNUNET_MQ_Envelope *env;
   struct GNUNET_CADET_TunnelEncryptedMessage *ax_msg;
+  struct CadetChannel *ch;
 
+  if (NULL != ctn)
+  {
+    ch = lookup_channel (t,
+                         *ctn);
+    if (GCCH_is_type_to_drop(ch, message))
+    {
+      GNUNET_break(0);
+      return NULL;
+    }
+  }
+  
   if (CADET_TUNNEL_KEY_OK != t->estate)
   {
     GNUNET_break (0);
index 47d9f98bf7c9e223412a44d9137da80421122756..3ee2c9852c6bee2cd3356629a47462ee263a9728 100644 (file)
@@ -226,7 +226,8 @@ struct CadetTunnelQueueEntry *
 GCT_send (struct CadetTunnel *t,
           const struct GNUNET_MessageHeader *message,
           GCT_SendContinuation cont,
-          void *cont_cls);
+          void *cont_cls,
+         struct GNUNET_CADET_ChannelTunnelNumber *ctn);
 
 
 /**
index 80a6e8227c5d8d10025b0396c5341af7f1418829..ae4a8fd8bed9805f6266a9e2fe24f252554d95e4 100644 (file)
@@ -73,6 +73,7 @@ struct CadetTestChannelWrapper
 #define SPEED_REL 8
 #define P2P_SIGNAL 10
 #define REOPEN 11
+#define DESTROY 12
 
 /**
  * Which test are we running?
@@ -1026,6 +1027,13 @@ start_test (void *cls)
   if (KEEPALIVE == test)
     return;                     /* Don't send any data. */
 
+  if (DESTROY == test)
+  {
+
+    
+    
+  }
+  
   data_received = 0;
   data_sent = 0;
   ack_received = 0;
index 45bfa4f1b4538bdf2796ad7548dd911bf8e28507..47e3051810fc607f55b93ea86cb58b1eb292e74d 100644 (file)
@@ -2736,9 +2736,8 @@ extern "C" {
  * 1000-1009 Connection-level Messages
  * 1010-1019 Channel-level Messages
  * 1020-1029 Local Client-Service
- * 1030-1039 Local Service Monitoring
- * 1040-1049 Application Data
- * 1050-1059 Reserved
+ * 1030-1049 Local Service Monitoring
+ * 1050-1059 Application Data
  */
 
 /********************************  Connection  ********************************/
@@ -2934,6 +2933,11 @@ extern "C" {
  */
 #define GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS_END 1041
 
+/**
+ * Request to drop a message of type X to peer y.
+ */
+#define GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE 1042
+
 
 /********************************  Application  *******************************/