From a638a97806436f4685bbfd2dea33e58ddb587c2f Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Wed, 14 Sep 2016 16:21:55 -0700 Subject: [PATCH] implement connections:tcp=disabled This enables an I2P-only node, which disables TCP entirely (instead of mapping TCP to Tor, which was the only other option that reveal-IP-address=False would allow). closes ticket:2824 --- docs/configuration.rst | 8 +++++++- src/allmydata/node.py | 25 ++++++++++++++----------- src/allmydata/test/test_connections.py | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 523fa1d7c..42c10ed24 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -357,7 +357,7 @@ set the ``tub.location`` option described below. that defaults to AUTO) * ``[connections] tcp =`` is set to ``tcp`` (or left as the default), - rather than being set to ``tor`` + rather than being set to ``tor`` or ``disabled`` Connection Management @@ -415,6 +415,12 @@ To hide the Tahoe node's IP address from the servers that it uses, set the [connections] tcp = tor +You can also disable TCP hints entirely, which would be appropriate when +running an I2P-only node:: + + [connections] + tcp = disabled + (Note that I2P does not support connections to normal TCP ports, so ``[connections] tcp = i2p`` is invalid) diff --git a/src/allmydata/node.py b/src/allmydata/node.py index e0842c48b..6454cc6d9 100644 --- a/src/allmydata/node.py +++ b/src/allmydata/node.py @@ -296,19 +296,22 @@ class Node(service.MultiService): # then we remember the default mappings from tahoe.cfg self._default_connection_handlers = {"tor": "tor", "i2p": "i2p"} tcp_handler_name = self.get_config("connections", "tcp", "tcp").lower() - if tcp_handler_name not in handlers: - raise ValueError("'tahoe.cfg [connections] tcp='" - " uses unknown handler type '%s'" - % tcp_handler_name) - if not handlers[tcp_handler_name]: - raise ValueError("'tahoe.cfg [connections] tcp=' uses " - "unavailable/unimportable handler type '%s'. " - "Please pip install tahoe-lafs[%s] to fix." - % (tcp_handler_name, tcp_handler_name)) - self._default_connection_handlers["tcp"] = tcp_handler_name + if tcp_handler_name == "disabled": + self._default_connection_handlers["tcp"] = None + else: + if tcp_handler_name not in handlers: + raise ValueError("'tahoe.cfg [connections] tcp='" + " uses unknown handler type '%s'" + % tcp_handler_name) + if not handlers[tcp_handler_name]: + raise ValueError("'tahoe.cfg [connections] tcp=' uses " + "unavailable/unimportable handler type '%s'. " + "Please pip install tahoe-lafs[%s] to fix." + % (tcp_handler_name, tcp_handler_name)) + self._default_connection_handlers["tcp"] = tcp_handler_name if not self._reveal_ip: - if self._default_connection_handlers["tcp"] == "tcp": + if self._default_connection_handlers.get("tcp") == "tcp": raise PrivacyError("tcp = tcp, must be set to 'tor'") def set_tub_options(self): diff --git a/src/allmydata/test/test_connections.py b/src/allmydata/test/test_connections.py index 4398da930..e1b6689b3 100644 --- a/src/allmydata/test/test_connections.py +++ b/src/allmydata/test/test_connections.py @@ -219,6 +219,8 @@ class Connections(unittest.TestCase): self.assertEqual(n._default_connection_handlers["tcp"], "tcp") self.assertEqual(n._default_connection_handlers["tor"], "tor") self.assertEqual(n._default_connection_handlers["i2p"], "i2p") + n.set_tub_options() + n._create_tub() def test_tor(self): n = FakeNode(BASECONFIG+"[connections]\ntcp = tor\n") @@ -242,6 +244,15 @@ class Connections(unittest.TestCase): self.assertIn("'tahoe.cfg [connections] tcp='", str(e)) self.assertIn("uses unknown handler type 'unknown'", str(e)) + def test_tcp_disabled(self): + n = FakeNode(BASECONFIG+"[connections]\ntcp = disabled\n") + n.init_connections() + self.assertEqual(n._default_connection_handlers["tcp"], None) + self.assertEqual(n._default_connection_handlers["tor"], "tor") + self.assertEqual(n._default_connection_handlers["i2p"], "i2p") + n.set_tub_options() + n._create_tub() + class Privacy(unittest.TestCase): def test_flag(self): n = FakeNode(BASECONFIG) @@ -266,6 +277,14 @@ class Privacy(unittest.TestCase): e = self.assertRaises(PrivacyError, n.init_connections) self.assertEqual(str(e), "tcp = tcp, must be set to 'tor'") + def test_connections_tcp_disabled(self): + n = FakeNode(BASECONFIG+ + "[connections]\ntcp = disabled\n"+ + "[node]\nreveal-IP-address = false\n") + n.check_privacy() + n.init_connections() # passes privacy check + self.assertEqual(n._default_connection_handlers["tcp"], None) + def test_tub_location_auto(self): n = FakeNode(BASECONFIG+"[node]\nreveal-IP-address = false\n") n._portnumfile = "missing"