Fixed bug #5822 by adding a monotonic time to the connection create message of a...
authort3sserakt <t3ss@posteo.de>
Fri, 5 Jun 2020 14:37:10 +0000 (16:37 +0200)
committert3sserakt <t3ss@posteo.de>
Fri, 5 Jun 2020 14:37:10 +0000 (16:37 +0200)
19 files changed:
src/cadet/Makefile.am
src/cadet/cadet.h
src/cadet/cadet_api.c
src/cadet/cadet_protocol.h
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_connection.h
src/cadet/gnunet-service-cadet_core.c
src/cadet/gnunet-service-cadet_peer.c
src/cadet/gnunet-service-cadet_peer.h
src/cadet/gnunet-service-cadet_tunnels.c
src/cadet/gnunet-service-cadet_tunnels.h
src/cadet/test_cadet.c
src/cadet/test_cadet.conf
src/include/gnunet_protocols.h
src/include/gnunet_signatures.h

index d8d81bf20d6714d4465a544f04cbfab752b406bd..2289a2d96838ce92d59cebb6cbbbc0eeac3ccdf2 100644 (file)
@@ -30,6 +30,7 @@ lib_LTLIBRARIES = \
 
 libgnunetcadet_la_SOURCES = \
   cadet_api.c \
+  cadet_api_drop_message.c \
   cadet_api_get_channel.c \
   cadet_api_get_path.c \
   cadet_api_list_peers.c \
@@ -95,6 +96,7 @@ check_PROGRAMS = \
   test_cadet_2_speed_reliable \
   test_cadet_2_speed_reliable_backwards \
   test_cadet_2_reopen \
+  test_cadet_2_destroy \
   test_cadet_5_forward \
   test_cadet_5_signal \
   test_cadet_5_keepalive \
@@ -211,6 +213,9 @@ test_cadet_5_reopen_SOURCES = \
   test_cadet.c
 test_cadet_5_reopen_LDADD = $(ld_cadet_test_lib)
 
+test_cadet_2_destroy_SOURCES = \
+  test_cadet.c
+test_cadet_2_destroy_LDADD = $(ld_cadet_test_lib)
 
 if ENABLE_TEST_RUN
 AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
index 29400e39f953fa25d24361b8799f47969c685a15..d17eab1d65e1fe3e12b6d48b9213c7def1ec1fc9 100644 (file)
@@ -95,7 +95,6 @@ extern "C" {
 
 GNUNET_NETWORK_STRUCT_BEGIN
 
-
 /**
  * Number uniquely identifying a channel of a client.
  */
@@ -111,6 +110,70 @@ struct GNUNET_CADET_ClientChannelNumber
   uint32_t channel_of_client GNUNET_PACKED;
 };
 
+/**
+ * Opaque handle to a channel.
+ */
+struct GNUNET_CADET_Channel
+{
+
+  /**
+   * Other end of the channel.
+   */
+  struct GNUNET_PeerIdentity peer;
+
+  /**
+   * Handle to the cadet this channel belongs to
+   */
+  struct GNUNET_CADET_Handle *cadet;
+
+  /**
+   * Channel's port, if incoming.
+   */
+  struct GNUNET_CADET_Port *incoming_port;
+
+  /**
+   * Any data the caller wants to put in here, used for the
+   * various callbacks (@e disconnects, @e window_changes, handlers).
+   */
+  void *ctx;
+
+  /**
+   * Message Queue for the channel (which we are implementing).
+   */
+  struct GNUNET_MQ_Handle *mq;
+
+  /**
+   * Task to allow mq to send more traffic.
+   */
+  struct GNUNET_SCHEDULER_Task *mq_cont;
+
+  /**
+   * Pending envelope with a message to be transmitted to the
+   * service as soon as we are allowed to.  Should only be
+   * non-NULL if @e allow_send is 0.
+   */
+  struct GNUNET_MQ_Envelope *pending_env;
+
+  /**
+   * Window change handler.
+   */
+  GNUNET_CADET_WindowSizeEventHandler window_changes;
+
+  /**
+   * Disconnect handler.
+   */
+  GNUNET_CADET_DisconnectEventHandler disconnects;
+
+  /**
+   * Local ID of the channel, #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI bit is set if outbound.
+   */
+  struct GNUNET_CADET_ClientChannelNumber ccn;
+
+  /**
+   * How many messages are we allowed to send to the service right now?
+   */
+  unsigned int allow_send;
+};
 
 /**
  * Message for a client to create and destroy channels.
@@ -252,7 +315,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.
  */
index 3a75266b73e6fd0c2a7bf667b51b4ca0258ab71c..45cb66c1df450a047125c346ac6ca6c86ab05641 100644 (file)
@@ -73,72 +73,6 @@ struct GNUNET_CADET_Handle
   struct GNUNET_TIME_Relative reconnect_time;
 };
 
-
-/**
- * Opaque handle to a channel.
- */
-struct GNUNET_CADET_Channel
-{
-  /**
-   * Other end of the channel.
-   */
-  struct GNUNET_PeerIdentity peer;
-
-  /**
-   * Handle to the cadet this channel belongs to
-   */
-  struct GNUNET_CADET_Handle *cadet;
-
-  /**
-   * Channel's port, if incoming.
-   */
-  struct GNUNET_CADET_Port *incoming_port;
-
-  /**
-   * Any data the caller wants to put in here, used for the
-   * various callbacks (@e disconnects, @e window_changes, handlers).
-   */
-  void *ctx;
-
-  /**
-   * Message Queue for the channel (which we are implementing).
-   */
-  struct GNUNET_MQ_Handle *mq;
-
-  /**
-   * Task to allow mq to send more traffic.
-   */
-  struct GNUNET_SCHEDULER_Task *mq_cont;
-
-  /**
-   * Pending envelope with a message to be transmitted to the
-   * service as soon as we are allowed to.  Should only be
-   * non-NULL if @e allow_send is 0.
-   */
-  struct GNUNET_MQ_Envelope *pending_env;
-
-  /**
-   * Window change handler.
-   */
-  GNUNET_CADET_WindowSizeEventHandler window_changes;
-
-  /**
-   * Disconnect handler.
-   */
-  GNUNET_CADET_DisconnectEventHandler disconnects;
-
-  /**
-   * Local ID of the channel, #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI bit is set if outbound.
-   */
-  struct GNUNET_CADET_ClientChannelNumber ccn;
-
-  /**
-   * How many messages are we allowed to send to the service right now?
-   */
-  unsigned int allow_send;
-};
-
-
 /**
  * Opaque handle to a port.
  */
index e3417f8c4e75492425ccf912b26673897e68f686..08298e2240c4f06e0b3bb669d908ec5b5bf9599d 100644 (file)
@@ -84,6 +84,24 @@ struct GNUNET_CADET_ConnectionCreateMessage
    */
   uint32_t options GNUNET_PACKED;
 
+  /**
+   * This flag indicates the peer sending the connection create 
+   * meassage likes to trigger a KX handshake.
+   */
+  int has_monotime;
+  
+  /**
+   *  This monotonic time is set, if a peer likes to trigger a KX, but is not
+   *  the peer that should start the KX. (xrs,t3ss)
+   */
+  struct GNUNET_TIME_AbsoluteNBO monotime;
+
+  /**
+   *  We sign the monotime. The receiving peer can check the signature, to verify
+   *  the sending peer.
+   */
+  struct GNUNET_CRYPTO_EddsaSignature monotime_sig;
+
   /**
    * ID of the connection
    */
index ba83fe0fc8b1c1abf3e7b08aa4fcefcc26295199..03af3d5c0d5946b237d83819cecc1e9ac66e3860 100644 (file)
@@ -580,6 +580,7 @@ handle_channel_create (void *cls,
   if (ntohl (tcm->ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
   {
     /* Channel ID not in allowed range. */
+    LOG (GNUNET_ERROR_TYPE_DEBUG,"Channel ID not in allowed range.");
     GNUNET_break (0);
     GNUNET_SERVICE_client_drop (c->client);
     return;
@@ -589,6 +590,7 @@ handle_channel_create (void *cls,
   if (NULL != ch)
   {
     /* Channel ID already in use. Not allowed. */
+    LOG (GNUNET_ERROR_TYPE_DEBUG,"Channel ID already in use. Not allowed.");
     GNUNET_break (0);
     GNUNET_SERVICE_client_drop (c->client);
     return;
@@ -1008,6 +1010,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.
@@ -1305,48 +1327,52 @@ run (void *cls,
  * Define "main" method using service macro.
  */
 GNUNET_SERVICE_MAIN
-  ("cadet",
-  GNUNET_SERVICE_OPTION_NONE,
-  &run,
-  &client_connect_cb,
-  &client_disconnect_cb,
-  NULL,
-  GNUNET_MQ_hd_fixed_size (port_open,
-                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
-                           struct GNUNET_CADET_PortMessage,
-                           NULL),
-  GNUNET_MQ_hd_fixed_size (port_close,
-                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
-                           struct GNUNET_CADET_PortMessage,
-                           NULL),
-  GNUNET_MQ_hd_fixed_size (channel_create,
-                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
-                           struct GNUNET_CADET_LocalChannelCreateMessage,
-                           NULL),
-  GNUNET_MQ_hd_fixed_size (channel_destroy,
-                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
-                           struct GNUNET_CADET_LocalChannelDestroyMessage,
-                           NULL),
-  GNUNET_MQ_hd_var_size (local_data,
-                         GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
-                         struct GNUNET_CADET_LocalData,
-                         NULL),
-  GNUNET_MQ_hd_fixed_size (local_ack,
-                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
-                           struct GNUNET_CADET_LocalAck,
-                           NULL),
-  GNUNET_MQ_hd_fixed_size (get_peers,
-                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PEERS,
-                           struct GNUNET_MessageHeader,
-                           NULL),
-  GNUNET_MQ_hd_fixed_size (show_path,
-                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH,
-                           struct GNUNET_CADET_RequestPathInfoMessage,
-                           NULL),
-  GNUNET_MQ_hd_fixed_size (info_tunnels,
-                           GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_TUNNELS,
-                           struct GNUNET_MessageHeader,
-                           NULL),
-  GNUNET_MQ_handler_end ());
+("cadet",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ GNUNET_MQ_hd_fixed_size (port_open,
+                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
+                          struct GNUNET_CADET_PortMessage,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (port_close,
+                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
+                          struct GNUNET_CADET_PortMessage,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (channel_create,
+                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
+                          struct GNUNET_CADET_LocalChannelCreateMessage,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (channel_destroy,
+                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
+                          struct GNUNET_CADET_LocalChannelDestroyMessage,
+                          NULL),
+ GNUNET_MQ_hd_var_size (local_data,
+                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
+                        struct GNUNET_CADET_LocalData,
+                        NULL),
+ GNUNET_MQ_hd_fixed_size (local_ack,
+                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
+                          struct GNUNET_CADET_LocalAck,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (get_peers,
+                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PEERS,
+                          struct GNUNET_MessageHeader,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (show_path,
+                          GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH,
+                          struct GNUNET_CADET_RequestPathInfoMessage,
+                          NULL),
+ GNUNET_MQ_hd_fixed_size (info_tunnels,
+                          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 6da0950f1e313dca81273e7597095d1cd47a3ed6..ff216f8c3045caa7633ac4870bf245b87a0ba703 100644 (file)
@@ -325,4 +325,5 @@ const char *
 GSC_2s (struct CadetClient *c);
 
 
+
 #endif
index 5c8103c5e76c9d4d5d893e90869f9f2823ce8017..e6fce562f80639d341ebba13b04679a3cbb30f3e 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;
+  
 };
 
+/**
+ * Assign type of message 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);
 }
 
 
@@ -1477,7 +1513,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);
 }
 
@@ -1865,7 +1901,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 0a6c973294df543afd85708ed9ee3ff08eadb43f..7a072f128a425531267f2f43b4d706a08099439a 100644 (file)
@@ -57,6 +57,23 @@ 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 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);
+
+/**
+ * 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);
 
 /**
  * Get the static string for identification of the channel.
index c07339ebca807703c1bf48bb710418f1ef944330..1dac9eb1ead30d1e1b3c18da850b24b35e8c87aa 100644 (file)
@@ -26,6 +26,7 @@
  * @author Christian Grothoff
  */
 #include "platform.h"
+#include "gnunet_signatures.h"
 #include "gnunet-service-cadet_connection.h"
 #include "gnunet-service-cadet_channel.h"
 #include "gnunet-service-cadet_paths.h"
@@ -78,7 +79,6 @@ enum CadetConnectionState
   CADET_CONNECTION_READY
 };
 
-
 /**
  * Low-level connection to a destination.
  */
@@ -206,6 +206,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 =
@@ -214,6 +222,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);
 }
@@ -392,7 +407,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);
 }
 
 
@@ -580,6 +595,20 @@ GCC_handle_encrypted (struct CadetConnection *cc,
 }
 
 
+void
+set_monotime_sig (struct GNUNET_CADET_ConnectionCreateMessage *msg)
+{
+
+  struct CadetConnectionCreatePS cp = { .purpose.purpose = htonl (
+                                          GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR),
+                                        .purpose.size = htonl (sizeof(cp)),
+                                        .monotonic_time = msg->monotime};
+
+  GNUNET_CRYPTO_eddsa_sign (my_private_key, &cp,
+                            &msg->monotime_sig);
+
+}
+
 /**
  * Send a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE message to the
  * first hop.
@@ -593,6 +622,7 @@ send_create (void *cls)
   struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
   struct GNUNET_PeerIdentity *pids;
   struct GNUNET_MQ_Envelope *env;
+  struct CadetTunnel *t;
 
   cc->task = NULL;
   GNUNET_assert (GNUNET_YES == cc->mqm_ready);
@@ -603,6 +633,18 @@ send_create (void *cls)
   // TODO This will be removed in a major release, because this will be a protocol breaking change. We set the deprecated 'reliable' bit here that was removed.
   create_msg->options = 2;
   create_msg->cid = cc->cid;
+
+  // check for tunnel state and set signed monotime (xrs,t3ss)
+  t = GCP_get_tunnel (cc->destination, GNUNET_YES);
+  if ((NULL != t)&& (GCT_get_estate (t) == CADET_TUNNEL_KEY_UNINITIALIZED) &&
+      (GCT_alice_or_betty (GCP_get_id (cc->destination)) == GNUNET_NO))
+  {
+    create_msg->has_monotime = GNUNET_YES;
+    create_msg->monotime = GNUNET_TIME_absolute_hton (
+      GNUNET_TIME_absolute_get_monotonic (cfg));
+    set_monotime_sig (create_msg);
+  }
+
   pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
   pids[0] = my_full_id;
   for (unsigned int i = 0; i <= cc->off; i++)
@@ -792,6 +834,7 @@ connection_create (struct CadetPeer *destination,
   cc = GNUNET_new (struct CadetConnection);
   cc->state = init_state;
   cc->ct = ct;
+  cc->destination = destination; /* xrs,t3ss,lurchi*/
   cc->cid = *cid;
   cc->retry_delay =
     GNUNET_TIME_relative_multiply (INITIAL_CONNECTION_CREATE_RETRY_DELAY, off);
index b05c3b72c5cc5fb161c94f2e11253775544a84fe..a9ebef5677929171770b21442d7c449d9ac18971 100644 (file)
@@ -182,7 +182,29 @@ void
 GCC_handle_kx_auth (struct CadetConnection *cc,
                     const struct
                     GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg);
+struct CadetConnectionCreatePS
+{
+
+  /**
+   * Purpose is #GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
 
+  /**
+   * Time at the initiator when generating the signature.
+   *
+   * Note that the receiver MUST IGNORE the absolute time, and only interpret
+   * the value as a mononic time and reject "older" values than the last one
+   * observed.  This is necessary as we do not want to require synchronized
+   * clocks and may not have a bidirectional communication channel.
+   *
+   * Even with this, there is no real guarantee against replay achieved here,
+   * unless the latest timestamp is persisted.  Persistence should be
+   * provided via PEERSTORE if possible.
+   */
+  struct GNUNET_TIME_AbsoluteNBO monotonic_time;
+
+};
 
 /**
  * Performance metrics for a connection.
index d540228968453c32b2877ff4afce6ee9f6cc847d..04847f906a3f077efdbb852715683448adb43768 100644 (file)
@@ -227,7 +227,6 @@ static unsigned long long cur_buffers;
  */
 static struct GNUNET_SCHEDULER_Task *timeout_task;
 
-
 /**
  * Get the route corresponding to a hash.
  *
@@ -724,6 +723,7 @@ handle_connection_create (
   uint16_t size = ntohs (msg->header.size) - sizeof(*msg);
   unsigned int path_length;
   unsigned int off;
+  struct CadetTunnel *t;
 
   path_length = size / sizeof(struct GNUNET_PeerIdentity);
   if (0 == path_length)
@@ -822,8 +822,19 @@ handle_connection_create (
          GCP_2s (origin),
          GNUNET_sh2s (&msg->cid.connection_of_tunnel));
     path = GCPP_get_path_from_route (path_length - 1, pids);
+    t = GCP_get_tunnel (sender, GNUNET_YES);
+
+    // Check for CADET state in case the other side has lost the tunnel (xrs,t3ss)
+    if ((GNUNET_YES == msg->has_monotime) &&
+        (GNUNET_YES == GCP_check_and_update_monotime(origin, msg->monotime)) &&
+        ( GNUNET_OK == GCP_check_monotime_sig(origin, msg)) &&
+         (CADET_TUNNEL_KEY_OK == GCT_get_estate(t)))
+    {
+      GCT_change_estate (t, CADET_TUNNEL_KEY_UNINITIALIZED);
+    }
+
     if (GNUNET_OK !=
-        GCT_add_inbound_connection (GCP_get_tunnel (origin, GNUNET_YES),
+        GCT_add_inbound_connection (t,
                                     &msg->cid,
                                     path))
     {
index 8258881d0ed3a3d6acf0071bda8927be9e360da7..0ff4d1fb8950a5c8bda2651e2222017d553dda87 100644 (file)
@@ -31,6 +31,7 @@
  *   to take a break if we have some connections and have searched a lot (?))
  */
 #include "platform.h"
+#include "gnunet_time_lib.h"
 #include "gnunet_util_lib.h"
 #include "gnunet_hello_lib.h"
 #include "gnunet_signatures.h"
 #include "gnunet_ats_service.h"
 #include "gnunet_core_service.h"
 #include "gnunet_statistics_service.h"
-#include "cadet_protocol.h"
+#include "gnunet-service-cadet_peer.h"
+#include "gnunet-service-cadet.h"
 #include "gnunet-service-cadet_connection.h"
 #include "gnunet-service-cadet_dht.h"
-#include "gnunet-service-cadet_peer.h"
 #include "gnunet-service-cadet_paths.h"
 #include "gnunet-service-cadet_tunnels.h"
 
@@ -66,7 +67,6 @@
  */
 #define MAX_OOO_QUEUE_SIZE  100
 
-
 /**
  * Data structure used to track whom we have to notify about changes
  * to our message queue.
@@ -118,7 +118,7 @@ struct CadetPeer
   /**
    * Last time we heard from this peer (currently not used!)
    */
-  struct GNUNET_TIME_Absolute last_contactXXX;
+  struct GNUNET_TIME_Absolute last_connection_create;
 
   /**
    * Array of DLLs of paths traversing the peer, organized by the
@@ -1552,5 +1552,60 @@ GCP_send_ooo (struct CadetPeer *cp,
                   env);
 }
 
+/*
+ * FIXME: comment
+ */
+void
+GCP_update_monotime (struct CadetPeer *peer)
+{
+  peer->last_connection_create = GNUNET_TIME_absolute_get_monotonic (cfg);
+}
+
+/*
+ * FIXME: comment
+ */
+int
+GCP_check_and_update_monotime (struct CadetPeer *peer,
+                               struct GNUNET_TIME_AbsoluteNBO monotime)
+{
+
+  struct GNUNET_TIME_Absolute mt = GNUNET_TIME_absolute_ntoh (monotime);
+
+  if (mt.abs_value_us > *(&peer->last_connection_create.abs_value_us))
+  {
+    peer->last_connection_create = mt;
+    return GNUNET_YES;
+  }
+  return GNUNET_NO;
+}
+
+/*
+ * FIXME: documentation here
+ */
+int
+GCP_check_monotime_sig (struct CadetPeer *peer, const struct
+                        GNUNET_CADET_ConnectionCreateMessage *msg)
+{
+  // struct CadetPeer *peer;
+  // const struct GNUNET_CADET_ConnectionCreateMessage *msg;
+
+  struct CadetConnectionCreatePS cp = { .purpose.purpose = htonl (
+                                          GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR),
+                                        .purpose.size = htonl (sizeof(cp)),
+                                        .monotonic_time = msg->monotime};
+
+  if (GNUNET_OK !=
+      GNUNET_CRYPTO_eddsa_verify (
+        GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR,
+        &cp,
+        &msg->monotime_sig,
+        &peer->pid.public_key))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
 
 /* end of gnunet-service-cadet-new_peer.c */
index bec0606a01a08fbb1b4b0009d9ca1ddd3b2e6734..31bd23121fc9a6502897d28cc748a3a33429fdc2 100644 (file)
@@ -402,5 +402,14 @@ void
 GCP_set_mq (struct CadetPeer *cp,
             struct GNUNET_MQ_Handle *mq);
 
+int
+GCP_check_monotime_sig (struct CadetPeer *peer, const struct GNUNET_CADET_ConnectionCreateMessage *msg);
+
+void 
+GCP_update_monotime (struct CadetPeer *cp);
+
+int 
+GCP_check_and_update_monotime (struct CadetPeer *peer,
+                               struct GNUNET_TIME_AbsoluteNBO monotime);
 
 #endif
index f1f2ec81f32fb3b448602fe0090291f4beaa221d..66e7d5b1eda44a2bed1c08b5f353c14abd7c6781 100644 (file)
@@ -464,8 +464,8 @@ struct CadetTunnel
  * @param other the other peer
  * @return #GNUNET_YES for Alice, #GNUNET_NO for Betty, #GNUNET_SYSERR if talking to myself
  */
-static int
-alice_or_betty (const struct GNUNET_PeerIdentity *other)
+int
+GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other)
 {
   if (0 > GNUNET_memcmp (&my_full_id,
                          other))
@@ -1345,7 +1345,7 @@ send_kx (struct CadetTunnel *t,
   struct GNUNET_CADET_TunnelKeyExchangeMessage *msg;
   enum GNUNET_CADET_KX_Flags flags;
 
-  if (GNUNET_YES != alice_or_betty (GCP_get_id (t->destination)))
+  if (GNUNET_YES != GCT_alice_or_betty (GCP_get_id (t->destination)))
     return; /* only Alice may send KX */
   if ((NULL == ct) ||
       (GNUNET_NO == ct->is_ready))
@@ -1521,7 +1521,7 @@ update_ax_by_kx (struct CadetTunnelAxolotl *ax,
   const char salt[] = "CADET Axolotl salt";
   int am_I_alice;
 
-  if (GNUNET_SYSERR == (am_I_alice = alice_or_betty (pid)))
+  if (GNUNET_SYSERR == (am_I_alice = GCT_alice_or_betty (pid)))
   {
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
@@ -1726,7 +1726,7 @@ GCT_handle_kx (struct CadetTConnection *ct,
                             1,
                             GNUNET_NO);
   if (GNUNET_YES ==
-      alice_or_betty (GCP_get_id (t->destination)))
+      GCT_alice_or_betty (GCP_get_id (t->destination)))
   {
     /* Betty/Bob is not allowed to send KX! */
     GNUNET_break_op (0);
@@ -2123,9 +2123,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:
@@ -2429,12 +2430,21 @@ 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);
@@ -3028,7 +3038,8 @@ GCT_send_channel_destroy (struct CadetTunnel *t,
   GCT_send (t,
             &msg.header,
             NULL,
-            NULL);
+            NULL,
+            &ctn);
 }
 
 
@@ -3445,18 +3456,32 @@ GCT_handle_encrypted (struct CadetTConnection *ct,
  * @param t Tunnel on which this message is transmitted.
  * @param cont Continuation to call once message is really sent.
  * @param cont_cls Closure for @c cont.
+ * @param The ID of the channel we are using for sending.
  * @return Handle to cancel message
  */
 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 ((NULL != ch)&& GCCH_is_type_to_drop (ch, message))
+    {
+      GNUNET_break (0);
+      return NULL;
+    }
+  }
 
   if (CADET_TUNNEL_KEY_OK != t->estate)
   {
index ef07badea2a801115716804fcab45fe77121c15b..147f2e56f13eab232f35e6a6960e566b3f825757 100644 (file)
@@ -80,6 +80,14 @@ enum CadetTunnelEState
   CADET_TUNNEL_KEY_OK
 };
 
+/**
+ * Am I Alice or Betty (some call her Bob), or talking to myself?
+ *
+ * @param other the other peer
+ * @return #GNUNET_YES for Alice, #GNUNET_NO for Betty, #GNUNET_SYSERR if talking to myself
+ */
+int
+GCT_alice_or_betty (const struct GNUNET_PeerIdentity *other);
 
 /**
  * Get the static string for the peer this tunnel is directed.
@@ -226,7 +234,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);
 
 
 /**
@@ -320,6 +329,16 @@ GCT_iterate_channels (struct CadetTunnel *t,
 enum CadetTunnelEState
 GCT_get_estate (struct CadetTunnel *t);
 
+/**
+ * Change the tunnel encryption state.
+ * If the encryption state changes to OK, stop the rekey task.
+ *
+ * @param t Tunnel whose encryption state to change, or NULL.
+ * @param state New encryption state.
+ */
+void
+GCT_change_estate (struct CadetTunnel *t,
+                   enum CadetTunnelEState state);
 
 /**
  * Handle KX message.
index 25713709c96add2f3274980f768450a38b707b09..779d3bc9f1114911632e900ca4f6c24913b31f76 100644 (file)
@@ -25,6 +25,7 @@
  */
 #include <stdio.h>
 #include "platform.h"
+#include "cadet.h"
 #include "cadet_test_lib.h"
 #include "gnunet_cadet_service.h"
 #include "gnunet_statistics_service.h"
@@ -74,6 +75,17 @@ struct CadetTestChannelWrapper
 #define SPEED_REL 8
 #define P2P_SIGNAL 10
 #define REOPEN 11
+#define DESTROY 12
+
+/**
+ * Active peer listing operation.
+ */
+static struct GNUNET_CADET_PeersLister *plo;
+
+/*
+ * Task called to check for existing tunnel and depending on that reopen channel
+ */
+static struct GNUNET_SCHEDULER_Task *get_peers_task;
 
 /**
  * Which test are we running?
@@ -123,7 +135,12 @@ static struct GNUNET_TESTBED_Operation *t_op[2];
 /**
  * Peer ids.
  */
-static struct GNUNET_PeerIdentity *p_id[2];
+static struct GNUNET_PeerIdentity *testpeer_id[2];
+
+/**
+ * Peer ids.
+ */
+static struct GNUNET_CONFIGURATION_Handle *p_cfg[2];
 
 /**
  * Port ID
@@ -133,7 +150,7 @@ static struct GNUNET_HashCode port;
 /**
  * Peer ids counter.
  */
-static unsigned int p_ids;
+static unsigned int peerinfo_task_cnt;
 
 /**
  * Is the setup initialized?
@@ -195,16 +212,6 @@ static struct GNUNET_SCHEDULER_Task *test_task;
  */
 static struct GNUNET_SCHEDULER_Task *send_next_msg_task;
 
-/**
- * Cadet handle for the root peer
- */
-static struct GNUNET_CADET_Handle *h1;
-
-/**
- * Cadet handle for the first leaf peer
- */
-static struct GNUNET_CADET_Handle *h2;
-
 /**
  * Channel handle for the root peer
  */
@@ -226,6 +233,9 @@ static struct GNUNET_TIME_Absolute start_time;
  */
 static struct GNUNET_TESTBED_Peer **testbed_peers;
 
+
+struct GNUNET_CADET_Handle **cadets_running;
+
 /**
  * Statistics operation handle.
  */
@@ -246,6 +256,17 @@ static unsigned int ka_received;
  */
 static unsigned int msg_dropped;
 
+/**
+ * Drop the next cadet message of a given type..
+ *
+ * @param mq message queue
+ * @param ccn client channel number.
+ * @param type of cadet message to be dropped.
+ */
+void
+GNUNET_CADET_drop_message (struct GNUNET_MQ_Handle *mq,
+                           struct GNUNET_CADET_ClientChannelNumber ccn,
+                           uint16_t type);
 
 /******************************************************************************/
 
@@ -516,6 +537,49 @@ static void
 disconnect_handler (void *cls,
                     const struct GNUNET_CADET_Channel *channel);
 
+static struct GNUNET_PeerIdentity *
+get_from_p_ids ()
+{
+  if (0 < GNUNET_memcmp (testpeer_id[0], testpeer_id[1]))
+  {
+    return testpeer_id[1];
+  }
+  else
+  {
+    return testpeer_id[0];
+  }
+}
+
+static struct GNUNET_CADET_Handle *
+get_from_cadets ()
+{
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "1\n");
+  if (0 < GNUNET_memcmp (testpeer_id[0], testpeer_id[1]))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "standard peer\n");
+    return cadets_running[0];
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "the other peer\n");
+    return cadets_running[peers_running - 1];
+  }
+
+}
+
+static unsigned int
+get_peer_nr (int outgoing)
+{
+  if (0 < GNUNET_memcmp (testpeer_id[0], testpeer_id[1]))
+  {
+    return GNUNET_YES == outgoing ? 0 : peers_running - 1;
+  }
+  else
+  {
+    return GNUNET_YES == outgoing ? peers_running - 1 : 0;
+  }
+}
 
 /**
  * Task to reconnect to other peer.
@@ -534,6 +598,8 @@ reconnect_op (void *cls)
   };
   long l = (long) cls;
   struct CadetTestChannelWrapper *ch;
+  static struct GNUNET_PeerIdentity *p_id;
+  static struct GNUNET_CADET_Handle *h1;
 
   reconnect_task = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -544,18 +610,128 @@ reconnect_op (void *cls)
     GNUNET_CADET_channel_destroy (outgoing_ch);
     outgoing_ch = NULL;
   }
+  ch = GNUNET_new (struct CadetTestChannelWrapper);
+
+  p_id = get_from_p_ids ();
+  h1 = get_from_cadets ();
+
+  outgoing_ch = GNUNET_CADET_channel_create (h1,
+                                             ch,
+                                             p_id,
+                                             &port,
+                                             NULL,
+                                             &disconnect_handler,
+                                             handlers);
+  ch->ch = outgoing_ch;
+  send_test_message (outgoing_ch);
+}
+
+void
+reopen_channel ()
+{
+  struct CadetTestChannelWrapper *ch;
+  static struct GNUNET_CADET_Handle *h1;
+  static struct GNUNET_PeerIdentity *p_id;
+  struct GNUNET_MQ_MessageHandler handlers[] = {
+    GNUNET_MQ_hd_var_size (data,
+                           GNUNET_MESSAGE_TYPE_DUMMY,
+                           struct GNUNET_MessageHeader,
+                           NULL),
+    GNUNET_MQ_handler_end ()
+  };
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "creating channel again\n");
+  p_id = get_from_p_ids ();
+  h1 = get_from_cadets ();
+
   ch = GNUNET_new (struct CadetTestChannelWrapper);
   outgoing_ch = GNUNET_CADET_channel_create (h1,
                                              ch,
-                                             p_id[1],
+                                             p_id,
                                              &port,
                                              NULL,
                                              &disconnect_handler,
                                              handlers);
   ch->ch = outgoing_ch;
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Sending second test data (after destroying the channel) on channel %p...\n",
+              outgoing_ch);
   send_test_message (outgoing_ch);
 }
 
+static void
+peers_callback (void *cls, const struct GNUNET_CADET_PeerListEntry *ple);
+
+/**
+ * We ask the monitoring api for all the peers.
+ */
+static void
+get_peers (void *cls)
+{
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "requesting peers info!\n");
+  plo = GNUNET_CADET_list_peers (p_cfg[get_peer_nr (GNUNET_YES)],
+                                 &peers_callback, NULL);
+
+}
+
+/**
+ * Method called to retrieve information about all peers in CADET, called
+ * once per peer.
+ *
+ * After last peer has been reported, an additional call with NULL is done.
+ *
+ * We check the peer we are interested in, if we have a tunnel. If not, we
+ * reopen the channel
+ *
+ * @param cls Closure.
+ * @param ple information about peer, or NULL on "EOF".
+ */
+static void
+peers_callback (void *cls, const struct GNUNET_CADET_PeerListEntry *ple)
+{
+
+  const struct GNUNET_PeerIdentity *p_id;
+  const struct GNUNET_PeerIdentity *peer;
+
+
+  peer = &ple->peer;
+
+  if (NULL == ple)
+  {
+    plo = NULL;
+    return;
+  }
+  p_id = get_from_p_ids ();
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "ple->peer %s\n",
+              GNUNET_i2s_full (&ple->peer));
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "p_id %s\n",
+              GNUNET_i2s_full (p_id));
+
+  if ((0 == GNUNET_memcmp (&ple->peer, p_id))&& ple->have_tunnel)
+  {
+
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "schedule get_peers again?\n");
+    get_peers_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
+                                                   &get_peers,
+                                                   NULL);
+
+  }
+  else if (0 == GNUNET_memcmp (&ple->peer, p_id) )
+  {
+
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "reopen channel\n");
+
+    reopen_channel ();
+
+  }
+}
 
 /**
  * Function called whenever an MQ-channel is destroyed, unless the destruction
@@ -575,9 +751,22 @@ disconnect_handler (void *cls,
   struct CadetTestChannelWrapper *ch_w = cls;
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Channel disconnected at %d\n",
+              "Channel disconnected at ok=%d\n",
               ok);
   GNUNET_assert (ch_w->ch == channel);
+
+  if ((DESTROY == test) && (3 == ok))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Reopen channel task!\n");
+    if (NULL == get_peers_task)
+    {
+      get_peers_task = GNUNET_SCHEDULER_add_now (&get_peers,
+                                                 NULL);
+    }
+    return;
+  }
+
   if (channel == incoming_ch)
   {
     ok++;
@@ -651,8 +840,8 @@ send_test_message (struct GNUNET_CADET_Channel *channel)
   int size;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Sending test message on channel %p\n",
-              channel);
+              "Sending test message on channel %u\n",
+              channel->ccn.channel_of_client);
   size = size_payload;
   if (GNUNET_NO == initialized)
   {
@@ -699,6 +888,10 @@ send_test_message (struct GNUNET_CADET_Channel *channel)
                 "Sending DATA %u [%d bytes]\n",
                 data_sent, size);
   }
+  else if (DESTROY == test)
+  {
+    payload = data_sent;
+  }
   else
   {
     GNUNET_assert (0);
@@ -826,7 +1019,7 @@ handle_data (void *cls,
   }
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              " ok: (%d/%d)\n",
+              "handle_data ok: (%d/%d)\n",
               ok,
               ok_goal);
   data = (uint32_t *) &message[1];
@@ -844,6 +1037,49 @@ handle_data (void *cls,
                 payload, *counter);
   }
 
+  if (DESTROY == test)
+  {
+    if (2 == ok)
+    {
+      ok++;
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "dropping message ok: (%d/%d)\n",
+                  ok,
+                  ok_goal);
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "TEST ID 0: %s\n",
+                  GNUNET_i2s (testpeer_id[0]));
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "TEST ID 1: %s\n",
+                  GNUNET_i2s (testpeer_id[1]));
+
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO, "dropping message\n");
+      GNUNET_CADET_drop_message (GNUNET_CADET_get_mq (outgoing_ch),
+                                 outgoing_ch->ccn,
+                                 GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY);
+      if (NULL != outgoing_ch)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                    "Destroying channel %p...\n",
+                    outgoing_ch);
+        GNUNET_CADET_channel_destroy (outgoing_ch);
+        outgoing_ch = NULL;
+      }
+    }
+    else if (5 == ok)
+    {
+      ok++;
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "destroy test finished ok: (%d/%d)\n",
+                  ok,
+                  ok_goal);
+      disconnect_task =
+        GNUNET_SCHEDULER_add_now (&gather_stats_and_exit,
+                                  (void *) __LINE__);
+      // End of DESTROY test.
+    }
+  }
+
   if (GNUNET_NO == initialized)
   {
     initialized = GNUNET_YES;
@@ -861,7 +1097,7 @@ handle_data (void *cls,
   if (get_target_channel () == channel)  /* Got "data" */
   {
     GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received data %u\n", data_received);
-    if ((SPEED != test) || ( (ok_goal - 2) == ok) )
+    if ((DESTROY != test) && ((SPEED != test) || ( (ok_goal - 2) == ok)) )
     {
       /* Send ACK */
       send_test_message (channel);
@@ -927,11 +1163,13 @@ connect_handler (void *cls,
               channel);
   ok++;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              " ok: %d\n",
-              ok);
-  if (peer == peers_requested - 1)
+              "connect_handler ok: (%d/%d)\n",
+              ok,
+              ok_goal);
+
+  if (peer == get_peer_nr (GNUNET_NO))
   {
-    if (NULL != incoming_ch)
+    if ((DESTROY != test)&&(NULL != incoming_ch))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "Duplicate incoming channel for client %lu\n",
@@ -947,7 +1185,7 @@ connect_handler (void *cls,
                 (long) cls);
     GNUNET_assert (0);
   }
-  if ((NULL != disconnect_task) && (REOPEN != test))
+  if ((NULL != disconnect_task) && (REOPEN != test) && (DESTROY != test))
   {
     GNUNET_SCHEDULER_cancel (disconnect_task);
     disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
@@ -971,6 +1209,7 @@ connect_handler (void *cls,
                                                    (void *) __LINE__);
   }
 
+
   /* TODO: cannot return channel as-is, in order to unify the data handlers */
   ch = GNUNET_new (struct CadetTestChannelWrapper);
   ch->ch = channel;
@@ -998,6 +1237,8 @@ start_test (void *cls)
     GNUNET_MQ_handler_end ()
   };
   struct CadetTestChannelWrapper *ch;
+  static struct GNUNET_CADET_Handle *h1;
+  static struct GNUNET_PeerIdentity *p_id;
 
   test_task = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "start_test: %s\n", test_name);
@@ -1012,20 +1253,25 @@ start_test (void *cls)
     test = SPEED;
   }
 
+  p_id = get_from_p_ids ();
+  h1 = get_from_cadets ();
+
   ch = GNUNET_new (struct CadetTestChannelWrapper);
   outgoing_ch = GNUNET_CADET_channel_create (h1,
                                              ch,
-                                             p_id[1],
+                                             p_id,
                                              &port,
                                              NULL,
                                              &disconnect_handler,
                                              handlers);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "channel created\n");
 
   ch->ch = outgoing_ch;
 
-  disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
-                                                  &gather_stats_and_exit,
-                                                  (void *) __LINE__);
+  if (DESTROY != test)
+    disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
+                                                    &gather_stats_and_exit,
+                                                    (void *) __LINE__);
   if (KEEPALIVE == test)
     return;                     /* Don't send any data. */
 
@@ -1054,7 +1300,7 @@ start_test (void *cls)
 /**
  * Callback to be called when the requested peer information is available
  *
- * @param cls the closure from GNUNET_TESTBED_peer_get_information()
+ * @param cls the closure from GNUNET_TESTBED_peer_getinformation()
  * @param op the operation this callback corresponds to
  * @param pinfo the result; will be NULL if the operation has failed
  * @param emsg error message if the operation has failed;
@@ -1068,9 +1314,6 @@ pi_cb (void *cls,
 {
   long i = (long) cls;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "ID callback for %ld\n",
-              i);
   if ((NULL == pinfo) ||
       (NULL != emsg))
   {
@@ -1080,15 +1323,40 @@ pi_cb (void *cls,
     abort_test (__LINE__);
     return;
   }
-  p_id[i] = pinfo->result.id;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "id: %s\n",
-              GNUNET_i2s (p_id[i]));
-  p_ids++;
-  if (p_ids < 2)
+
+  if (GNUNET_TESTBED_PIT_IDENTITY == pinfo->pit)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "ID callback for %ld\n",
+                i);
+    testpeer_id[i] = pinfo->result.id;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "id: %s\n",
+                GNUNET_i2s (testpeer_id[i]));
+  }
+  else if (GNUNET_TESTBED_PIT_CONFIGURATION == pinfo->pit)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "CFG callback for %ld\n",
+                i);
+    p_cfg[i] = pinfo->result.cfg;
+  }
+  else
+  {
+    GNUNET_break (0);
+  }
+
+  peerinfo_task_cnt++;
+  if (peerinfo_task_cnt < 4)
     return;
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Got all IDs, starting test\n");
+              "Got all peer information, starting test\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "TEST ID 0: %s\n",
+              GNUNET_i2s (testpeer_id[0]));
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "TEST ID 1: %s\n",
+              GNUNET_i2s (testpeer_id[1]));
   test_task = GNUNET_SCHEDULER_add_now (&start_test, NULL);
 }
 
@@ -1115,8 +1383,8 @@ tmain (void *cls,
   peers_running = num_peers;
   GNUNET_assert (peers_running == peers_requested);
   testbed_peers = peers;
-  h1 = cadets[0];
-  h2 = cadets[num_peers - 1];
+  cadets_running = cadets;
+
   disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
                                                   &disconnect_cadet_peers,
                                                   (void *) __LINE__);
@@ -1130,6 +1398,14 @@ tmain (void *cls,
                                                  GNUNET_TESTBED_PIT_IDENTITY,
                                                  &pi_cb,
                                                  (void *) 1L);
+  t_op[0] = GNUNET_TESTBED_peer_get_information (peers[0],
+                                                 GNUNET_TESTBED_PIT_CONFIGURATION,
+                                                 &pi_cb,
+                                                 (void *) 0L);
+  t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1],
+                                                 GNUNET_TESTBED_PIT_CONFIGURATION,
+                                                 &pi_cb,
+                                                 (void *) 1L);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "requested peer ids\n");
 }
 
@@ -1272,6 +1548,13 @@ main (int argc, char *argv[])
     // */
     ok_goal = 6;
   }
+  else if (strstr (argv[0], "_destroy") != NULL)
+  {
+    test = DESTROY;
+    test_name = "destroy";
+    ok_goal = 6;
+    short_time = GNUNET_TIME_relative_multiply (short_time, 5);
+  }
   else
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n");
@@ -1286,7 +1569,7 @@ main (int argc, char *argv[])
     GNUNET_asprintf (&test_name, "backwards %s", test_name);
   }
 
-  p_ids = 0;
+  peerinfo_task_cnt = 0;
   ports[0] = &port;
   ports[1] = NULL;
   GNUNET_CADET_TEST_ruN ("test_cadet_small",
index 30e496aff6854a78819698bbf1d65cfc90805c40..067dd5fb4f488cb08d46f7671e2a7b374a725297 100644 (file)
@@ -27,7 +27,8 @@ QUOTA = 1 MB
 DATABASE = heap
 
 [transport]
-PLUGINS = udp
+#PLUGINS = udp
+PLUGINS = tcp
 NEIGHBOUR_LIMIT = 50
 #MANIPULATE_DELAY_IN = 10 ms
 #MANIPULATE_DELAY_OUT = 10 ms
@@ -102,3 +103,7 @@ START_ON_DEMAND = NO
 [rps]
 IMMEDIATE_START = NO
 START_ON_DEMAND = NO
+
+[rest]
+IMMEDIATE_START = NO
+START_ON_DEMAND = NO
index a9cd7466a99166ccfba55d33d92f9a9d5ffd4309..0db6150aa469362ece6f8b9b574be03e904de390 100644 (file)
@@ -2734,9 +2734,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  ********************************/
@@ -2932,6 +2931,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  *******************************/
 
index a00e0372da18b480420698117ad54065d70b4898..5031137701498ffe405636eee9bd90703b4084c7 100644 (file)
@@ -241,6 +241,10 @@ extern "C"
  */
 #define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR 37
 
+/**
+ * Signature by a peer that like to create a connection.
+ */
+#define GNUNET_SIGNATURE_PURPOSE_CADET_CONNECTION_INITIATOR 38
 
 #if 0                           /* keep Emacsens' auto-indent happy */
 {