aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet-new_connection.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-30 16:01:30 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-30 16:01:30 +0100
commit8b92d9a2c651d753f756aba5710b6d59ee0f24a1 (patch)
treef9375a03b2a99eea83ca157c42219453fbc217af /src/cadet/gnunet-service-cadet-new_connection.c
parent91e2293a4a7ca3bcb287ee0a5010a3524b035c56 (diff)
downloadgnunet-8b92d9a2c651d753f756aba5710b6d59ee0f24a1.tar.gz
gnunet-8b92d9a2c651d753f756aba5710b6d59ee0f24a1.zip
track and return performance metrics per cadet connection
Diffstat (limited to 'src/cadet/gnunet-service-cadet-new_connection.c')
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.c100
1 files changed, 92 insertions, 8 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_connection.c b/src/cadet/gnunet-service-cadet-new_connection.c
index bf2aa6aee..8536b638d 100644
--- a/src/cadet/gnunet-service-cadet-new_connection.c
+++ b/src/cadet/gnunet-service-cadet-new_connection.c
@@ -24,11 +24,6 @@
24 * end-to-end routes and transmits messages along the route 24 * end-to-end routes and transmits messages along the route
25 * @author Bartlomiej Polot 25 * @author Bartlomiej Polot
26 * @author Christian Grothoff 26 * @author Christian Grothoff
27 *
28 * TODO:
29 * - keep per-connection performance metrics
30 * - in particular, interact with channel (!) to see
31 * if we get ACKs indicating successful payload delivery.
32 */ 27 */
33#include "platform.h" 28#include "platform.h"
34#include "gnunet-service-cadet-new.h" 29#include "gnunet-service-cadet-new.h"
@@ -141,6 +136,11 @@ struct CadetConnection
141 struct GNUNET_TIME_Relative retry_delay; 136 struct GNUNET_TIME_Relative retry_delay;
142 137
143 /** 138 /**
139 * Performance metrics for this connection.
140 */
141 struct CadetConnectionMetrics metrics;
142
143 /**
144 * State of the connection. 144 * State of the connection.
145 */ 145 */
146 enum CadetConnectionState state; 146 enum CadetConnectionState state;
@@ -151,6 +151,11 @@ struct CadetConnection
151 enum GNUNET_CADET_ChannelOption options; 151 enum GNUNET_CADET_ChannelOption options;
152 152
153 /** 153 /**
154 * How many latency observations did we make for this connection?
155 */
156 unsigned int latency_datapoints;
157
158 /**
154 * Offset of our @e destination in @e path. 159 * Offset of our @e destination in @e path.
155 */ 160 */
156 unsigned int off; 161 unsigned int off;
@@ -301,6 +306,19 @@ GCC_get_ct (struct CadetConnection *cc)
301 306
302 307
303/** 308/**
309 * Obtain performance @a metrics from @a cc.
310 *
311 * @param cc connection to query
312 * @return the metrics
313 */
314const struct CadetConnectionMetrics *
315GCC_get_metrics (struct CadetConnection *cc)
316{
317 return &cc->metrics;
318}
319
320
321/**
304 * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the 322 * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
305 * tunnel to prevent it from timing out. 323 * tunnel to prevent it from timing out.
306 * 324 *
@@ -377,18 +395,80 @@ send_keepalive (void *cls)
377 395
378 396
379/** 397/**
398 * We sent a message for which we expect to receive an ACK via
399 * the connection identified by @a cti.
400 *
401 * @param cid connection identifier where we expect an ACK
402 */
403void
404GCC_ack_expected (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
405{
406 struct CadetConnection *cc;
407
408 cc = GNUNET_CONTAINER_multishortmap_get (connections,
409 &cid->connection_of_tunnel);
410 if (NULL == cc)
411 return; /* whopise, connection alredy down? */
412 cc->metrics.num_acked_transmissions++;
413}
414
415
416/**
417 * We observed an ACK for a message that was originally sent via
418 * the connection identified by @a cti.
419 *
420 * @param cti connection identifier where we got an ACK for a message
421 * that was originally sent via this connection (the ACK
422 * may have gotten back to us via a different connection).
423 */
424void
425GCC_ack_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid)
426{
427 struct CadetConnection *cc;
428
429 cc = GNUNET_CONTAINER_multishortmap_get (connections,
430 &cid->connection_of_tunnel);
431 if (NULL == cc)
432 return; /* whopise, connection alredy down? */
433 cc->metrics.num_successes++;
434}
435
436
437/**
380 * We observed some the given @a latency on the connection 438 * We observed some the given @a latency on the connection
381 * identified by @a cti. (The same connection was taken 439 * identified by @a cti. (The same connection was taken
382 * in both directions.) 440 * in both directions.)
383 * 441 *
384 * @param cti connection identifier where we measured latency 442 * @param cid connection identifier where we measured latency
385 * @param latency the observed latency 443 * @param latency the observed latency
386 */ 444 */
387void 445void
388GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, 446GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
389 struct GNUNET_TIME_Relative latency) 447 struct GNUNET_TIME_Relative latency)
390{ 448{
391 GNUNET_break (0); // FIXME 449 struct CadetConnection *cc;
450 double weight;
451 double result;
452
453 cc = GNUNET_CONTAINER_multishortmap_get (connections,
454 &cid->connection_of_tunnel);
455 if (NULL == cc)
456 return; /* whopise, connection alredy down? */
457 GNUNET_STATISTICS_update (stats,
458 "# latencies observed",
459 1,
460 GNUNET_NO);
461 cc->latency_datapoints++;
462 if (cc->latency_datapoints >= 7)
463 weight = 7.0;
464 else
465 weight = cc->latency_datapoints;
466 /* Compute weighted average, giving at MOST weight 7 to the
467 existing values, or less if that value is based on fewer than 7
468 measurements. */
469 result = (weight * cc->metrics.aged_latency.rel_value_us) + 1.0 * latency.rel_value_us;
470 result /= (weight + 1.0);
471 cc->metrics.aged_latency.rel_value_us = (uint64_t) result;
392} 472}
393 473
394 474
@@ -413,6 +493,7 @@ GCC_handle_connection_create_ack (struct CadetConnection *cc)
413 GNUNET_SCHEDULER_cancel (cc->task); 493 GNUNET_SCHEDULER_cancel (cc->task);
414 cc->task = NULL; 494 cc->task = NULL;
415 } 495 }
496 cc->metrics.age = GNUNET_TIME_absolute_get ();
416 update_state (cc, 497 update_state (cc,
417 CADET_CONNECTION_READY, 498 CADET_CONNECTION_READY,
418 cc->mqm_ready); 499 cc->mqm_ready);
@@ -492,6 +573,7 @@ GCC_handle_encrypted (struct CadetConnection *cc,
492 GCC_2s (cc)); 573 GCC_2s (cc));
493 GCC_handle_connection_create_ack (cc); 574 GCC_handle_connection_create_ack (cc);
494 } 575 }
576 cc->metrics.last_use = GNUNET_TIME_absolute_get ();
495 GCT_handle_encrypted (cc->ct, 577 GCT_handle_encrypted (cc->ct,
496 msg); 578 msg);
497} 579}
@@ -666,6 +748,7 @@ manage_first_hop_mq (void *cls,
666 break; 748 break;
667 case CADET_CONNECTION_CREATE_RECEIVED: 749 case CADET_CONNECTION_CREATE_RECEIVED:
668 /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */ 750 /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
751 cc->metrics.age = GNUNET_TIME_absolute_get ();
669 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack, 752 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
670 cc); 753 cc);
671 break; 754 break;
@@ -891,6 +974,7 @@ GCC_transmit (struct CadetConnection *cc,
891 GCC_2s (cc)); 974 GCC_2s (cc));
892 GNUNET_assert (GNUNET_YES == cc->mqm_ready); 975 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
893 GNUNET_assert (CADET_CONNECTION_READY == cc->state); 976 GNUNET_assert (CADET_CONNECTION_READY == cc->state);
977 cc->metrics.last_use = GNUNET_TIME_absolute_get ();
894 cc->mqm_ready = GNUNET_NO; 978 cc->mqm_ready = GNUNET_NO;
895 if (NULL != cc->task) 979 if (NULL != cc->task)
896 { 980 {