summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Perry <mikeperry-git@torproject.org>2017-06-23 18:34:41 -0400
committerNick Mathewson <nickm@torproject.org>2017-09-12 10:28:45 -0400
commit6d221c8f371a0c1809552b699f1afab8cde3bd31 (patch)
treef03bda8eca62ccf13b3f0a32af1baf595865bfd0
parent79e2e4d3cbabff41675aa1f7defb67f4acba398c (diff)
downloadtor-6d221c8f371a0c1809552b699f1afab8cde3bd31.tar.gz
tor-6d221c8f371a0c1809552b699f1afab8cde3bd31.zip
Ticket #17857: Apply padding off-switch to existing connections.
-rw-r--r--src/or/channel.c30
-rw-r--r--src/or/channelpadding.c26
-rw-r--r--src/or/channelpadding.h5
-rw-r--r--src/test/test_channelpadding.c65
4 files changed, 98 insertions, 28 deletions
diff --git a/src/or/channel.c b/src/or/channel.c
index 8348ffd649..17b2191b77 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -66,6 +66,7 @@
#include "scheduler.h"
#include "compat_time.h"
#include "networkstatus.h"
+#include "rendservice.h"
/* Global lists of channels */
@@ -2712,17 +2713,26 @@ channel_do_open_actions(channel_t *chan)
/* Disable or reduce padding according to user prefs. */
if (chan->padding_enabled || get_options()->ConnectionPadding == 1) {
- if (!get_options()->ConnectionPadding ||
- (get_options()->Tor2webMode &&
- !networkstatus_get_param(NULL, "nf_pad_tor2web", 1, 0, 1))
- || (get_options()->HiddenServiceSingleHopMode &&
- !networkstatus_get_param(NULL, "nf_pad_single_onion", 1, 0, 1))) {
+ if (!get_options()->ConnectionPadding) {
+ /* Disable if torrc disabled */
channelpadding_disable_padding_on_channel(chan);
- }
-
- /* Padding can be forced and/or reduced by clients, regardless of if
- * the channel supports it */
- if (get_options()->ReducedConnectionPadding) {
+ } else if (get_options()->Tor2webMode &&
+ !networkstatus_get_param(NULL,
+ CHANNELPADDING_TOR2WEB_PARAM,
+ CHANNELPADDING_TOR2WEB_DEFAULT, 0, 1)) {
+ /* Disable if we're using tor2web and the consensus disabled padding
+ * for tor2web */
+ channelpadding_disable_padding_on_channel(chan);
+ } else if (rend_service_allow_non_anonymous_connection(get_options()) &&
+ !networkstatus_get_param(NULL,
+ CHANNELPADDING_SOS_PARAM,
+ CHANNELPADDING_SOS_DEFAULT, 0, 1)) {
+ /* Disable if we're using RSOS and the consensus disabled padding
+ * for RSOS*/
+ channelpadding_disable_padding_on_channel(chan);
+ } else if (get_options()->ReducedConnectionPadding) {
+ /* Padding can be forced and/or reduced by clients, regardless of if
+ * the channel supports it */
channelpadding_reduce_padding_on_channel(chan);
}
}
diff --git a/src/or/channelpadding.c b/src/or/channelpadding.c
index 9a2fdc4bbe..ee6d29f7c8 100644
--- a/src/or/channelpadding.c
+++ b/src/or/channelpadding.c
@@ -21,6 +21,7 @@
#include "router.h"
#include "compat_time.h"
#include <event2/event.h>
+#include "rendservice.h"
STATIC int channelpadding_get_netflow_inactive_timeout_ms(const channel_t *);
STATIC int channelpadding_send_disable_command(channel_t *);
@@ -136,10 +137,14 @@ channelpadding_new_consensus_params(networkstatus_t *ns)
networkstatus_get_param(ns, "nf_pad_relays", 0, 0, 1);
consensus_nf_pad_tor2web =
- networkstatus_get_param(ns, "nf_pad_tor2web", 1, 0, 1);
+ networkstatus_get_param(ns,
+ CHANNELPADDING_TOR2WEB_PARAM,
+ CHANNELPADDING_TOR2WEB_DEFAULT, 0, 1);
consensus_nf_pad_single_onion =
- networkstatus_get_param(ns, "nf_pad_single_onion", 1, 0, 1);
+ networkstatus_get_param(ns,
+ CHANNELPADDING_SOS_PARAM,
+ CHANNELPADDING_SOS_DEFAULT, 0, 1);
}
/**
@@ -717,11 +722,24 @@ channelpadding_decide_to_pad_channel(channel_t *chan)
return CHANNELPADDING_WONTPAD;
}
- if (options->Tor2webMode && !consensus_nf_pad_tor2web)
+ if (options->Tor2webMode && !consensus_nf_pad_tor2web) {
+ /* If the consensus just changed values, this channel may still
+ * think padding is enabled. Negotiate it off. */
+ if (chan->padding_enabled)
+ channelpadding_disable_padding_on_channel(chan);
+
return CHANNELPADDING_WONTPAD;
+ }
+
+ if (rend_service_allow_non_anonymous_connection(options) &&
+ !consensus_nf_pad_single_onion) {
+ /* If the consensus just changed values, this channel may still
+ * think padding is enabled. Negotiate it off. */
+ if (chan->padding_enabled)
+ channelpadding_disable_padding_on_channel(chan);
- if (options->HiddenServiceSingleHopMode && !consensus_nf_pad_single_onion)
return CHANNELPADDING_WONTPAD;
+ }
if (!chan->has_queued_writes(chan)) {
int is_client_channel = 0;
diff --git a/src/or/channelpadding.h b/src/or/channelpadding.h
index 2708ee9739..a227e27d5b 100644
--- a/src/or/channelpadding.h
+++ b/src/or/channelpadding.h
@@ -13,6 +13,11 @@
#include "channelpadding_negotiation.h"
+#define CHANNELPADDING_TOR2WEB_PARAM "nf_pad_tor2web"
+#define CHANNELPADDING_TOR2WEB_DEFAULT 1
+#define CHANNELPADDING_SOS_PARAM "nf_pad_single_onion"
+#define CHANNELPADDING_SOS_DEFAULT 1
+
typedef enum {
CHANNELPADDING_WONTPAD,
CHANNELPADDING_PADLATER,
diff --git a/src/test/test_channelpadding.c b/src/test/test_channelpadding.c
index 99f8880a40..998368cf4a 100644
--- a/src/test/test_channelpadding.c
+++ b/src/test/test_channelpadding.c
@@ -371,6 +371,7 @@ test_channelpadding_killonehop(void *arg)
timers_initialize();
setup_mock_consensus();
+ setup_mock_network();
/* Do we disable padding if tor2webmode or rsos are enabled, and
* the consensus says don't pad? */
@@ -380,7 +381,6 @@ test_channelpadding_killonehop(void *arg)
smartlist_clear(current_md_consensus->net_params);
channelpadding_new_consensus_params(current_md_consensus);
- setup_mock_network();
tried_to_write_cell = 0;
get_options_mutable()->Tor2webMode = 1;
client_relay3->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
@@ -402,17 +402,35 @@ test_channelpadding_killonehop(void *arg)
(void*)"nf_pad_tor2web=0");
channelpadding_new_consensus_params(current_md_consensus);
- // Test client side (it should stop immediately)
+ // Before the client tries to pad, the relay will still pad:
+ tried_to_write_cell = 0;
+ relay3_client->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ get_options_mutable()->ORPort_set = 1;
+ get_options_mutable()->Tor2webMode = 0;
+ decision = channelpadding_decide_to_pad_channel(relay3_client);
+ tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
+ tt_assert(relay3_client->pending_padding_callback);
+
+ // Wait for the timer
+ event_base_loop(tor_libevent_get_base(), 0);
+ tt_int_op(tried_to_write_cell, OP_EQ, 1);
+ tt_assert(!client_relay3->pending_padding_callback);
+
+ // Test client side (it should stop immediately, but send a negotiate)
+ tried_to_write_cell = 0;
+ tt_assert(relay3_client->padding_enabled);
+ tt_assert(client_relay3->padding_enabled);
+ get_options_mutable()->Tor2webMode = 1;
+ /* For the relay to recieve the negotiate: */
+ get_options_mutable()->ORPort_set = 1;
decision = channelpadding_decide_to_pad_channel(client_relay3);
tt_int_op(decision, OP_EQ, CHANNELPADDING_WONTPAD);
+ tt_int_op(tried_to_write_cell, OP_EQ, 1);
tt_assert(!client_relay3->pending_padding_callback);
-
- // Reset connnections.. XXX: remove this requirement via client
- // negotiation
- free_mock_network();
- setup_mock_network();
+ tt_assert(!relay3_client->padding_enabled);
// Test relay side (it should have gotten the negotiation to disable)
+ get_options_mutable()->ORPort_set = 1;
get_options_mutable()->Tor2webMode = 0;
tt_int_op(channelpadding_decide_to_pad_channel(relay3_client), OP_EQ,
CHANNELPADDING_WONTPAD);
@@ -423,11 +441,13 @@ test_channelpadding_killonehop(void *arg)
smartlist_clear(current_md_consensus->net_params);
channelpadding_new_consensus_params(current_md_consensus);
- // Reset connections
- free_mock_network();
- setup_mock_network();
+ relay3_client->padding_enabled = 1;
+ client_relay3->padding_enabled = 1;
+
tried_to_write_cell = 0;
+ get_options_mutable()->ORPort_set = 0;
get_options_mutable()->HiddenServiceSingleHopMode = 1;
+ get_options_mutable()->HiddenServiceNonAnonymousMode = 1;
client_relay3->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
decision = channelpadding_decide_to_pad_channel(client_relay3);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
@@ -447,17 +467,34 @@ test_channelpadding_killonehop(void *arg)
(void*)"nf_pad_single_onion=0");
channelpadding_new_consensus_params(current_md_consensus);
+ // Before the client tries to pad, the relay will still pad:
+ tried_to_write_cell = 0;
+ relay3_client->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ get_options_mutable()->ORPort_set = 1;
+ get_options_mutable()->HiddenServiceSingleHopMode = 0;
+ get_options_mutable()->HiddenServiceNonAnonymousMode = 0;
+ decision = channelpadding_decide_to_pad_channel(relay3_client);
+ tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
+ tt_assert(relay3_client->pending_padding_callback);
+
+ // Wait for the timer
+ event_base_loop(tor_libevent_get_base(), 0);
+ tt_int_op(tried_to_write_cell, OP_EQ, 1);
+ tt_assert(!client_relay3->pending_padding_callback);
+
// Test client side (it should stop immediately)
+ get_options_mutable()->HiddenServiceSingleHopMode = 1;
+ get_options_mutable()->HiddenServiceNonAnonymousMode = 1;
+ /* For the relay to recieve the negotiate: */
+ get_options_mutable()->ORPort_set = 1;
decision = channelpadding_decide_to_pad_channel(client_relay3);
tt_int_op(decision, OP_EQ, CHANNELPADDING_WONTPAD);
tt_assert(!client_relay3->pending_padding_callback);
- // Reset connnections.. XXX: remove this requirement...
- free_mock_network();
- setup_mock_network();
-
// Test relay side (it should have gotten the negotiation to disable)
+ get_options_mutable()->ORPort_set = 1;
get_options_mutable()->HiddenServiceSingleHopMode = 0;
+ get_options_mutable()->HiddenServiceNonAnonymousMode = 0;
tt_int_op(channelpadding_decide_to_pad_channel(relay3_client), OP_EQ,
CHANNELPADDING_WONTPAD);
tt_assert(!relay3_client->padding_enabled);