handle KX AUTH failure by retransmitting KX
authorChristian Grothoff <christian@grothoff.org>
Mon, 30 Jan 2017 14:19:21 +0000 (15:19 +0100)
committerChristian Grothoff <christian@grothoff.org>
Mon, 30 Jan 2017 14:19:21 +0000 (15:19 +0100)
src/cadet/gnunet-service-cadet-new_channel.c
src/cadet/gnunet-service-cadet-new_connection.c
src/cadet/gnunet-service-cadet-new_connection.h
src/cadet/gnunet-service-cadet-new_tunnels.c

index afce4680fee6d8ce612cbf05adaa30690658349f..f6ef50caa7067b017cf21321cf27e9191c6daa3e 100644 (file)
@@ -128,6 +128,11 @@ struct CadetReliableMessage
    */
   struct CadetTunnelQueueEntry *qe;
 
+  /**
+   * Data message we are trying to send.
+   */
+  struct GNUNET_CADET_ChannelAppDataMessage *data_message;
+
   /**
    * How soon should we retry if we fail to get an ACK?
    * Messages in the queue are sorted by this value.
@@ -141,9 +146,23 @@ struct CadetReliableMessage
   struct GNUNET_TIME_Relative retry_delay;
 
   /**
-   * Data message we are trying to send.
+   * Time when we first successfully transmitted the message
+   * (that is, set @e num_transmissions to 1).
    */
-  struct GNUNET_CADET_ChannelAppDataMessage *data_message;
+  struct GNUNET_TIME_Absolute first_transmission_time;
+
+  /**
+   * Identifier of the connection that this message took when it
+   * was first transmitted.  Only useful if @e num_transmissions is 1.
+   */
+  struct GNUNET_CADET_ConnectionTunnelIdentifier connection_taken;
+
+  /**
+   * How often was this message transmitted?  #GNUNET_SYSERR if there
+   * was an error transmitting the message, #GNUNET_NO if it was not
+   * yet transmitted ever, otherwise the number of (re) transmissions.
+   */
+  int num_transmissions;
 
 };
 
@@ -1374,10 +1393,12 @@ retry_transmission (void *cls)
  * the queue and tell our client that it can send more.
  *
  * @param ch the channel that got the PLAINTEXT_DATA_ACK
+ * @param cti identifier of the connection that delivered the message
  * @param crm the message that got acknowledged
  */
 static void
 handle_matching_ack (struct CadetChannel *ch,
+                     const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
                      struct CadetReliableMessage *crm)
 {
   GNUNET_CONTAINER_DLL_remove (ch->head_sent,
@@ -1395,6 +1416,15 @@ handle_matching_ack (struct CadetChannel *ch,
     GCT_send_cancel (crm->qe);
     crm->qe = NULL;
   }
+  if ( (1 == crm->num_transmissions) &&
+       (NULL != cti) &&
+       (0 == memcmp (cti,
+                     &crm->connection_taken,
+                     sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier))) )
+  {
+    GCC_latency_observed (cti,
+                          GNUNET_TIME_absolute_get_duration (crm->first_transmission_time));
+  }
   GNUNET_free (crm->data_message);
   GNUNET_free (crm);
   send_ack_to_client (ch,
@@ -1452,6 +1482,7 @@ GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
            ntohl (crm->data_message->mid.mid),
            GCCH_2s (ch));
       handle_matching_ack (ch,
+                           cti,
                            crm);
       found = GNUNET_YES;
       continue;
@@ -1471,6 +1502,7 @@ GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
            ntohl (crm->data_message->mid.mid),
            GCCH_2s (ch));
       handle_matching_ack (ch,
+                           cti,
                            crm);
       found = GNUNET_YES;
     }
@@ -1597,6 +1629,22 @@ data_sent_cb (void *cls,
                         : GNUNET_YES);
     return;
   }
+  if (NULL == cid)
+  {
+    /* There was an error sending. */
+    crm->num_transmissions = GNUNET_SYSERR;
+  }
+  else if (GNUNET_SYSERR != crm->num_transmissions)
+  {
+    /* Increment transmission counter, and possibly store @a cid
+       if this was the first transmission. */
+    crm->num_transmissions++;
+    if (1 == crm->num_transmissions)
+    {
+      crm->first_transmission_time = GNUNET_TIME_absolute_get ();
+      crm->connection_taken = *cid;
+    }
+  }
   if (0 == crm->retry_delay.rel_value_us)
     crm->retry_delay = ch->expected_delay;
   else
index 894ffdcb9f6f89b37b56b9c381fe7d7f6f9737a5..bf2aa6aee27c04294b520d1877faf4e6ecbd59db 100644 (file)
@@ -376,6 +376,22 @@ send_keepalive (void *cls)
 }
 
 
+/**
+ * We observed some the given @a latency on the connection
+ * identified by @a cti.  (The same connection was taken
+ * in both directions.)
+ *
+ * @param cti connection identifier where we measured latency
+ * @param latency the observed latency
+ */
+void
+GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
+                      struct GNUNET_TIME_Relative latency)
+{
+  GNUNET_break (0); // FIXME
+}
+
+
 /**
  * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for this connection, implying
  * that the end-to-end connection is up.  Process it.
index 1302b0060af127eb1a1c4807087a690b4e96a37d..c42ec9c46bcd1209abae9c4a8ab5676ca95878b2 100644 (file)
 
 /**
  * @file cadet/gnunet-service-cadet-new_connection.h
- * @brief
+ * @brief A connection is a live end-to-end messaging mechanism
+ *       where the peers are identified by a path and know how
+ *       to forward along the route using a connection identifier
+ *       for routing the data.
  * @author Bartlomiej Polot
  * @author Christian Grothoff
  */
@@ -184,6 +187,19 @@ GCC_handle_encrypted (struct CadetConnection *cc,
                       const struct GNUNET_CADET_TunnelEncryptedMessage *msg);
 
 
+/**
+ * We observed some the given @a latency on the connection
+ * identified by @a cti.  (The same connection was taken
+ * in both directions.)
+ *
+ * @param cti connection identifier where we measured latency
+ * @param latency the observed latency
+ */
+void
+GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti,
+                      struct GNUNET_TIME_Relative latency);
+
+
 /**
  * Return the tunnel associated with this connection.
  *
index b5c15f5907b5e70242fba50530e52baa340df1ce..3b5b4c6b50751bec25b75ff612491c9eb9aae2fd 100644 (file)
@@ -1816,8 +1816,11 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
                    sizeof (kx_auth)))
   {
     /* This KX_AUTH is not using the latest KX/KX_AUTH data
-       we transmitted to the sender, refuse it! */
+       we transmitted to the sender, refuse it, try KX again. */
     GNUNET_break_op (0);
+    send_kx (t,
+             NULL,
+             &t->ax);
     return;
   }
   /* Yep, we're good. */