[Pkg-privacy-commits] [txtorcon] 20/96: Wait for descriptor upload on HiddenSerivce .listen()
Jérémy Bobbio
lunar at moszumanska.debian.org
Sun Sep 6 18:33:34 UTC 2015
This is an automated email from the git hooks/post-receive script.
lunar pushed a commit to branch master
in repository txtorcon.
commit 4e106e21ae93bdeadad1d9a6142712b7e25a5008
Author: meejah <meejah at meejah.ca>
Date: Sat Jan 17 00:30:04 2015 -0700
Wait for descriptor upload on HiddenSerivce .listen()
We wait for the right text to appear in an INFO message from Tor -- fragile,
but the only way to determine if your hidden service descriptor has been
uploaded to an HSDir
Also refactor a test so it gets the 650 INFO events we have to send now.
---
test/test_endpoints.py | 29 +++++++++++++----------------
test/test_torconfig.py | 19 ++++++++++++++++++-
test/test_torinfo.py | 1 +
txtorcon/endpoints.py | 31 ++++++++++++++++++++++++++++---
4 files changed, 60 insertions(+), 20 deletions(-)
diff --git a/test/test_endpoints.py b/test/test_endpoints.py
index 19ea38c..c4ceed9 100644
--- a/test/test_endpoints.py
+++ b/test/test_endpoints.py
@@ -45,6 +45,11 @@ class EndpointTests(unittest.TestCase):
endpoints._global_tor_lock = defer.DeferredLock()
self.reactor = FakeReactorTcp(self)
self.protocol = FakeControlProtocol([])
+ self.protocol.event_happened(
+ 'INFO',
+ 'connection_dir_client_reached_eof(): Uploaded rendezvous '\
+ 'descriptor (status 200 ("Service descriptor (v2) stored"))'
+ )
self.config = TorConfig(self.protocol)
self.protocol.answers.append('config/names=\nHiddenServiceOptions Virtual')
self.protocol.answers.append('HiddenServiceOptions')
@@ -185,32 +190,24 @@ class EndpointTests(unittest.TestCase):
def test_already_bootstrapped(self):
self.config.bootstrap()
-
ep = TCPHiddenServiceEndpoint(self.reactor, self.config, 123)
d = ep.listen(NoOpProtocolFactory())
return d
@defer.inlineCallbacks
def test_explicit_data_dir(self):
- config = TorConfig()
- td = tempfile.mkdtemp()
- ep = TCPHiddenServiceEndpoint(self.reactor, config, 123, td)
-
- # fake out some things so we don't actually have to launch + bootstrap
- class FakeTorProcessProtocol(object):
- tor_protocol = self.reactor.protocol
- process = FakeTorProcessProtocol()
- ep._launch_tor = Mock(return_value=process)
- config._update_proto(Mock())
- config.bootstrap()
- yield config.post_bootstrap
+ config = TorConfig(self.protocol)
+ ep = TCPHiddenServiceEndpoint(self.reactor, config, 123, '/dev/null')
# make sure listen() correctly configures our hidden-serivce
# with the explicit directory we passed in above
- port = yield ep.listen(NoOpProtocolFactory())
+ d = ep.listen(NoOpProtocolFactory())
+ def foo(fail):
+ print "ERROR", fail
+ d.addErrback(foo)
+ port = yield d
self.assertEqual(1, len(config.HiddenServices))
- self.assertEqual(config.HiddenServices[0].dir, td)
- shutil.rmtree(td)
+ self.assertEqual(config.HiddenServices[0].dir, '/dev/null')
def test_failure(self):
self.reactor.failures = 1
diff --git a/test/test_torconfig.py b/test/test_torconfig.py
index cdbbeda..94a3d37 100644
--- a/test/test_torconfig.py
+++ b/test/test_torconfig.py
@@ -44,7 +44,18 @@ class FakeControlProtocol:
self.post_bootstrap = defer.succeed(self)
self.on_disconnect = defer.Deferred()
self.sets = []
- self.events = {}
+ self.events = {} # event type -> callback
+ self.pending_events = {} # event type -> list
+
+ def event_happened(self, event_type, *args):
+ '''
+ Use this in your tests to send 650 events when an event-listener is added.
+ XXX Also if we've *already* added one? Do that if there's a use-case for it
+ '''
+ if event_type in self.pending_events:
+ self.pending_events[event_type].append(args)
+ else:
+ self.pending_events[event_type] = [args]
def answer_pending(self, answer):
d = self.pending[0]
@@ -80,6 +91,12 @@ class FakeControlProtocol:
def add_event_listener(self, nm, cb):
self.events[nm] = cb
+ if nm in self.pending_events:
+ for event in self.pending_events[nm]:
+ cb(*event)
+
+ def remove_event_listener(self, nm, cb):
+ del self.events[nm]
class CheckAnswer:
diff --git a/test/test_torinfo.py b/test/test_torinfo.py
index 5cd7958..8610b7c 100644
--- a/test/test_torinfo.py
+++ b/test/test_torinfo.py
@@ -14,6 +14,7 @@ class FakeControlProtocol:
def __init__(self, answers):
self.answers = answers
+ self.pending = []
self.post_bootstrap = defer.succeed(self)
def get_info_raw(self, info):
diff --git a/txtorcon/endpoints.py b/txtorcon/endpoints.py
index 4aff66b..6d78394 100644
--- a/txtorcon/endpoints.py
+++ b/txtorcon/endpoints.py
@@ -357,6 +357,11 @@ class TCPHiddenServiceEndpoint(object):
FIXME TODO: also listen for an INFO-level Tor message (does
exist, #tor-dev says) that indicates the hidden service's
descriptor is published.
+
+ It is "connection_dir_client_reached_eof(): Uploaded
+ rendezvous descriptor (status 200 ("Service descriptor (v2)
+ stored"))" at INFO level.
+
"""
self.protocolfactory = protocolfactory
@@ -378,15 +383,35 @@ class TCPHiddenServiceEndpoint(object):
# NOTE at some point, we can support unix sockets here
# once Tor does. See bug #XXX
+
+ # specifically NOT creating the hidden-service dir; letting
+ # Tor do it will more-likely result in a usable situation...
if not os.path.exists(self.hidden_service_dir):
- log.msg('Creating "%s".' % self.hidden_service_dir)
- os.makedirs(self.hidden_service_dir)
+ log.msg('Noting that "%s" does not exist; letting Tor create it.' % self.hidden_service_dir)
+
+ # listen for the descriptor upload event
+ info_callback = defer.Deferred()
+ def info_event(msg):
+ # XXX giant hack here; Right Thing would be to implement a
+ # "real" event in Tor and listen for that.
+ if 'Service descriptor (v2) stored' in msg:
+ info_callback.callback(None)
+ self.config.protocol.add_event_listener('INFO', info_event)
+
self.hiddenservice = HiddenService(
self.config, self.hidden_service_dir,
- ['%d 127.0.0.1:%d' % (self.public_port, self.local_port)])
+ ['%d 127.0.0.1:%d' % (self.public_port, self.local_port)],
+ group_readable=1)
self.config.HiddenServices.append(self.hiddenservice)
yield self.config.save()
+ self._tor_progress_update(100.0, 'wait_descriptor',
+ 'Waiting for descriptor upload...')
+ yield info_callback # awaits an INFO log-line from Tor .. sketchy
+ yield self.config.protocol.remove_event_listener('INFO', info_event)
+ self._tor_progress_update(100.0, 'wait_descriptor',
+ 'At least one descriptor uploaded.')
+
log.msg(
'Started hidden service "%s" on port %d' %
(self.onion_uri, self.public_port))
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/txtorcon.git
More information about the Pkg-privacy-commits
mailing list