diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index 8b0ef9a951..9a91c545b2 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -659,7 +659,7 @@ listener_connection_new(int type, int socket_family) connection_init(time(NULL), TO_CONN(listener_conn), type, socket_family); /* Listener connections aren't accounted for with note_connection() so do * this explicitly so to count them. */ - rep_hist_note_conn_opened(false, type); + rep_hist_note_conn_opened(false, type, socket_family); return listener_conn; } @@ -1163,7 +1163,8 @@ connection_mark_for_close_internal_, (connection_t *conn, conn->timestamp_last_write_allowed = time(NULL); /* Note the connection close. */ - rep_hist_note_conn_closed(conn->from_listener, conn->type); + rep_hist_note_conn_closed(conn->from_listener, conn->type, + conn->socket_family); } /** Find each connection that has hold_open_until_flushed set to @@ -2011,7 +2012,7 @@ connection_handle_listener_read(connection_t *conn, int new_type) log_notice(LD_APP, "Denying socks connection from untrusted address %s.", fmt_and_decorate_addr(&addr)); - rep_hist_note_conn_rejected(new_type); + rep_hist_note_conn_rejected(new_type, conn->socket_family); tor_close_socket(news); return 0; } @@ -2021,7 +2022,7 @@ connection_handle_listener_read(connection_t *conn, int new_type) if (dir_policy_permits_address(&addr) == 0) { log_notice(LD_DIRSERV,"Denying dir connection from address %s.", fmt_and_decorate_addr(&addr)); - rep_hist_note_conn_rejected(new_type); + rep_hist_note_conn_rejected(new_type, conn->socket_family); tor_close_socket(news); return 0; } @@ -2030,7 +2031,7 @@ connection_handle_listener_read(connection_t *conn, int new_type) /* Assess with the connection DoS mitigation subsystem if this address * can open a new connection. */ if (dos_conn_addr_get_defense_type(&addr) == DOS_CONN_DEFENSE_CLOSE) { - rep_hist_note_conn_rejected(new_type); + rep_hist_note_conn_rejected(new_type, conn->socket_family); tor_close_socket(news); return 0; } diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index 5ef7a0982b..2b600385e0 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -4209,7 +4209,7 @@ connection_exit_connect(edge_connection_t *edge_conn) log_info(LD_EXIT,"%s failed exit policy%s. Closing.", connection_describe(conn), why_failed_exit_policy); - rep_hist_note_conn_rejected(conn->type); + rep_hist_note_conn_rejected(conn->type, conn->socket_family); connection_edge_end(edge_conn, END_STREAM_REASON_EXITPOLICY); circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn); connection_free(conn); @@ -4237,7 +4237,7 @@ connection_exit_connect(edge_connection_t *edge_conn) nodelist_reentry_contains(&conn->addr, conn->port)) { log_info(LD_EXIT, "%s tried to connect back to a known relay address. " "Closing.", connection_describe(conn)); - rep_hist_note_conn_rejected(conn->type); + rep_hist_note_conn_rejected(conn->type, conn->socket_family); connection_edge_end(edge_conn, END_STREAM_REASON_CONNECTREFUSED); circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn); connection_free(conn); diff --git a/src/core/or/status.c b/src/core/or/status.c index 601c03becc..11912ffc25 100644 --- a/src/core/or/status.c +++ b/src/core/or/status.c @@ -147,7 +147,7 @@ note_connection(bool inbound, const connection_t *conn) } } - rep_hist_note_conn_opened(inbound, conn->type); + rep_hist_note_conn_opened(inbound, conn->type, conn->socket_family); } /** diff --git a/src/feature/relay/relay_metrics.c b/src/feature/relay/relay_metrics.c index cd80c5e95e..02e38d7699 100644 --- a/src/feature/relay/relay_metrics.c +++ b/src/feature/relay/relay_metrics.c @@ -184,6 +184,22 @@ handshake_type_to_str(const uint16_t type) } } +/** Helper function to convert a socket family type into a string. */ +static inline const char * +af_to_string(const int af) +{ + switch (af) { + case AF_INET: + return "ipv4"; + case AF_INET6: + return "ipv6"; + case AF_UNIX: + return "unix"; + default: + return ""; + } +} + /** Fill function for the RELAY_METRICS_NUM_CIRCUITS metric. */ static void fill_circuits_values(void) @@ -515,6 +531,7 @@ fill_single_connection_value(metrics_store_entry_t *sentry, unsigned int conn_type, const char* direction, const char* state, + int socket_family, uint64_t value) { metrics_store_entry_add_label(sentry, @@ -523,6 +540,8 @@ fill_single_connection_value(metrics_store_entry_t *sentry, metrics_format_label("direction", direction)); metrics_store_entry_add_label(sentry, metrics_format_label("state", state)); + metrics_store_entry_add_label(sentry, + metrics_format_label("family", af_to_string(socket_family))); metrics_store_entry_update(sentry, value); } @@ -540,28 +559,49 @@ fill_connections_values(void) } metrics_store_entry_t *sentry = metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); - fill_single_connection_value(sentry, i, "initiated", "created", - rep_hist_get_conn_created(false, i)); + fill_single_connection_value(sentry, i, "initiated", "created", AF_INET, + rep_hist_get_conn_created(false, i, AF_INET)); + sentry = metrics_store_add(the_store, rentry->type, rentry->name, + rentry->help); + fill_single_connection_value(sentry, i, "initiated", "created", AF_INET6, + rep_hist_get_conn_created(false, i, + AF_INET6)); sentry = metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); - fill_single_connection_value(sentry, i, "received", "created", - rep_hist_get_conn_created(true, i)); + fill_single_connection_value(sentry, i, "received", "created", AF_INET, + rep_hist_get_conn_created(true, i, AF_INET)); + sentry = metrics_store_add(the_store, rentry->type, rentry->name, + rentry->help); + fill_single_connection_value(sentry, i, "received", "created", AF_INET6, + rep_hist_get_conn_created(true, i, AF_INET6)); sentry = metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); - fill_single_connection_value(sentry, i, "initiated", "opened", - rep_hist_get_conn_opened(false, i)); + fill_single_connection_value(sentry, i, "initiated", "opened", AF_INET, + rep_hist_get_conn_opened(false, i, AF_INET)); + sentry = metrics_store_add(the_store, rentry->type, rentry->name, + rentry->help); + fill_single_connection_value(sentry, i, "initiated", "opened", AF_INET6, + rep_hist_get_conn_opened(false, i, AF_INET6)); sentry = metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); - fill_single_connection_value(sentry, i, "received", "opened", - rep_hist_get_conn_opened(true, i)); + fill_single_connection_value(sentry, i, "received", "opened", AF_INET, + rep_hist_get_conn_opened(true, i, AF_INET)); + sentry = metrics_store_add(the_store, rentry->type, rentry->name, + rentry->help); + fill_single_connection_value(sentry, i, "received", "opened", AF_INET6, + rep_hist_get_conn_opened(true, i, AF_INET6)); sentry = metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); - fill_single_connection_value(sentry, i, "received", "rejected", - rep_hist_get_conn_rejected(i)); + fill_single_connection_value(sentry, i, "received", "rejected", AF_INET, + rep_hist_get_conn_rejected(i, AF_INET)); + sentry = metrics_store_add(the_store, rentry->type, rentry->name, + rentry->help); + fill_single_connection_value(sentry, i, "received", "rejected", AF_INET6, + rep_hist_get_conn_rejected(i, AF_INET6)); } } diff --git a/src/feature/stats/rephist.c b/src/feature/stats/rephist.c index 3dcc53fd07..8f4f33151a 100644 --- a/src/feature/stats/rephist.c +++ b/src/feature/stats/rephist.c @@ -1693,70 +1693,127 @@ rep_hist_get_exit_stream_seen(unsigned int cmd) (from_listener) ? CONN_DIRECTION_RECEIVED : CONN_DIRECTION_INITIATED /** Number of connections created as in seen per direction per type. */ -static uint64_t conn_num_created[2][CONN_TYPE_MAX_]; +static uint64_t conn_num_created_v4[2][CONN_TYPE_MAX_]; +static uint64_t conn_num_created_v6[2][CONN_TYPE_MAX_]; /** Number of connections opened per direction per type. */ -static uint64_t conn_num_opened[2][CONN_TYPE_MAX_]; +static uint64_t conn_num_opened_v4[2][CONN_TYPE_MAX_]; +static uint64_t conn_num_opened_v6[2][CONN_TYPE_MAX_]; /** Number of connections rejected per type. Always inbound. */ -static uint64_t conn_num_rejected[CONN_TYPE_MAX_]; +static uint64_t conn_num_rejected_v4[CONN_TYPE_MAX_]; +static uint64_t conn_num_rejected_v6[CONN_TYPE_MAX_]; /** Note that a connection has opened of the given type. */ void -rep_hist_note_conn_opened(bool from_listener, unsigned int type) +rep_hist_note_conn_opened(bool from_listener, unsigned int type, int af) { tor_assert(type <= CONN_TYPE_MAX_); unsigned int dir = CONN_DIRECTION(from_listener); - conn_num_created[dir][type]++; - conn_num_opened[dir][type]++; + switch (af) { + case AF_INET: + conn_num_created_v4[dir][type]++; + conn_num_opened_v4[dir][type]++; + break; + case AF_INET6: + conn_num_created_v6[dir][type]++; + conn_num_opened_v6[dir][type]++; + break; + default: + /* Ignore non IP connections at this point in time. */ + break; + } } /** Note that a connection has closed of the given type. */ void -rep_hist_note_conn_closed(bool from_listener, unsigned int type) +rep_hist_note_conn_closed(bool from_listener, unsigned int type, int af) { tor_assert(type <= CONN_TYPE_MAX_); unsigned int dir = CONN_DIRECTION(from_listener); - if (conn_num_opened[dir][type] > 0) { - conn_num_opened[dir][type]--; + switch (af) { + case AF_INET: + if (conn_num_opened_v4[dir][type] > 0) { + conn_num_opened_v4[dir][type]--; + } + break; + case AF_INET6: + if (conn_num_opened_v6[dir][type] > 0) { + conn_num_opened_v6[dir][type]--; + } + break; + default: + /* Ignore non IP connections at this point in time. */ + break; } } /** Note that a connection has rejected of the given type. */ void -rep_hist_note_conn_rejected(unsigned int type) +rep_hist_note_conn_rejected(unsigned int type, int af) { tor_assert(type <= CONN_TYPE_MAX_); - conn_num_rejected[type]++; + switch (af) { + case AF_INET: + conn_num_rejected_v4[type]++; + break; + case AF_INET6: + conn_num_rejected_v6[type]++; + break; + default: + /* Ignore non IP connections at this point in time. */ + break; + } } /** Return number of created connections of the given type. */ uint64_t -rep_hist_get_conn_created(bool from_listener, unsigned int type) +rep_hist_get_conn_created(bool from_listener, unsigned int type, int af) { tor_assert(type <= CONN_TYPE_MAX_); unsigned int dir = CONN_DIRECTION(from_listener); - return conn_num_created[dir][type]; + switch (af) { + case AF_INET: + return conn_num_created_v4[dir][type]; + case AF_INET6: + return conn_num_created_v6[dir][type]; + default: + return 0; + } } /** Return number of opened connections of the given type. */ uint64_t -rep_hist_get_conn_opened(bool from_listener, unsigned int type) +rep_hist_get_conn_opened(bool from_listener, unsigned int type, int af) { tor_assert(type <= CONN_TYPE_MAX_); unsigned int dir = CONN_DIRECTION(from_listener); - return conn_num_opened[dir][type]; + switch (af) { + case AF_INET: + return conn_num_opened_v4[dir][type]; + case AF_INET6: + return conn_num_opened_v6[dir][type]; + default: + return 0; + } } /** Return number of opened connections of the given type. */ uint64_t -rep_hist_get_conn_rejected(unsigned int type) +rep_hist_get_conn_rejected(unsigned int type, int af) { tor_assert(type <= CONN_TYPE_MAX_); - return conn_num_rejected[type]; + switch (af) { + case AF_INET: + return conn_num_rejected_v4[type]; + case AF_INET6: + return conn_num_rejected_v6[type]; + default: + return 0; + } } /*** cell statistics ***/ diff --git a/src/feature/stats/rephist.h b/src/feature/stats/rephist.h index 02d23a4c1b..fbfab4c451 100644 --- a/src/feature/stats/rephist.h +++ b/src/feature/stats/rephist.h @@ -41,12 +41,12 @@ void rep_hist_note_exit_bytes(uint16_t port, size_t num_written, size_t num_read); void rep_hist_note_exit_stream_opened(uint16_t port); -void rep_hist_note_conn_opened(bool initiated, unsigned int type); -void rep_hist_note_conn_closed(bool initiated, unsigned int type); -void rep_hist_note_conn_rejected(unsigned int type); -uint64_t rep_hist_get_conn_created(bool initiated, unsigned int type); -uint64_t rep_hist_get_conn_opened(bool initiated, unsigned int type); -uint64_t rep_hist_get_conn_rejected(unsigned int type); +void rep_hist_note_conn_opened(bool initiated, unsigned int type, int af); +void rep_hist_note_conn_closed(bool initiated, unsigned int type, int af); +void rep_hist_note_conn_rejected(unsigned int type, int af); +uint64_t rep_hist_get_conn_created(bool initiated, unsigned int type, int af); +uint64_t rep_hist_get_conn_opened(bool initiated, unsigned int type, int af); +uint64_t rep_hist_get_conn_rejected(unsigned int type, int af); void rep_hist_note_exit_stream(unsigned int cmd); uint64_t rep_hist_get_exit_stream_seen(unsigned int cmd);