diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index 9271a70914..c6af478c44 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -658,6 +658,9 @@ listener_connection_new(int type, int socket_family) listener_connection_t *listener_conn = tor_malloc_zero(sizeof(listener_connection_t)); 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); return listener_conn; } @@ -1160,6 +1163,9 @@ connection_mark_for_close_internal_, (connection_t *conn, * the number of seconds since last successful write, so * we get our whole 15 seconds */ conn->timestamp_last_write_allowed = time(NULL); + + /* Note the connection close. */ + rep_hist_note_conn_closed(conn->from_listener, conn->type); } /** Find each connection that has hold_open_until_flushed set to @@ -2074,6 +2080,9 @@ connection_handle_listener_read(connection_t *conn, int new_type) tor_assert(0); }; + /* We are receiving this connection. */ + newconn->from_listener = 1; + if (connection_add(newconn) < 0) { /* no space, forget it */ connection_free(newconn); return 0; /* no need to tear down the parent */ @@ -2085,7 +2094,7 @@ connection_handle_listener_read(connection_t *conn, int new_type) return 0; } - note_connection(true /* inbound */, conn->socket_family); + note_connection(true /* inbound */, newconn); return 0; } @@ -2258,7 +2267,7 @@ connection_connect_sockaddr,(connection_t *conn, } } - note_connection(false /* outbound */, conn->socket_family); + note_connection(false /* outbound */, conn); /* it succeeded. we're connected. */ log_fn(inprogress ? LOG_DEBUG : LOG_INFO, LD_NET, diff --git a/src/core/or/connection_st.h b/src/core/or/connection_st.h index 6326afbc6e..d3a230daa0 100644 --- a/src/core/or/connection_st.h +++ b/src/core/or/connection_st.h @@ -87,6 +87,10 @@ struct connection_t { /** True iff we've called connection_close_immediate() on this linked * connection. */ unsigned int linked_conn_is_closed:1; + /** True iff this connection was opened from a listener and thus we've + * recevied this connection. Else, it means we've initiated an outbound + * connection. */ + unsigned int from_listener:1; /** CONNECT/SOCKS proxy client handshake state (for outgoing connections). */ unsigned int proxy_state:4; diff --git a/src/core/or/status.c b/src/core/or/status.c index 1e599aafb3..601c03becc 100644 --- a/src/core/or/status.c +++ b/src/core/or/status.c @@ -30,6 +30,7 @@ #include "app/config/statefile.h" #include "feature/hs/hs_stats.h" #include "feature/hs/hs_service.h" +#include "core/or/connection_st.h" #include "core/or/dos.h" #include "feature/stats/geoip_stats.h" @@ -130,21 +131,23 @@ static unsigned n_outgoing_ipv6; * heartbeat message. **/ void -note_connection(bool inbound, int family) +note_connection(bool inbound, const connection_t *conn) { - if (family == AF_INET) { + if (conn->socket_family == AF_INET) { if (inbound) { ++n_incoming_ipv4; } else { ++n_outgoing_ipv4; } - } else if (family == AF_INET6) { + } else if (conn->socket_family == AF_INET6) { if (inbound) { ++n_incoming_ipv6; } else { ++n_outgoing_ipv6; } } + + rep_hist_note_conn_opened(inbound, conn->type); } /** diff --git a/src/core/or/status.h b/src/core/or/status.h index 57e28002fc..55492d24da 100644 --- a/src/core/or/status.h +++ b/src/core/or/status.h @@ -11,7 +11,7 @@ #include "lib/testsupport/testsupport.h" -void note_connection(bool inbound, int family); +void note_connection(bool inbound, const connection_t *conn); void note_circ_closed_for_unrecognized_cells(time_t n_seconds, uint32_t n_cells); diff --git a/src/feature/stats/rephist.c b/src/feature/stats/rephist.c index 52bd94aba9..b272f27909 100644 --- a/src/feature/stats/rephist.c +++ b/src/feature/stats/rephist.c @@ -69,6 +69,7 @@ #define REPHIST_PRIVATE #include "core/or/or.h" #include "app/config/config.h" +#include "core/mainloop/connection.h" #include "core/or/circuitlist.h" #include "core/or/connection_or.h" #include "feature/dirauth/authmode.h" @@ -1638,6 +1639,62 @@ rep_hist_note_exit_stream_opened(uint16_t port) log_debug(LD_HIST, "Opened exit stream to port %d", port); } +/******* Connections statistics *******/ + +#define CONN_DIRECTION_INITIATED 0 +#define CONN_DIRECTION_RECEIVED 1 + +#define CONN_DIRECTION(from_listener) \ + (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_]; +/** Number of connections opened per direction per type. */ +static uint64_t conn_num_opened[2][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) +{ + tor_assert(type <= CONN_TYPE_MAX_); + + unsigned int dir = CONN_DIRECTION(from_listener); + + conn_num_created[dir][type]++; + conn_num_opened[dir][type]++; +} + +/** Note that a connection has closed of the given type. */ +void +rep_hist_note_conn_closed(bool from_listener, unsigned int type) +{ + 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]--; + } +} + +/** Return number of created connections of the given type. */ +uint64_t +rep_hist_get_conn_created(bool from_listener, unsigned int type) +{ + tor_assert(type <= CONN_TYPE_MAX_); + unsigned int dir = CONN_DIRECTION(from_listener); + return conn_num_created[dir][type]; +} + +/** Return number of opened connections of the given type. */ +uint64_t +rep_hist_get_conn_opened(bool from_listener, unsigned int type) +{ + tor_assert(type <= CONN_TYPE_MAX_); + unsigned int dir = CONN_DIRECTION(from_listener); + return conn_num_opened[dir][type]; +} + /*** cell statistics ***/ /** Start of the current buffer stats interval or 0 if we're not diff --git a/src/feature/stats/rephist.h b/src/feature/stats/rephist.h index e8f43fbb1d..21808cdee8 100644 --- a/src/feature/stats/rephist.h +++ b/src/feature/stats/rephist.h @@ -41,6 +41,11 @@ 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); +uint64_t rep_hist_get_conn_created(bool initiated, unsigned int type); +uint64_t rep_hist_get_conn_opened(bool initiated, unsigned int type); + void rep_hist_buffer_stats_init(time_t now); void rep_hist_buffer_stats_add_circ(circuit_t *circ, time_t end_of_interval);