diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-01-30 16:01:30 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-01-30 16:01:30 +0100 |
commit | 8b92d9a2c651d753f756aba5710b6d59ee0f24a1 (patch) | |
tree | f9375a03b2a99eea83ca157c42219453fbc217af /src/cadet/gnunet-service-cadet-new_connection.c | |
parent | 91e2293a4a7ca3bcb287ee0a5010a3524b035c56 (diff) | |
download | gnunet-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.c | 100 |
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 | */ | ||
314 | const struct CadetConnectionMetrics * | ||
315 | GCC_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 | */ | ||
403 | void | ||
404 | GCC_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 | */ | ||
424 | void | ||
425 | GCC_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 | */ |
387 | void | 445 | void |
388 | GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, | 446 | GCC_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 | { |