test: Handling of ESTABLISH_INTRO DoS extension

Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
David Goulet
2019-08-13 10:12:45 -04:00
committed by George Kadianakis
parent dde073764c
commit 4c71accc49
+151
View File
@@ -26,6 +26,7 @@
#include "feature/hs/hs_cell.h"
#include "feature/hs/hs_circuitmap.h"
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_config.h"
#include "feature/hs/hs_dos.h"
#include "feature/hs/hs_intropoint.h"
#include "feature/hs/hs_service.h"
@@ -909,6 +910,153 @@ test_received_introduce1_handling(void *arg)
UNMOCK(relay_send_command_from_edge_);
}
static void
test_received_establish_intro_dos_ext(void *arg)
{
int ret;
ssize_t cell_len = 0;
uint8_t cell[RELAY_PAYLOAD_SIZE] = {0};
char circ_nonce[DIGEST_LEN] = {0};
hs_service_intro_point_t *ip = NULL;
hs_service_config_t config;
or_circuit_t *intro_circ = or_circuit_new(0,NULL);
(void) arg;
MOCK(relay_send_command_from_edge_, mock_relay_send_command_from_edge);
hs_circuitmap_init();
/* Setup. */
crypto_rand(circ_nonce, sizeof(circ_nonce));
ip = service_intro_point_new(NULL);
tt_assert(ip);
ip->support_intro2_dos_defense = 1;
memset(&config, 0, sizeof(config));
config.has_dos_defense_enabled = 1;
config.intro_dos_rate_per_sec = 13;
config.intro_dos_burst_per_sec = 42;
helper_prepare_circ_for_intro(intro_circ, circ_nonce);
/* The INTRO2 bucket should be 0 at this point. */
tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ, 0);
tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ, 0);
tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ, 0);
tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ, 0);
/* Case 1: Build encoded cell. Usable DoS parameters. */
cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell);
tt_size_op(cell_len, OP_GT, 0);
/* Pass it to the intro point. */
ret = hs_intro_received_establish_intro(intro_circ, cell, cell_len);
tt_int_op(ret, OP_EQ, 0);
/* Should be set to the burst value. */
tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ, 42);
/* Validate the config of the intro2 bucket. */
tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ, 13);
tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ, 42);
tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ, 1);
/* Need to reset the circuit in between test cases. */
circuit_free_(TO_CIRCUIT(intro_circ));
intro_circ = or_circuit_new(0,NULL);
helper_prepare_circ_for_intro(intro_circ, circ_nonce);
/* Case 2: Build encoded cell. Bad DoS parameters. */
config.has_dos_defense_enabled = 1;
config.intro_dos_rate_per_sec = UINT_MAX;
config.intro_dos_burst_per_sec = 13;
cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell);
tt_size_op(cell_len, OP_GT, 0);
/* Pass it to the intro point. */
ret = hs_intro_received_establish_intro(intro_circ, cell, cell_len);
tt_int_op(ret, OP_EQ, 0);
tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT);
tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_DEFAULT);
/* Need to reset the circuit in between test cases. */
circuit_free_(TO_CIRCUIT(intro_circ));
intro_circ = or_circuit_new(0,NULL);
helper_prepare_circ_for_intro(intro_circ, circ_nonce);
/* Case 3: Build encoded cell. Burst is smaller than rate. Not allowed. */
config.has_dos_defense_enabled = 1;
config.intro_dos_rate_per_sec = 87;
config.intro_dos_burst_per_sec = 45;
cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell);
tt_size_op(cell_len, OP_GT, 0);
/* Pass it to the intro point. */
ret = hs_intro_received_establish_intro(intro_circ, cell, cell_len);
tt_int_op(ret, OP_EQ, 0);
tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT);
tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_DEFAULT);
/* Need to reset the circuit in between test cases. */
circuit_free_(TO_CIRCUIT(intro_circ));
intro_circ = or_circuit_new(0,NULL);
helper_prepare_circ_for_intro(intro_circ, circ_nonce);
/* Case 4: Build encoded cell. Rate is 0 but burst is not 0. Disables the
* defense. */
config.has_dos_defense_enabled = 1;
config.intro_dos_rate_per_sec = 0;
config.intro_dos_burst_per_sec = 45;
cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell);
tt_size_op(cell_len, OP_GT, 0);
/* Pass it to the intro point. */
ret = hs_intro_received_establish_intro(intro_circ, cell, cell_len);
tt_int_op(ret, OP_EQ, 0);
tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT);
tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_DEFAULT);
/* Need to reset the circuit in between test cases. */
circuit_free_(TO_CIRCUIT(intro_circ));
intro_circ = or_circuit_new(0,NULL);
helper_prepare_circ_for_intro(intro_circ, circ_nonce);
/* Case 5: Build encoded cell. Burst is 0 but rate is not 0. Disables the
* defense. */
config.has_dos_defense_enabled = 1;
config.intro_dos_rate_per_sec = 45;
config.intro_dos_burst_per_sec = 0;
cell_len = hs_cell_build_establish_intro(circ_nonce, &config, ip, cell);
tt_size_op(cell_len, OP_GT, 0);
/* Pass it to the intro point. */
ret = hs_intro_received_establish_intro(intro_circ, cell, cell_len);
tt_int_op(ret, OP_EQ, 0);
tt_u64_op(token_bucket_ctr_get(&intro_circ->introduce2_bucket), OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
tt_u64_op(intro_circ->introduce2_bucket.cfg.rate, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_DEFAULT);
tt_int_op(intro_circ->introduce2_bucket.cfg.burst, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_DEFAULT);
tt_int_op(intro_circ->introduce2_dos_defense_enabled, OP_EQ,
HS_CONFIG_V3_DOS_DEFENSE_DEFAULT);
done:
circuit_free_(TO_CIRCUIT(intro_circ));
service_intro_point_free(ip);
hs_circuitmap_free_all();
UNMOCK(relay_send_command_from_edge_);
}
static void *
hs_subsystem_setup_fn(const struct testcase_t *tc)
{
@@ -967,5 +1115,8 @@ struct testcase_t hs_intropoint_tests[] = {
{ "received_introduce1_handling",
test_received_introduce1_handling, TT_FORK, NULL, &test_setup},
{ "received_establish_intro_dos_ext",
test_received_establish_intro_dos_ext, TT_FORK, NULL, &test_setup},
END_OF_TESTCASES
};