From 91e2293a4a7ca3bcb287ee0a5010a3524b035c56 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 30 Jan 2017 15:19:21 +0100 Subject: [PATCH] handle KX AUTH failure by retransmitting KX --- src/cadet/gnunet-service-cadet-new_channel.c | 52 ++++++++++++++++++- .../gnunet-service-cadet-new_connection.c | 16 ++++++ .../gnunet-service-cadet-new_connection.h | 18 ++++++- src/cadet/gnunet-service-cadet-new_tunnels.c | 5 +- 4 files changed, 87 insertions(+), 4 deletions(-) diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c index afce4680f..f6ef50caa 100644 --- a/src/cadet/gnunet-service-cadet-new_channel.c +++ b/src/cadet/gnunet-service-cadet-new_channel.c @@ -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 diff --git a/src/cadet/gnunet-service-cadet-new_connection.c b/src/cadet/gnunet-service-cadet-new_connection.c index 894ffdcb9..bf2aa6aee 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.c +++ b/src/cadet/gnunet-service-cadet-new_connection.c @@ -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. diff --git a/src/cadet/gnunet-service-cadet-new_connection.h b/src/cadet/gnunet-service-cadet-new_connection.h index 1302b0060..c42ec9c46 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.h +++ b/src/cadet/gnunet-service-cadet-new_connection.h @@ -21,7 +21,10 @@ /** * @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. * diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c index b5c15f590..3b5b4c6b5 100644 --- a/src/cadet/gnunet-service-cadet-new_tunnels.c +++ b/src/cadet/gnunet-service-cadet-new_tunnels.c @@ -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. */ -- 2.25.1