From dbdf8bebde8b0f18009c7e9c6e89406f241ad0e6 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 10 Jul 2020 09:47:55 -0400 Subject: [PATCH] Collect IPv6 bidi connection statistics --- src/core/mainloop/connection.c | 4 ++-- src/feature/stats/connstats.c | 37 +++++++++++++++++++++++++--------- src/feature/stats/connstats.h | 3 ++- src/test/test_stats.c | 28 ++++++++++++++----------- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index 0d2e6a220b..1d53e077d1 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -3363,11 +3363,11 @@ record_num_bytes_transferred_impl(connection_t *conn, if (!connection_is_rate_limited(conn)) return; + const bool is_ipv6 = (conn->socket_family == AF_INET6); if (conn->type == CONN_TYPE_OR) conn_stats_note_or_conn_bytes(conn->global_identifier, num_read, - num_written, now); + num_written, now, is_ipv6); - const bool is_ipv6 = (conn->socket_family == AF_INET6); if (num_read > 0) { bwhist_note_bytes_read(num_read, now, is_ipv6); } diff --git a/src/feature/stats/connstats.c b/src/feature/stats/connstats.c index 7d7c67361d..73bc8d7ccc 100644 --- a/src/feature/stats/connstats.c +++ b/src/feature/stats/connstats.c @@ -70,6 +70,8 @@ typedef struct conn_counts_t { /** A collection of connection counts, over all OR connections. */ static conn_counts_t counts; +/** A collection of connection counts, over IPv6 OR connections only. */ +static conn_counts_t counts_ipv6; /** Entry in a map from connection ID to the number of read and written * bytes on this connection in a BIDI_INTERVAL second interval. */ @@ -78,6 +80,7 @@ typedef struct bidi_map_entry_t { uint64_t conn_id; /**< Connection ID */ size_t read; /**< Number of read bytes */ size_t written; /**< Number of written bytes */ + bool is_ipv6; /**< True if this is an IPv6 connection */ } bidi_map_entry_t; /** Map of OR connections together with the number of read and written @@ -123,6 +126,7 @@ conn_stats_reset(time_t now) { start_of_conn_stats_interval = now; memset(&counts, 0, sizeof(counts)); + memset(&counts_ipv6, 0, sizeof(counts_ipv6)); conn_stats_free_all(); } @@ -159,17 +163,18 @@ static void collect_period_statistics(void) { bidi_map_entry_t **ptr, **next, *ent; - conn_counts_t *cnt = &counts; for (ptr = HT_START(bidimap, &bidi_map); ptr; ptr = next) { ent = *ptr; - add_entry_to_count(cnt, ent); + add_entry_to_count(&counts, ent); + if (ent->is_ipv6) + add_entry_to_count(&counts_ipv6, ent); next = HT_NEXT_RMV(bidimap, &bidi_map, ptr); tor_free(ent); } log_info(LD_GENERAL, "%d below threshold, %d mostly read, " "%d mostly written, %d both read and written.", - cnt->below_threshold, cnt->mostly_read, cnt->mostly_written, - cnt->both_read_and_written); + counts.below_threshold, counts.mostly_read, counts.mostly_written, + counts.both_read_and_written); } /** We read num_read bytes and wrote num_written from/to OR @@ -178,7 +183,8 @@ collect_period_statistics(void) * for this connection. */ void conn_stats_note_or_conn_bytes(uint64_t conn_id, size_t num_read, - size_t num_written, time_t when) + size_t num_written, time_t when, + bool is_ipv6) { if (!start_of_conn_stats_interval) return; @@ -199,11 +205,13 @@ conn_stats_note_or_conn_bytes(uint64_t conn_id, size_t num_read, if (entry) { entry->written += num_written; entry->read += num_read; + entry->is_ipv6 |= is_ipv6; } else { entry = tor_malloc_zero(sizeof(bidi_map_entry_t)); entry->conn_id = conn_id; entry->written = num_written; entry->read = num_read; + entry->is_ipv6 = is_ipv6; HT_INSERT(bidimap, &bidi_map, entry); } } @@ -215,21 +223,30 @@ conn_stats_note_or_conn_bytes(uint64_t conn_id, size_t num_read, char * conn_stats_format(time_t now) { - char *result, written[ISO_TIME_LEN+1]; + char *result, written_at[ISO_TIME_LEN+1]; if (!start_of_conn_stats_interval) return NULL; /* Not initialized. */ tor_assert(now >= start_of_conn_stats_interval); - format_iso_time(written, now); - tor_asprintf(&result, "conn-bi-direct %s (%d s) %d,%d,%d,%d\n", - written, + format_iso_time(written_at, now); + tor_asprintf(&result, + "conn-bi-direct %s (%d s) %d,%d,%d,%d\n" + "ipv6-conn-bi-direct %s (%d s) %d,%d,%d,%d\n", + written_at, (unsigned) (now - start_of_conn_stats_interval), counts.below_threshold, counts.mostly_read, counts.mostly_written, - counts.both_read_and_written); + counts.both_read_and_written, + written_at, + (unsigned) (now - start_of_conn_stats_interval), + counts_ipv6.below_threshold, + counts_ipv6.mostly_read, + counts_ipv6.mostly_written, + counts_ipv6.both_read_and_written); + return result; } diff --git a/src/feature/stats/connstats.h b/src/feature/stats/connstats.h index 43b6549741..1a03d0748b 100644 --- a/src/feature/stats/connstats.h +++ b/src/feature/stats/connstats.h @@ -14,7 +14,8 @@ void conn_stats_init(time_t now); void conn_stats_note_or_conn_bytes(uint64_t conn_id, size_t num_read, - size_t num_written, time_t when); + size_t num_written, time_t when, + bool is_ipv6); void conn_stats_reset(time_t now); char *conn_stats_format(time_t now); time_t conn_stats_save(time_t now); diff --git a/src/test/test_stats.c b/src/test/test_stats.c index 288757229a..f0715c2e45 100644 --- a/src/test/test_stats.c +++ b/src/test/test_stats.c @@ -112,37 +112,41 @@ test_stats(void *arg) /* Continue with testing connection statistics; we shouldn't collect * conn stats without initializing them. */ - conn_stats_note_or_conn_bytes(1, 20, 400, now); + conn_stats_note_or_conn_bytes(1, 20, 400, now, false); s = conn_stats_format(now + 86400); tt_ptr_op(s, OP_EQ, NULL); /* Initialize stats, note bytes, and generate history string. */ conn_stats_init(now); - conn_stats_note_or_conn_bytes(1, 30000, 400000, now); - conn_stats_note_or_conn_bytes(1, 30000, 400000, now + 5); - conn_stats_note_or_conn_bytes(2, 400000, 30000, now + 10); - conn_stats_note_or_conn_bytes(2, 400000, 30000, now + 15); + conn_stats_note_or_conn_bytes(1, 30000, 400000, now, false); + conn_stats_note_or_conn_bytes(1, 30000, 400000, now + 5, false); + conn_stats_note_or_conn_bytes(2, 400000, 30000, now + 10, true); + conn_stats_note_or_conn_bytes(2, 400000, 30000, now + 15, true); s = conn_stats_format(now + 86400); - tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,1,0\n",OP_EQ, s); + tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,1,0\n" + "ipv6-conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,0,0\n", + OP_EQ, s); tor_free(s); /* Stop collecting stats, add some bytes, and ensure we don't generate * a history string. */ conn_stats_terminate(); - conn_stats_note_or_conn_bytes(2, 400000, 30000, now + 15); + conn_stats_note_or_conn_bytes(2, 400000, 30000, now + 15, true); s = conn_stats_format(now + 86400); tt_ptr_op(s, OP_EQ, NULL); /* Re-start stats, add some bytes, reset stats, and see what history we * get when observing no bytes at all. */ conn_stats_init(now); - conn_stats_note_or_conn_bytes(1, 30000, 400000, now); - conn_stats_note_or_conn_bytes(1, 30000, 400000, now + 5); - conn_stats_note_or_conn_bytes(2, 400000, 30000, now + 10); - conn_stats_note_or_conn_bytes(2, 400000, 30000, now + 15); + conn_stats_note_or_conn_bytes(1, 30000, 400000, now, false); + conn_stats_note_or_conn_bytes(1, 30000, 400000, now + 5, false); + conn_stats_note_or_conn_bytes(2, 400000, 30000, now + 10, true); + conn_stats_note_or_conn_bytes(2, 400000, 30000, now + 15, true); conn_stats_reset(now); s = conn_stats_format(now + 86400); - tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,0,0\n",OP_EQ, s); + tt_str_op("conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,0,0\n" + "ipv6-conn-bi-direct 2010-08-12 13:27:30 (86400 s) 0,0,0,0\n", + OP_EQ, s); tor_free(s); /* Continue with testing buffer statistics; we shouldn't collect buffer