Merge branch 'tor-github/pr/1907'

This commit is contained in:
David Goulet
2020-07-01 12:26:19 -04:00
6 changed files with 163 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
o Minor features (control port, rephist):
- Introduce GETINFO "stats/ntor/{assigned/requested}" and
"stats/tap/{assigned/requested}" to get the NTorand TAP
circuit onion handshake rephist values respectively.
Closes ticket 28279. Patch by Neel Chauhan.
+44
View File
@@ -51,6 +51,7 @@
#include "feature/rend/rendcache.h"
#include "feature/stats/geoip_stats.h"
#include "feature/stats/predict_ports.h"
#include "feature/stats/rephist.h"
#include "lib/version/torversion.h"
#include "lib/encoding/kvline.h"
@@ -1440,6 +1441,39 @@ getinfo_helper_liveness(control_connection_t *control_conn,
return 0;
}
/** Implementation helper for GETINFO: answers queries about circuit onion
* handshake rephist values */
STATIC int
getinfo_helper_rephist(control_connection_t *control_conn,
const char *question, char **answer,
const char **errmsg)
{
(void) control_conn;
(void) errmsg;
int result;
if (!strcmp(question, "stats/ntor/assigned")) {
result =
rep_hist_get_circuit_handshake_assigned(ONION_HANDSHAKE_TYPE_NTOR);
} else if (!strcmp(question, "stats/ntor/requested")) {
result =
rep_hist_get_circuit_handshake_requested(ONION_HANDSHAKE_TYPE_NTOR);
} else if (!strcmp(question, "stats/tap/assigned")) {
result =
rep_hist_get_circuit_handshake_assigned(ONION_HANDSHAKE_TYPE_TAP);
} else if (!strcmp(question, "stats/tap/requested")) {
result =
rep_hist_get_circuit_handshake_requested(ONION_HANDSHAKE_TYPE_TAP);
} else {
*errmsg = "Unrecognized handshake type";
return -1;
}
tor_asprintf(answer, "%d", result);
return 0;
}
/** Implementation helper for GETINFO: answers queries about shared random
* value. */
static int
@@ -1664,6 +1698,16 @@ static const getinfo_item_t getinfo_items[] = {
"Onion services detached from the control connection."),
ITEM("sr/current", sr, "Get current shared random value."),
ITEM("sr/previous", sr, "Get previous shared random value."),
PREFIX("stats/ntor/", rephist, "NTor circuit handshake stats."),
ITEM("stats/ntor/assigned", rephist,
"Assigned NTor circuit handshake stats."),
ITEM("stats/ntor/requested", rephist,
"Requested NTor circuit handshake stats."),
PREFIX("stats/tap/", rephist, "TAP circuit handshake stats."),
ITEM("stats/tap/assigned", rephist,
"Assigned TAP circuit handshake stats."),
ITEM("stats/tap/requested", rephist,
"Requested TAP circuit handshake stats."),
{ NULL, NULL, NULL, 0 }
};
+4
View File
@@ -60,6 +60,10 @@ STATIC int getinfo_helper_current_time(
control_connection_t *control_conn,
const char *question, char **answer,
const char **errmsg);
STATIC int getinfo_helper_rephist(
control_connection_t *control_conn,
const char *question, char **answer,
const char **errmsg);
#endif /* defined(CONTROL_GETINFO_PRIVATE) */
#endif /* !defined(TOR_CONTROL_GETINFO_H) */
+20
View File
@@ -2455,6 +2455,26 @@ rep_hist_note_circuit_handshake_assigned(uint16_t type)
onion_handshakes_assigned[type]++;
}
/** Get the circuit handshake value that is requested. */
MOCK_IMPL(int,
rep_hist_get_circuit_handshake_requested, (uint16_t type))
{
if (BUG(type > MAX_ONION_HANDSHAKE_TYPE)) {
return 0;
}
return onion_handshakes_requested[type];
}
/** Get the circuit handshake value that is assigned. */
MOCK_IMPL(int,
rep_hist_get_circuit_handshake_assigned, (uint16_t type))
{
if (BUG(type > MAX_ONION_HANDSHAKE_TYPE)) {
return 0;
}
return onion_handshakes_assigned[type];
}
/** Log our onionskin statistics since the last time we were called. */
void
rep_hist_log_circuit_handshake_stats(time_t now)
+3
View File
@@ -77,6 +77,9 @@ void rep_hist_note_circuit_handshake_requested(uint16_t type);
void rep_hist_note_circuit_handshake_assigned(uint16_t type);
void rep_hist_log_circuit_handshake_stats(time_t now);
MOCK_DECL(int, rep_hist_get_circuit_handshake_requested, (uint16_t type));
MOCK_DECL(int, rep_hist_get_circuit_handshake_assigned, (uint16_t type));
void rep_hist_hs_stats_init(time_t now);
void rep_hist_hs_stats_term(void);
time_t rep_hist_hs_stats_write(time_t now);
+87
View File
@@ -19,6 +19,7 @@
#include "feature/rend/rendservice.h"
#include "feature/nodelist/authcert.h"
#include "feature/nodelist/nodelist.h"
#include "feature/stats/rephist.h"
#include "test/test.h"
#include "test/test_helpers.h"
#include "lib/net/resolve.h"
@@ -2112,6 +2113,91 @@ test_control_getconf(void *arg)
smartlist_free(reply_strs);
}
static int
mock_rep_hist_get_circuit_handshake(uint16_t type)
{
int ret;
switch (type) {
case ONION_HANDSHAKE_TYPE_NTOR:
ret = 80;
break;
case ONION_HANDSHAKE_TYPE_TAP:
ret = 86;
break;
default:
ret = 0;
break;
}
return ret;
}
static void
test_rep_hist(void *arg)
{
/* We just need one of these to pass, it doesn't matter what's in it */
control_connection_t dummy;
/* Get results out */
char *answer = NULL;
const char *errmsg = NULL;
(void) arg;
/* We need these for returning the (mock) rephist. */
MOCK(rep_hist_get_circuit_handshake_requested,
mock_rep_hist_get_circuit_handshake);
MOCK(rep_hist_get_circuit_handshake_assigned,
mock_rep_hist_get_circuit_handshake);
/* NTor tests */
getinfo_helper_rephist(&dummy, "stats/ntor/requested",
&answer, &errmsg);
tt_ptr_op(answer, OP_NE, NULL);
tt_ptr_op(errmsg, OP_EQ, NULL);
tt_str_op(answer, OP_EQ, "80");
tor_free(answer);
errmsg = NULL;
getinfo_helper_rephist(&dummy, "stats/ntor/assigned",
&answer, &errmsg);
tt_ptr_op(answer, OP_NE, NULL);
tt_ptr_op(errmsg, OP_EQ, NULL);
tt_str_op(answer, OP_EQ, "80");
tor_free(answer);
errmsg = NULL;
/* TAP tests */
getinfo_helper_rephist(&dummy, "stats/tap/requested",
&answer, &errmsg);
tt_ptr_op(answer, OP_NE, NULL);
tt_ptr_op(errmsg, OP_EQ, NULL);
tt_str_op(answer, OP_EQ, "86");
tor_free(answer);
errmsg = NULL;
getinfo_helper_rephist(&dummy, "stats/tap/assigned",
&answer, &errmsg);
tt_ptr_op(answer, OP_NE, NULL);
tt_ptr_op(errmsg, OP_EQ, NULL);
tt_str_op(answer, OP_EQ, "86");
tor_free(answer);
errmsg = NULL;
getinfo_helper_rephist(&dummy, "stats/tap/onion_circuits_ddosed",
&answer, &errmsg);
tt_ptr_op(answer, OP_EQ, NULL);
tt_str_op(errmsg, OP_EQ, "Unrecognized handshake type");
errmsg = NULL;
done:
UNMOCK(rep_hist_get_circuit_handshake_requested);
UNMOCK(rep_hist_get_circuit_handshake_assigned);
tor_free(answer);
return;
}
#ifndef COCCI
#define PARSER_TEST(type) \
{ "parse/" #type, test_controller_parse_cmd, 0, &passthrough_setup, \
@@ -2146,5 +2232,6 @@ struct testcase_t controller_tests[] = {
{ "getinfo_md_all", test_getinfo_md_all, 0, NULL, NULL },
{ "control_reply", test_control_reply, 0, NULL, NULL },
{ "control_getconf", test_control_getconf, 0, NULL, NULL },
{ "rep_hist", test_rep_hist, 0, NULL, NULL },
END_OF_TESTCASES
};