From b00c2d21b7bd4b2ce63ff4fa14a82b9b02dfe360 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Tue, 20 Sep 2016 13:04:06 -0700 Subject: [PATCH] test tub.port with multiple endpoints, add docs I think the preferred way to listen on both IPv4 and IPv6 will be to use "--port=tcp:PORT,tcp6:PORT". This is now reflected in the docs. refs ticket:867 --- docs/configuration.rst | 15 ++++++----- src/allmydata/test/test_node.py | 44 ++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 42c10ed24..80b411869 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -138,12 +138,15 @@ set the ``tub.location`` option described below. ``http://127.0.0.1:3456/static/foo.html`` will serve the contents of ``BASEDIR/public_html/foo.html`` . -``tub.port = (endpoint specification string or "disabled", optional)`` +``tub.port = (endpoint specification strings or "disabled", optional)`` This controls which port the node uses to accept Foolscap connections - from other nodes. It is parsed as a Twisted "server endpoint descriptor", - which accepts values like ``tcp:12345`` and - ``tcp:23456:interface=127.0.0.1``. + from other nodes. It is parsed as a comma-separated list of Twisted + "server endpoint descriptor" strings, each of which is a value like + ``tcp:12345`` and ``tcp:23456:interface=127.0.0.1``. + + To listen on multiple ports at once (e.g. both TCP-on-IPv4 and + TCP-on-IPv6), use something like ``tcp:12345,tcp6:12345``. If ``tub.port`` is the string ``disabled``, the node will not listen at all, and thus cannot accept connections from other nodes. If ``[storage] @@ -156,8 +159,8 @@ set the ``tub.location`` option described below. be used as a TCP port number, like ``tcp:%d`` (which will accept connections on all interfaces). However ``tub.port`` cannot be ``0`` or ``tcp:0`` (older versions accepted this, but the node is no longer - willing to ask Twisted to allocate port numbers in this way). To - automatically allocate a TCP port, leave ``tub.port`` blank. + willing to ask Twisted to allocate port numbers in this way). If + ``tub.port`` is present, it may not be empty. If the ``tub.port`` config key is not provided (e.g. ``tub.port`` appears nowhere in the ``[node]`` section, or is commented out), the node will diff --git a/src/allmydata/test/test_node.py b/src/allmydata/test/test_node.py index d027d8c95..6b4b4f825 100644 --- a/src/allmydata/test/test_node.py +++ b/src/allmydata/test/test_node.py @@ -1,5 +1,5 @@ -import os, stat, sys, time, mock +import os, stat, sys, time, mock, base64 from twisted.trial import unittest from twisted.internet import defer @@ -322,6 +322,48 @@ ENABLE_HELPER = """ enabled = true """ +class FakeTub: + def __init__(self): + self.tubID = base64.b32encode("foo") + self.listening_ports = [] + def setOption(self, name, value): pass + def removeAllConnectionHintHandlers(self): pass + def addConnectionHintHandler(self, hint_type, handler): pass + def listenOn(self, what): + self.listening_ports.append(what) + def setLocation(self, location): pass + def setServiceParent(self, parent): pass + +class MultiplePorts(unittest.TestCase): + def test_multiple_ports(self): + n = EmptyNode() + n.basedir = self.mktemp() + n.config_fname = os.path.join(n.basedir, "tahoe.cfg") + os.mkdir(n.basedir) + os.mkdir(os.path.join(n.basedir, "private")) + port1 = iputil.allocate_tcp_port() + port2 = iputil.allocate_tcp_port() + port = ("tcp:%d:interface=127.0.0.1,tcp:%d:interface=127.0.0.1" % + (port1, port2)) + location = "tcp:localhost:%d,tcp:localhost:%d" % (port1, port2) + with open(n.config_fname, "w") as f: + f.write(BASE_CONFIG) + f.write("tub.port = %s\n" % port) + f.write("tub.location = %s\n" % location) + # we're doing a lot of calling-into-setup-methods here, it might be + # better to just create a real Node instance, I'm not sure. + n.read_config() + n.check_privacy() + n.services = [] + n.init_connections() + n.set_tub_options() + t = FakeTub() + with mock.patch("allmydata.node.Tub", return_value=t): + n.create_main_tub() + self.assertEqual(t.listening_ports, + ["tcp:%d:interface=127.0.0.1" % port1, + "tcp:%d:interface=127.0.0.1" % port2]) + class ClientNotListening(unittest.TestCase): def test_disabled(self): basedir = "test_node/test_disabled"