[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [ooni-probe/master] * Moving to using @defer.inlineCallbacks for rewriting the torrc Bridge line.
commit 4a6b164cbefb5dca519ece6cfd62486c8a14206e
Author: Isis Lovecruft <isis@xxxxxxxxxxxxxx>
Date: Thu Sep 20 03:38:29 2012 +0000
* Moving to using @defer.inlineCallbacks for rewriting the torrc Bridge line.
NOT DONE YET. NOT TESTED YET.
* Moving to bridges being assets and relays being a list attached to our
TorState() instance, so that we can pass it to CustomCircuit.
TODO: Make the CustomCircuit() instance handle iteration through relay list,
and provide access to objects for unreachable and reachable relays. We
should probably check how onionoo handles this.
---
ooni/plugins/bridget.py | 134 +++++++++++++++++++++++++++++++----------------
ooni/utils/circuit.py | 18 +++---
2 files changed, 97 insertions(+), 55 deletions(-)
diff --git a/ooni/plugins/bridget.py b/ooni/plugins/bridget.py
index 192c2dd..07d7269 100644
--- a/ooni/plugins/bridget.py
+++ b/ooni/plugins/bridget.py
@@ -341,55 +341,91 @@ class BridgetTest(OONITest):
rmtree(temp, ignore_errors=True)
#@timer(self.circuit_timeout)
+ @defer.inlineCallbacks
def reconfigure_bridge(state, bridge, use_pt=False, pt_type=None):
- """Rewrite the Bridge line in our torrc."""
- log.msg("Current Bridge: %s" % bridge)
- if use_pt is False:
- state.protocol.set_conf('Bridge', bridge)
- elif use_pt and pt_type is not None:
- state.protocol.set_conf('Bridge', pt_type +' '+ bridge)
- else:
- raise PTNotFoundException
- return state.callback
+ """
+ Rewrite the Bridge line in our torrc. If use of pluggable
+ transports was specified, rewrite the line as:
+ Bridge <transport_type> <ip>:<orport>
+ Otherwise, rewrite in the standard form.
+ """
+ log.msg("Current Bridge: %s" % bridge)
+ try:
+ if use_pt is False:
+ reset_tor = yield state.protocol.set_conf('Bridge', bridge)
+ elif use_pt and pt_type is not None:
+ reset_tor = yield state.protocol.set_conf('Bridge',
+ pt_type +' '+ bridge)
+ else:
+ raise PTNotFoundException
+
+ controller_response = reset_tor.callback
+ if not controller_response:
+ defer.returnValue((state.callback, None))
+ else:
+ defer.returnValue((state.callback, controller_response))
+ except Exception, e:
+ log.msg("Reconfiguring torrc Bridge line failed with %s" % bridge)
def reconfigure_fail(*param):
log.msg("Reconfiguring TorConfig with parameters %s failed" % param)
reactor.stop()
- def remove_relays(state, bridge_list):
+ @defer.inlineCallbacks
+ def remove_public_relays(state, bridges):
"""
Remove bridges from our bridge list which are also listed as
public relays.
"""
- ips = map(lambda addr: addr.split(':',1)[0], bridge_list)
- both = set(state.relays.values()).intersection(ips)
- if len(both) > 0:
- for bridge in both:
- bridge_list.remove(bridge)
- return state.callback
+ IPs = map(lambda addr: addr.split(':',1)[0], bridges)
+ both = set(state.routers.values()).intersection(IPs)
- def remove_relays_fail(state):
- log.msg("Unable to remove public relays from the bridge list.")
+ def __remove_line__(node, bridges=bridges):
+ for line in bridges:
+ if line.startswith(node):
+ log.msg("Removing %s because it is a public relay" % node)
+ bridges.remove(line)
- def setup_fail(args):
- log.msg("Setup Failed.")
- report.update({'failed': args})
+ if len(both) > 0:
+ try:
+ updated = yield map(lambda node: __remove_line__(node), both)
+ if not updated:
+ ## XXX do these need to be state.callback?
+ defer.returnValue(state)
+ else:
+ defer.returnValue(state)
+ except Exception, e:
+ log.msg("Unable to remove public relays from bridge list:\n%s"
+ % both)
+ log.err(e)
+
+ def setup_fail(proto, bridge_list, relay_list):
+ log.err("Setup Failed: %s" % proto)
+ log.err("We were given bridge list:\n%s\nAnd our relay list:\n%s\n"
+ % (bridge_list, relay_list))
+ report.update({'setup_fail': 'FAILED',
+ 'proto': proto,
+ 'bridge_list': bridge_list,
+ 'relay_list': relay_list})
reactor.stop()
- def setup_done(proto):
+ def setup_done(proto, bridge_list, relay_list):
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 start_tor(reactor, update, torrc, to_delete, control_port,
- tor_binary, data_directory):
+ if bridge_list is not None:
+ state.post_bootstrap.addCallback(remove_public_relays, bridge_list)
+ if relay_list is not None:
+ raise NotImplemented
+ #report.update({'success': args})
+
+ def start_tor(reactor, update, torrc, to_delete, control_port, tor_binary,
+ data_directory, bridge_list=None, relay_list=None):
"""
Create a TCP4ClientEndpoint at our control_port, and connect
it to our reactor and a spawned Tor process. Compare with
:meth:`txtorcon.launch_tor` for differences.
"""
- ## XXX do we need self.reactor?
end_point = TCP4ClientEndpoint(reactor, 'localhost', control_port)
connection_creator = partial(end_point.connect, TorProtocolFactory())
process_protocol = TorProcessProtocol(connection_creator, updates)
@@ -406,9 +442,9 @@ class BridgetTest(OONITest):
except RuntimeError, e:
process_protocol.connected_cb.errback(e)
finally:
- return process_protocol.connected_cb
+ return process_protocol.connected_cb, bridge_list, relay_list
- def state_complete(state):
+ def state_complete(state, bridge_list=None, relay_list=None):
"""Called when we've got a TorState."""
log.msg("We've completely booted up a Tor version %s at PID %d"
% (state.protocol.version, state.tor_pid))
@@ -418,7 +454,12 @@ class BridgetTest(OONITest):
for circ in state.circuits.values():
log.msg("%s" % circ)
- return state
+ if bridge_list is not None and relay_list is None:
+ return state, bridge_list
+ elif bridge_list is None and relay_list is not None:
+ raise NotImplemented
+ else:
+ return state, None
def state_attach(state, relay_list):
log.msg("Setting up custom circuit builder...")
@@ -426,12 +467,12 @@ class BridgetTest(OONITest):
state.set_attacher(attacher, reactor)
state.add_circuit_listener(attacher)
- for circ in state.circuits.values():
- for relay in circ.path:
- try:
- relay_list.remove(relay)
- except KeyError:
- continue
+ #for circ in state.circuits.values():
+ # for relay in circ.path:
+ # try:
+ # relay_list.remove(relay)
+ # except KeyError:
+ # continue
## XXX how do we attach to circuits with bridges?
d = defer.Deferred()
attacher.request_circuit_build(d)
@@ -457,7 +498,6 @@ class BridgetTest(OONITest):
data_dir = mkdtemp(prefix='bridget-tordata')
delete_list.append(data_dir)
conf.DataDirectory = data_dir
- #conf.__OwningControllerProcess = os.getpid()
(fd, torrc) = mkstemp(dir=data_dir)
delete_list.append(torrc)
@@ -468,8 +508,16 @@ class BridgetTest(OONITest):
log.msg("Bridget: initiating test ... ")
- while self.bridges_remaining() > 0:
- self.current_bridge = self.bridges.pop()
+ #while self.bridges_remaining() > 0:
+ while args['bridge']:
+
+ #self.current_bridge = self.bridges.pop()
+ self.current_bridge = args['bridge']
+ try:
+ self.bridges.remove(self.current_bridge)
+ except ValueError, ve:
+ log.err(ve)
+
if self.config.config.has_key('Bridge'):
log.msg("We now have %d untested bridges..."
% self.bridges_remaining())
@@ -479,9 +527,6 @@ class BridgetTest(OONITest):
self.pt_type)
reconf.addErrback(reconfigure_fail)
state.chainDeferred(reconf)
- #reconfigure_bridge(state, self.current_bridge,
- # self.use_pt, self.pt_type)
- #current_ip = self.current_bridge.split(':', 1)[0]
else:
self.config.Bridge = self.current_bridge
@@ -499,10 +544,7 @@ class BridgetTest(OONITest):
state.addCallback(setup_done)
state.addErrback(setup_fail)
state.addBoth(remove_relays, self.bridges)
- #state.addCallback(remove_relays, self.bridges)
- #state.addErrback(remove_relays_fail)
- #state.addCallback(state_attach, self.bridges)
- #state.addErrback(state_attach_fail)
+
return state
## XXX see txtorcon.TorControlProtocol.add_event_listener we
diff --git a/ooni/utils/circuit.py b/ooni/utils/circuit.py
index 0c77dd1..6ee0720 100644
--- a/ooni/utils/circuit.py
+++ b/ooni/utils/circuit.py
@@ -3,27 +3,27 @@
# ----------
# Utilities for working with Tor circuits.
#
-# This code is largely taken from the txtorcon documentation, and as
-# such any and all credit should go to meejah.
+# This code is largely taken from attach_streams_by_country.py in the txtorcon
+# documentation, and as such any and all credit should go to meejah. Minor
+# adjustments have been made to use OONI's logging system, and to build custom
+# circuits without actually attaching streams.
#
-# :author: Mike Warren, Isis Lovecruft
+# :author: Meejah, Isis Lovecruft
# :license: see included license file
# :version: 0.1.0-alpha
#
-from zope.interface import implements
+
+import random
from ooni.lib.txtorcon import CircuitListenerMixin, IStreamAttacher
+from ooni.lib.txtorcon import TorInfo
from ooni.utils import log
-
-import random
+from zope.interface import implements
class CustomCircuit(CircuitListenerMixin):
implements(IStreamAttacher)
- from txtorcon.interface import IRouterContainer
- from txtorcon.interface import ICircuitContainer
-
def __init__(self, state):
self.state = state
self.waiting_circuits = []
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits