mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 13:53:31 +01:00
Merge branch 'maint-0.4.7'
This commit is contained in:
commit
5080a4ff67
3
changes/ticket40194
Normal file
3
changes/ticket40194
Normal file
@ -0,0 +1,3 @@
|
||||
o Minor feature (relay, metrics):
|
||||
- Add counters to the MetricsPort how many connections, per type, are
|
||||
currently opened and how many were created. Part of ticket 40194.
|
@ -657,6 +657,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;
|
||||
}
|
||||
|
||||
@ -1158,6 +1161,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
|
||||
@ -2005,6 +2011,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);
|
||||
tor_close_socket(news);
|
||||
return 0;
|
||||
}
|
||||
@ -2014,6 +2021,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);
|
||||
tor_close_socket(news);
|
||||
return 0;
|
||||
}
|
||||
@ -2022,6 +2030,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);
|
||||
tor_close_socket(news);
|
||||
return 0;
|
||||
}
|
||||
@ -2072,6 +2081,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 */
|
||||
@ -2083,7 +2095,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;
|
||||
}
|
||||
@ -2262,7 +2274,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,
|
||||
|
@ -4206,6 +4206,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);
|
||||
connection_edge_end(edge_conn, END_STREAM_REASON_EXITPOLICY);
|
||||
circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
|
||||
connection_free(conn);
|
||||
@ -4233,6 +4234,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);
|
||||
connection_edge_end(edge_conn, END_STREAM_REASON_CONNECTREFUSED);
|
||||
circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
|
||||
connection_free(conn);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "orconfig.h"
|
||||
|
||||
#include "core/or/or.h"
|
||||
#include "core/mainloop/connection.h"
|
||||
#include "core/or/relay.h"
|
||||
|
||||
#include "lib/malloc/malloc.h"
|
||||
@ -24,6 +25,7 @@
|
||||
#include <event2/dns.h>
|
||||
|
||||
/** Declarations of each fill function for metrics defined in base_metrics. */
|
||||
static void fill_connections_values(void);
|
||||
static void fill_dns_error_values(void);
|
||||
static void fill_dns_query_values(void);
|
||||
static void fill_global_bw_limit_values(void);
|
||||
@ -87,6 +89,13 @@ static const relay_metrics_entry_t base_metrics[] =
|
||||
.help = "Total number of times we ran out of TCP ports",
|
||||
.fill_fn = fill_tcp_exhaustion_values,
|
||||
},
|
||||
{
|
||||
.key = RELAY_METRICS_NUM_CONNECTIONS,
|
||||
.type = METRICS_TYPE_COUNTER,
|
||||
.name = METRICS_NAME(relay_connections),
|
||||
.help = "Connections metrics of this relay",
|
||||
.fill_fn = fill_connections_values,
|
||||
},
|
||||
};
|
||||
static const size_t num_base_metrics = ARRAY_LENGTH(base_metrics);
|
||||
|
||||
@ -113,6 +122,62 @@ handshake_type_to_str(const uint16_t type)
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper: Fill in single connection metrics output. */
|
||||
static void
|
||||
fill_single_connection_value(metrics_store_entry_t *sentry,
|
||||
unsigned int conn_type,
|
||||
const char* direction,
|
||||
const char* state,
|
||||
uint64_t value)
|
||||
{
|
||||
metrics_store_entry_add_label(sentry,
|
||||
metrics_format_label("type", conn_type_to_string(conn_type)));
|
||||
metrics_store_entry_add_label(sentry,
|
||||
metrics_format_label("direction", direction));
|
||||
metrics_store_entry_add_label(sentry,
|
||||
metrics_format_label("state", state));
|
||||
metrics_store_entry_update(sentry, value);
|
||||
}
|
||||
|
||||
/** Fill function for the RELAY_METRICS_NUM_CONNECTIONS metric. */
|
||||
static void
|
||||
fill_connections_values(void)
|
||||
{
|
||||
const relay_metrics_entry_t *rentry =
|
||||
&base_metrics[RELAY_METRICS_NUM_CONNECTIONS];
|
||||
|
||||
for (unsigned int i = CONN_TYPE_MIN_; i < CONN_TYPE_MAX_ ; i++) {
|
||||
/* Type is unused. Ugly but else we clobber the output. */
|
||||
if (i == 10) {
|
||||
continue;
|
||||
}
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
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 function for the RELAY_METRICS_NUM_DNS metrics. */
|
||||
static void
|
||||
fill_tcp_exhaustion_values(void)
|
||||
|
@ -29,6 +29,8 @@ typedef enum {
|
||||
RELAY_METRICS_NUM_DNS_ERRORS = 5,
|
||||
/** Number of TCP exhaustion reached. */
|
||||
RELAY_METRICS_NUM_TCP_EXHAUSTION = 6,
|
||||
/** Number of connections. */
|
||||
RELAY_METRICS_NUM_CONNECTIONS = 7,
|
||||
} relay_metrics_key_t;
|
||||
|
||||
/** The metadata of a relay metric. */
|
||||
|
@ -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,81 @@ 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_];
|
||||
/** Number of connections rejected per type. Always inbound. */
|
||||
static uint64_t conn_num_rejected[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]--;
|
||||
}
|
||||
}
|
||||
|
||||
/** Note that a connection has rejected of the given type. */
|
||||
void
|
||||
rep_hist_note_conn_rejected(unsigned int type)
|
||||
{
|
||||
tor_assert(type <= CONN_TYPE_MAX_);
|
||||
|
||||
conn_num_rejected[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];
|
||||
}
|
||||
|
||||
/** Return number of opened connections of the given type. */
|
||||
uint64_t
|
||||
rep_hist_get_conn_rejected(unsigned int type)
|
||||
{
|
||||
tor_assert(type <= CONN_TYPE_MAX_);
|
||||
return conn_num_rejected[type];
|
||||
}
|
||||
|
||||
/*** cell statistics ***/
|
||||
|
||||
/** Start of the current buffer stats interval or 0 if we're not
|
||||
|
@ -41,6 +41,13 @@ 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_buffer_stats_init(time_t now);
|
||||
void rep_hist_buffer_stats_add_circ(circuit_t *circ,
|
||||
time_t end_of_interval);
|
||||
|
Loading…
Reference in New Issue
Block a user