[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [ooni-probe/master] There's still a problem with Tor's DataDirectory not being found, but it only asks for the consensus once per list of bridges/relays, i.e. once for every time bridget is run. This is still not optimal and should be fixed.
commit 859f9399455975a5d828427ede1d7e3662f1e591
Author: Isis Lovecruft <isis@xxxxxxxxxxxxxx>
Date: Thu Sep 13 12:41:39 2012 +0000
There's still a problem with Tor's DataDirectory not being found, but it only asks for the consensus once per list of bridges/relays, i.e. once for every time bridget is run. This is still not optimal and should be fixed.
The CustomCircuit class needs to be called as path=[] in reconf_controller(), but this should only be relevant when testing relays.
---
ooni/plugins/bridget.py | 191 +++++++++++++++++++++++++----------------------
1 files changed, 101 insertions(+), 90 deletions(-)
diff --git a/ooni/plugins/bridget.py b/ooni/plugins/bridget.py
index 2a7d573..a53630c 100644
--- a/ooni/plugins/bridget.py
+++ b/ooni/plugins/bridget.py
@@ -16,9 +16,10 @@ from __future__ import with_statement
from zope.interface import implements
from twisted.python import usage
from twisted.plugin import IPlugin
-from twisted.internet import reactor, error
+from twisted.internet import defer, error, reactor
import random
+import sys
try:
from ooni.lib.txtorcon import CircuitListenerMixin, IStreamAttacher
@@ -61,9 +62,11 @@ class BridgetArgs(usage.Options):
optFlags = [['random', 'x', 'Randomize control and socks ports']]
def postOptions(self):
+ ## We can't test pluggable transports without bridges
if self['transport'] and not self['bridges']:
e = "Pluggable transport requires the bridges option"
raise usage.UsageError, e
+ ## We can't use random and static port simultaneously
if self['socks'] and self['control']:
if self['random']:
e = "Unable to use random and specific ports simultaneously"
@@ -199,43 +202,6 @@ class BridgetTest(OONITest):
options = BridgetArgs
blocking = False
- def load_assets(self):
- """
- Load bridges and/or relays from files given in user options. Bridges
- should be given in the form IP:ORport. We don't want to load these as
- assets, because it's inefficient to start a Tor process for each one.
- """
- assets = {}
- self.bridge_list = []
- self.relay_list = []
-
- ## XXX fix me
- ## we should probably find a more memory nice way to load addresses,
- ## in case the files are really large
- if self.local_options:
- if self.local_options['bridges']:
- log.msg("Loading bridge information from %s ..."
- % self.local_options['bridges'])
- with open(self.local_options['bridges']) as bridge_file:
- for line in bridge_file.readlines():
- if line.startswith('#'):
- continue
- else:
- self.bridge_list.append(line.replace('\n',''))
- assets.update({'bridges': self.bridge_list})
-
- if self.local_options['relays']:
- log.msg("Loading relay information from %s ..."
- % self.local_options['relays'])
- with open(options['relays']) as relay_file:
- for line in relay_file.readlines():
- if line.startswith('#'):
- continue
- else:
- self.relay_list.append(line.replace('\n',''))
- assets.update({'relays': self.relay_list})
- return assets
-
def initialize(self):
"""
Extra initialization steps. We only want one child Tor process
@@ -257,6 +223,10 @@ class BridgetTest(OONITest):
options = self.local_options
self.config = TorConfig()
+ ## Don't run the experiment if we don't have anything to test
+ if not options['bridges'] and not options['relays']:
+ self.suicide = True
+
if options['bridges']:
self.config.UseBridges = 1
@@ -300,8 +270,42 @@ class BridgetTest(OONITest):
self.config.ControlPort = self.control_port
self.config.save()
- print self.config.create_torrc()
- report = {'tor_config': self.config.config}
+ def load_assets(self):
+ """
+ Load bridges and/or relays from files given in user options. Bridges
+ should be given in the form IP:ORport. We don't want to load these as
+ assets, because it's inefficient to start a Tor process for each one.
+ """
+ assets = {}
+ self.bridge_list = []
+ self.relay_list = []
+
+ ## XXX fix me
+ ## we should probably find a more memory nice way to load addresses,
+ ## in case the files are really large
+ if self.local_options:
+ if self.local_options['bridges']:
+ log.msg("Loading bridge information from %s ..."
+ % self.local_options['bridges'])
+ with open(self.local_options['bridges']) as bridge_file:
+ for line in bridge_file.readlines():
+ if line.startswith('#'):
+ continue
+ else:
+ self.bridge_list.append(line.replace('\n',''))
+ assets.update({'bridges': self.bridge_list})
+
+ if self.local_options['relays']:
+ log.msg("Loading relay information from %s ..."
+ % self.local_options['relays'])
+ with open(options['relays']) as relay_file:
+ for line in relay_file.readlines():
+ if line.startswith('#'):
+ continue
+ else:
+ self.relay_list.append(line.replace('\n',''))
+ assets.update({'relays': self.relay_list})
+ return assets
def experiment(self, args):
"""
@@ -317,75 +321,83 @@ class BridgetTest(OONITest):
this has a :class:`ooni.lib.txtorcon.torcontol.TorControlProtocol
<TorControlProtocol>` instance as .protocol.
"""
- log.msg("Bridget: initiating test ... ")
-
from ooni.lib.txtorcon import TorProtocolFactory, TorConfig, TorState
from ooni.lib.txtorcon import DEFAULT_VALUE, launch_tor
- log.msg("Starting Tor ...")
-
- def setup_failed(args):
- log.msg("Setup Failed.")
- report.update({'failed': args})
- reactor.stop()
-
- def setup_complete(proto):
- log.msg("Setup Complete: %s" % proto)
- state = TorState(proto.tor_protocol)
- state.post_bootstrap.addCallback(state_complete).addErrback(setup_failed)
- report.update({'success': args})
-
def bootstrap(ctrl):
"""
Launch a Tor process with the TorConfig instance returned from
initialize().
"""
conf = TorConfig(ctrl)
- conf.post_bootstrap.addCallback(setup_complete).addErrback(setup_failed)
+ conf.post_bootstrap.addCallback(setup_done).addErrback(setup_fail)
log.msg("Tor process connected, bootstrapping ...")
- def updates(prog, tag, summary):
- log.msg("%d%%: %s" % (prog, summary))
-
- def reconfigure_controller(conf, bridge):
+ def reconf_controller(conf, bridge):
## if bridges and relays, use one bridge then build a circuit
## from three relays
conf.Bridge = bridge
## XXX do we need a SIGHUP to restart?
- ## XXX see txtorcon.TorControlProtocol.add_event_listener we may not
- ## need full CustomCircuit class
-
- ## if bridges only, try one bridge at a time, but don't build
- ## circuits, just return
+ ## XXX see txtorcon.TorControlProtocol.add_event_listener we
+ ## may not need full CustomCircuit class
- ## if relays only, build circuits from relays
+ ## if bridges only, try one bridge at a time, but don't build
+ ## circuits, just return
+ ## if relays only, build circuits from relays
- def reconfigure_failed(args):
+ def reconf_fail(args):
log.msg("Reconfiguring Tor config with args %s failed" % args)
reactor.stop()
-
- if len(self.bridge_list) >= 1:
- for bridge in self.bridge_list:
- try:
- print "BRIDGE IS %s" % bridge
- reconfigure_controller(self.config, bridge)
- except:
- reconfigure_failed(bridge)
-
- ## :return: a Deferred which callbacks with a TorProcessProtocol
- ## connected to the fully-bootstrapped Tor; this has a
- ## txtorcon.TorControlProtocol instance as .protocol.
- d = launch_tor(self.config,
- reactor,
- progress_updates=updates,
- tor_binary=self.tor_binary)
- d.addCallback(bootstrap, self.config)
- d.addErrback(setup_failed)
- ## 4 build circuits
-
- #print "Tor process ID: %s" % d.transport.pid
- return d
+
+ def setup_fail(args):
+ log.msg("Setup Failed.")
+ report.update({'failed': args})
+ reactor.stop()
+
+ def setup_done(proto):
+ log.msg("Setup Complete: %s" % proto)
+ state = TorState(proto.tor_protocol)
+ state.post_bootstrap.addCallback(state_complete).addErrback(setup_fail)
+ report.update({'success': args})
+
+ def updates(prog, tag, summary):
+ log.msg("%d%%: %s" % (prog, summary))
+
+ if len(args) == 0:
+ log.msg("Bridget needs lists of bridges and/or relays to test!")
+ log.msg("Exiting ...")
+ d = sys.exit()
+ return d
+
+ else:
+ if len(self.bridge_list) >= 1:
+ for bridge in self.bridge_list:
+ try:
+ print "BRIDGE IS %s" % bridge
+ reconf_controller(self.config, bridge)
+ except:
+ reconf_fail(bridge)
+
+ log.msg("Bridget: initiating test ... ")
+ log.msg("Using the following as our torrc:\n%s"
+ % self.config.create_torrc())
+ report = {'tor_config': self.config.config}
+ log.msg("Starting Tor ...")
+
+ ## :return: a Deferred which callbacks with a TorProcessProtocol
+ ## connected to the fully-bootstrapped Tor; this has a
+ ## txtorcon.TorControlProtocol instance as .protocol.
+ d = launch_tor(self.config,
+ reactor,
+ progress_updates=updates,
+ tor_binary=self.tor_binary)
+ d.addCallback(bootstrap, self.config)
+ d.addErrback(setup_fail)
+ ## now build circuits
+
+ #print "Tor process ID: %s" % d.transport.pid
+ return d
## So that getPlugins() can register the Test:
bridget = BridgetTest(None, None, None)
@@ -399,7 +411,6 @@ bridget = BridgetTest(None, None, None)
##
## TODO:
## o add option for any kwarg=arg self.config setting
-## o add DataDirectory option?
## o cleanup documentation
## o check if bridges are public relays
## o take bridge_desc file as input, also be able to give same
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits