[or-cvs] [torflow/master 70/92] Allow multiple --exit arguments to be specified
mikeperry at torproject.org
mikeperry at torproject.org
Sat Aug 21 05:14:01 UTC 2010
Author: John M. Schanck <john at anomos.info>
Date: Thu, 12 Aug 2010 02:50:24 -0400
Subject: Allow multiple --exit arguments to be specified
Commit: 12cc26a132424186a625708ba59d1f5636f5a4f6
Also unifies soat's behavior when --exit is present and when
it is not.
---
NetworkScanners/ExitAuthority/soat.py | 94 +++++++++++++++++++--------------
1 files changed, 54 insertions(+), 40 deletions(-)
diff --git a/NetworkScanners/ExitAuthority/soat.py b/NetworkScanners/ExitAuthority/soat.py
index ba9d914..1af5856 100755
--- a/NetworkScanners/ExitAuthority/soat.py
+++ b/NetworkScanners/ExitAuthority/soat.py
@@ -187,11 +187,15 @@ class NullRedirectHandler(urllib2.HTTPRedirectHandler):
http_error_302 = http_error_303 = http_error_307 = http_error_301
class ExitScanHandler(ScanSupport.ScanHandler):
- def __init__(self, c, selmgr, strm_selector):
+ def __init__(self, c, selmgr, strm_selector, fixed_exits=[]):
ScanSupport.ScanHandler.__init__(self, c, selmgr,
strm_selector=strm_selector)
self.rlock = threading.Lock()
self.new_nodes=True
+ self.fixed_exits = set([])
+ for f in fixed_exits:
+ x = self.name_to_key.get(f, f)
+ self.fixed_exits.add(x.lstrip("$"))
def has_new_nodes(self):
# XXX: Hrmm.. could do this with conditions instead..
@@ -216,7 +220,10 @@ class ExitScanHandler(ScanSupport.ScanHandler):
[FlagsRestriction(["Running", "Valid", "Fast"], ["BadExit"]),
MinBWRestriction(min_node_bw),
ExitPolicyRestriction('255.255.255.255', port)])
- cond._result = [x for x in self.sorted_r if restriction.r_is_ok(x)]
+ if self.fixed_exits: # XXX: Can this be done with NodeRestrictions?
+ cond._result = [x for x in self.sorted_r if restriction.r_is_ok(x) and x.idhex in self.fixed_exits]
+ else:
+ cond._result = [x for x in self.sorted_r if restriction.r_is_ok(x)]
self._sanity_check(cond._result)
cond.notify()
cond.release()
@@ -247,6 +254,25 @@ class ExitScanHandler(ScanSupport.ScanHandler):
self.rlock.release()
plog("DEBUG", "newdesc_event end")
+ def select_exit_from_set(self, exits):
+ # Randomly selects from exits until a valid one is found
+ # Returns exit idhex or None if no exit is found
+ current_exit_idhex = None
+ rand_ord_exits = list(exits)
+ random.shuffle(rand_ord_exits)
+ for e in rand_ord_exits:
+ current_exit_idhex = e
+ plog("DEBUG", "Requesting $"+current_exit_idhex+" for next set of tests.")
+ self.set_exit_node("$"+current_exit_idhex)
+ if self.selmgr.bad_restrictions:
+ plog("DEBUG", "$"+current_exit_idhex+" is not available.")
+ exits.remove(current_exit_idhex)
+ current_exit_idhex = None
+ else:
+ self.new_exit()
+ break
+ return current_exit_idhex
+
# FIXME: Hrmm is this in the right place?
def check_all_exits_port_consistency(self):
'''
@@ -2835,7 +2861,7 @@ def cleanup(c, l, f):
except TorCtl.TorCtlClosed:
pass
-def setup_handler(out_dir, cookie_file):
+def setup_handler(out_dir, cookie_file, fixed_exits=[]):
plog('INFO', 'Connecting to Tor at '+TorUtil.control_host+":"+str(TorUtil.control_port))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TorUtil.control_host,TorUtil.control_port))
@@ -2843,7 +2869,7 @@ def setup_handler(out_dir, cookie_file):
c.debug(file(out_dir+"/control.log", "w", buffering=0))
c.authenticate_cookie(file(cookie_file, "r"))
l = c.get_option("__LeaveStreamsUnattached")[0][1]
- h = ExitScanHandler(c, __selmgr, PathSupport.SmartSocket.StreamSelector)
+ h = ExitScanHandler(c, __selmgr, PathSupport.SmartSocket.StreamSelector, fixed_exits)
c.set_event_handler(h)
#c.set_periodic_timer(2.0, "PULSE")
@@ -2901,11 +2927,11 @@ def main(argv):
do_dns_rebind = ('--dnsrebind','') in flags
do_consistency = ('--policies','') in flags
- scan_exit=None
+ fixed_exits=[]
fixed_targets=[]
for flag in flags:
if flag[0] == "--exit":
- scan_exit = flag[1]
+ fixed_exits.append(flag[1])
if flag[0] == "--target":
fixed_targets.append(flag[1])
if flag[0] == "--pernode":
@@ -2929,7 +2955,8 @@ def main(argv):
try:
global scanhdlr
(c,scanhdlr) = setup_handler(data_dir,
- data_dir+"tor/control_auth_cookie")
+ data_dir+"tor/control_auth_cookie",
+ fixed_exits)
except Exception, e:
traceback.print_exc()
plog("WARN", "Can't connect to Tor: "+str(e))
@@ -3051,23 +3078,6 @@ def main(argv):
for test in tests.itervalues():
test.rewind()
- if scan_exit:
- scanhdlr.set_exit_node(scan_exit)
- if scanhdlr.selmgr.bad_restrictions:
- plog("NOTICE", "Requested exit node, %s, is not available. Exiting." % scan_exit)
- return
- plog("NOTICE", "Scanning only "+scan_exit)
- scanhdlr.new_exit()
- tests_done = 0
- while tests_done < len(tests):
- for test in tests.values():
- if test.finished():
- tests_done += 1
- continue
- result = test.run_test()
- plog("INFO", test.proto+" test via "+scan_exit+" has result "+str(result))
- return
-
# start testing
while 1:
avail_tests = tests.values()
@@ -3095,12 +3105,10 @@ def main(argv):
scanhdlr._sanity_check(map(lambda id: test.node_map[id],
test.nodes))
- if common_nodes:
- current_exit_idhex = random.choice(list(common_nodes))
- plog("DEBUG", "Chose to run "+str(n_tests)+" tests via "+current_exit_idhex+" (tests share "+str(len(common_nodes))+" exit nodes)")
-
- scanhdlr.set_exit_node("$"+current_exit_idhex)
- scanhdlr.new_exit()
+ any_avail = bool(common_nodes)
+ if any_avail:
+ current_exit_idhex = scanhdlr.select_exit_from_set(common_nodes)
+ plog("DEBUG", "Chose to run "+str(n_tests)+" tests via "+str(current_exit_idhex)+" (tests share "+str(len(common_nodes))+" exit nodes)")
for test in to_run:
result = test.run_test()
if result != TEST_INCONCLUSIVE:
@@ -3108,20 +3116,23 @@ def main(argv):
datahandler.saveTest(test)
plog("INFO", test.proto+" test via "+current_exit_idhex+" has result "+str(result))
plog("INFO", test.proto+" attempts: "+str(test.tests_run)+". Completed: "+str(test.total_nodes - test.scan_nodes)+"/"+str(test.total_nodes)+" ("+str(test.percent_complete())+"%)")
- else:
+ elif len(to_run) > 1:
plog("NOTICE", "No nodes in common between "+", ".join(map(lambda t: t.proto, to_run)))
for test in to_run:
if test.finished():
continue
- current_exit = test.get_node()
- scanhdlr.set_exit_node("$"+current_exit_idhex)
- scanhdlr.new_exit()
- result = test.run_test()
- if result != TEST_INCONCLUSIVE:
- test.mark_chosen(current_exit_idhex, result)
- datahandler.saveTest(test)
- plog("INFO", test.proto+" test via "+current_exit_idhex+" has result "+str(result))
- plog("INFO", test.proto+" attempts: "+str(test.tests_run)+". Completed: "+str(test.total_nodes - test.scan_nodes)+"/"+str(test.total_nodes)+" ("+str(test.percent_complete())+"%)")
+ current_exit_idhex = scanhdlr.select_exit_from_set(test.nodes().copy())
+ if current_exit_idhex:
+ any_avail = True
+ result = test.run_test()
+ if result != TEST_INCONCLUSIVE:
+ test.mark_chosen(current_exit_idhex, result)
+ datahandler.saveTest(test)
+ plog("INFO", test.proto+" test via "+current_exit_idhex+" has result "+str(result))
+ plog("INFO", test.proto+" attempts: "+str(test.tests_run)+". Completed: "+str(test.total_nodes - test.scan_nodes)+"/"+str(test.total_nodes)+" ("+str(test.percent_complete())+"%)")
+ else:
+ plog("INFO", "No available exits for "+test.proto+" test.")
+ continue
# Check each test for rewind
for test in tests.itervalues():
@@ -3141,6 +3152,9 @@ def main(argv):
if all_finished:
plog("NOTICE", "All tests have finished. Exiting\n")
return
+ if not any_avail:
+ plog("NOTICE", "Not enough exits were available to complete the tests. Exiting")
+ return
# initiate the program
#
--
1.7.1
More information about the tor-commits
mailing list