There is now a single script called "rttprober"[0] that depends on a patched[1] Tor client running a certain configuration[2]. The goal is to measure RTTs of Tor circuits. It takes a few parameters as input: an authenticated Stem Tor controller for communication with the Tor client..
Hi ra, glad to see that you're using stem! If you have any questions, suggestions, feature requests, or would like a code review then let me know. Few things I spotted...
# Stem does not do that yet. # See https://trac.torproject.org/projects/tor/ticket/7953 if is_valid_fingerprint(fingerprint): query = "ns/id/%s" % fingerprint else: raise ValueError("Invalid fingerprint: %s." % fingerprint) desc = self._controller.get_info(query) return RouterStatusEntryV3(desc)
As of just four weeks ago the Controller started providing v3 responses, so you can replace this with "self._controller.get_network_status(fingerprint)"...
https://gitweb.torproject.org/stem.git/commitdiff/003fa8e
circ.build_flags.count('IS_INTERNAL') == 0
This would more commonly be done as...
'IS_INTERNAL' not in circ.build_flags
try: controller.reset_conf("__DisablePredictedCircuits") controller.reset_conf("__LeaveStreamsUnattached") controller.close() except NameError: pass
What raises a NameError?
# close circuit, but ignore if it does not exist anymore try: self._controller.get_circuit(self._cid) self._controller.close_circuit(self._cid) except (ValueError, InvalidArguments): pass
What is the purpose of the get_circuit() call? If it's not superfluous then you can provide a default argument to prevent it from raising an exception (just about every getter allows for one). Also, you can omit exception types to catch everything (if you'd like to ignore all errors). For instance, in this case...
self._controller.get_circuit(self._cid, None)
try: self._controller.close_circuit(self._cid) except: pass
try: controller = Controller.from_port() except SocketError: sys.stderr.write("ERROR: Couldn't connect to Tor.\n") sys.exit(1) controller.authenticate()
This is certainly a fine way of doing it, but you might want to also look at connection.connect_port()...
https://stem.torproject.org/api/connection.html#stem.connection.connect_port
It is intended to be a quick and easy method of getting a Controller for command-line applications. For instance, it will present a password prompt if tor is configured to use password authentication. Just realized I should have included it in a tutorial somewhere...
Your code looks great! If you wouldn't mind I'd love to reference it on stem's examples page...
https://stem.torproject.org/tutorials/double_double_toil_and_trouble.html
Shall I reference 'https://bitbucket.org/ra_/tor-rtt/' or do you anticipate your project having a more permanent home? (this might be a question for Mike as much as you)
Cheers! -Damian