From 0187bd872885343761174218529aed7058f8d636 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 28 Oct 2011 10:51:21 -0400 Subject: [PATCH 1/3] Implement the last of proposal 110 Reject all EXTEND requests not received in a relay_early cell --- changes/prop110 | 7 +++++++ src/or/relay.c | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 changes/prop110 diff --git a/changes/prop110 b/changes/prop110 new file mode 100644 index 0000000000..843595ecf4 --- /dev/null +++ b/changes/prop110 @@ -0,0 +1,7 @@ + o Major features: + - Now that Tor 0.2.0.x is completely deprecated, we can enable the + final part of "Proposal 110: Avoiding infinite length circuits" + by refusing all circuit-extend requests that do not appear in a + "relay_early" cell. This change helps Tor to resist a class of + denial-of-service attacks by limiting the maximum circuit length. + diff --git a/src/or/relay.c b/src/or/relay.c index 6cf4b73a5f..60d439aca9 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1194,6 +1194,25 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, "'extend' cell received for non-zero stream. Dropping."); return 0; } + if (cell->command != CELL_RELAY_EARLY) { +#define EARLY_WARNING_INTERVAL 900 + static ratelim_t early_warning_limit = + RATELIM_INIT(EARLY_WARNING_INTERVAL); + char *m; + if (cell->command == CELL_RELAY) { + if ((m = rate_limit_log(&early_warning_limit, approx_time()))) { + /* XXXX make this a protocol_warn once we're happier with it*/ + log_fn(LOG_WARN, domain, "EXTEND cell received, " + "but not via RELAY_EARLY. Dropping.%s", m); + tor_free(m); + } + } else { + log_fn(LOG_WARN, domain, + "EXTEND cell received, in a cell with type %d! Dropping.", + cell->command); + } + return 0; + } return circuit_extend(cell, circ); case RELAY_COMMAND_EXTENDED: if (!layer_hint) { From 847541ce5db48152576639d7adc0a6209b661be9 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 21 Nov 2011 17:51:46 -0500 Subject: [PATCH 2/3] Log what fraction of EXTEND cells have died for being non-early --- src/or/relay.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/or/relay.c b/src/or/relay.c index 60d439aca9..fdc26006a0 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1188,7 +1188,9 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_mark_and_flush(TO_CONN(conn)); } return 0; - case RELAY_COMMAND_EXTEND: + case RELAY_COMMAND_EXTEND: { + static uint64_t total_n_extend=0, total_nonearly=0; + total_n_extend++; if (conn) { log_fn(LOG_PROTOCOL_WARN, domain, "'extend' cell received for non-zero stream. Dropping."); @@ -1200,10 +1202,15 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, RATELIM_INIT(EARLY_WARNING_INTERVAL); char *m; if (cell->command == CELL_RELAY) { + ++total_nonearly; if ((m = rate_limit_log(&early_warning_limit, approx_time()))) { /* XXXX make this a protocol_warn once we're happier with it*/ + double percentage = ((double)total_nonearly)/total_n_extend; + percentage *= 100; log_fn(LOG_WARN, domain, "EXTEND cell received, " "but not via RELAY_EARLY. Dropping.%s", m); + log_fn(LOG_WARN, domain, " (We have dropped %.02f%% of all " + "EXTEND cells for this reason)", percentage); tor_free(m); } } else { @@ -1214,6 +1221,7 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, return 0; } return circuit_extend(cell, circ); + } case RELAY_COMMAND_EXTENDED: if (!layer_hint) { log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL, From 2710a96ba4a25bf7d2f3a8ddca7120fbb6aa2cb0 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 22 Dec 2011 10:12:49 -0500 Subject: [PATCH 3/3] Allow prop110 violations if AllowNonearlyExtend is set in consensus --- src/or/relay.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/or/relay.c b/src/or/relay.c index fdc26006a0..e5790dc5eb 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -1196,7 +1196,8 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, "'extend' cell received for non-zero stream. Dropping."); return 0; } - if (cell->command != CELL_RELAY_EARLY) { + if (cell->command != CELL_RELAY_EARLY && + !networkstatus_get_param(NULL,"AllowNonearlyExtend",0,0,1)) { #define EARLY_WARNING_INTERVAL 900 static ratelim_t early_warning_limit = RATELIM_INIT(EARLY_WARNING_INTERVAL);