commit ee3bca1e15e4bc927a296b52df5c2706ce087b52 Author: Damian Johnson atagar@torproject.org Date: Wed May 23 12:03:08 2018 -0700
Example script for downloading descriptors
Providing a simple demo in our examples of downloading descriptors from ORPort or DirPorts. Handy little script in its own right. :P
% python download_descriptor.py --type consensus --dirport 128.31.0.34:9131 Downloading consensus descriptor from 128.31.0.34:9131...
r moria1 lpXfw1/+uGEym58asExGOXAgzjE IpcU7dolas8+Q+oAzwgvZIWx7PA 2018-05-23 02:41:25 128.31.0.34 9101 9131 s Authority Fast Running Stable V2Dir Valid v Tor 0.3.3.5-rc-dev pr Cons=1-2 Desc=1-2 DirCache=1-2 HSDir=1-2 HSIntro=3-4 HSRend=1-2 Link=1-5 LinkAuth=1,3 Microdesc=1-2 Relay=1-2 w Bandwidth=20 Unmeasured=1 p reject 1-65535
Requested by starlight on...
https://lists.torproject.org/pipermail/tor-relays/2018-May/015270.html --- docs/_static/example/download_descriptor.py | 131 ++++++++++++++++++++++ docs/change_log.rst | 1 + docs/tutorials/double_double_toil_and_trouble.rst | 4 + docs/tutorials/examples/download_descriptor.rst | 27 +++++ 4 files changed, 163 insertions(+)
diff --git a/docs/_static/example/download_descriptor.py b/docs/_static/example/download_descriptor.py new file mode 100644 index 00000000..7e712ecf --- /dev/null +++ b/docs/_static/example/download_descriptor.py @@ -0,0 +1,131 @@ +""" +Simple script to dowload a descriptor from Tor's ORPort or DirPort. +""" + +import collections +import getopt +import sys + +import stem +import stem.descriptor.remote +import stem.util.connection +import stem.util.tor_tools + +# By default downloading moria1's server descriptor from itself. + +DEFAULT_ARGS = { + 'descriptor_type': 'server', + 'fingerprint': '9695DFC35FFEB861329B9F1AB04C46397020CE31', + 'download_from': stem.DirPort('128.31.0.34', 9131), + 'print_help': False, +} + +VALID_TYPES = ('server', 'extrainfo', 'consensus') + +HELP_TEXT = """\ +Downloads a descriptor through Tor's ORPort or DirPort. + + -t, --type TYPE descriptor type to download, options are: + %s + -f, --fingerprint FP relay to download the descriptor of + --orport ADDRESS:PORT ORPort to download from + --dirport ADDRESS:PORT DirPort to download from + -h, --help presents this help +""" % ', '.join(VALID_TYPES) + + +def parse(argv): + """ + Parses our arguments, providing a named tuple with their values. + + :param list argv: input arguments to be parsed + + :returns: a **named tuple** with our parsed arguments + + :raises: **ValueError** if we got an invalid argument + """ + + args = dict(DEFAULT_ARGS) + + try: + recognized_args, unrecognized_args = getopt.getopt(argv, 't:f:h', ['type=', 'fingerprint=', 'orport=', 'dirport=', 'help']) + + if unrecognized_args: + raise getopt.GetoptError("'%s' aren't recognized arguments" % "', '".join(unrecognized_args)) + except Exception as exc: + raise ValueError('%s (for usage provide --help)' % exc) + + for opt, arg in recognized_args: + if opt in ('-t', '--type'): + if arg not in VALID_TYPES: + raise ValueError("'%s' isn't a recognized decriptor type, options are: %s" % (arg, ', '.join(VALID_TYPES))) + + args['descriptor_type'] = arg + elif opt in ('-f', '--fingerprint'): + if not stem.util.tor_tools.is_valid_fingerprint(arg): + raise ValueError("'%s' isn't a relay fingerprint" % arg) + + args['fingerprint'] = arg + elif opt in ('--orport', '--dirport'): + if ':' not in arg: + raise ValueError("'%s' should be of the form 'address:port'" % arg) + + address, port = arg.rsplit(':', 1) + + if not stem.util.connection.is_valid_ipv4_address(address): + raise ValueError("'%s' isn't a valid IPv4 address" % address) + elif not stem.util.connection.is_valid_port(port): + raise ValueError("'%s' isn't a valid port number" % port) + + endpoint_class = stem.ORPort if opt == '--orport' else stem.DirPort + args['download_from'] = endpoint_class(address, port) + elif opt in ('-h', '--help'): + args['print_help'] = True + + # translates our args dict into a named tuple + + Args = collections.namedtuple('Args', args.keys()) + return Args(**args) + + +def main(): + try: + args = parse(sys.argv[1:]) + except ValueError as exc: + print(exc) + sys.exit(1) + + if args.print_help: + print(HELP_TEXT) + sys.exit() + + print('Downloading %s descriptor from %s:%s...\n' % (args.descriptor_type, args.download_from.address, args.download_from.port)) + desc = None + + if args.descriptor_type in ('server', 'extrainfo'): + if args.descriptor_type == 'server': + download_func = stem.descriptor.remote.get_server_descriptors + else: + download_func = stem.descriptor.remote.get_extrainfo_descriptors + + desc = download_func( + fingerprints = [args.fingerprint], + endpoints = [args.download_from], + ).run()[0] + elif args.descriptor_type == 'consensus': + for consensus_desc in stem.descriptor.remote.get_consensus(endpoints = [args.download_from]): + if consensus_desc.fingerprint == args.fingerprint: + desc = consensus_desc + break + + if not desc: + print('Unable to find a descriptor for %s in the consensus' % args.fingerprint) + sys.exit(1) + else: + print("'%s' is not a recognized descriptor type, options are: %s" % (args.descriptor_type, ', '.join(VALID_TYPES))) + sys.exit(1) + + print(desc) + +if __name__ == '__main__': + main() diff --git a/docs/change_log.rst b/docs/change_log.rst index 257ff123..8d1f302d 100644 --- a/docs/change_log.rst +++ b/docs/change_log.rst @@ -84,6 +84,7 @@ The following are only available within Stem's `git repository
* Added `terminal styling <tutorials/east_of_the_sun.html#terminal-styling>`_ to our utilities tutorial * Added `multiprocessing <tutorials/east_of_the_sun.html#multiprocessing>`_ to our utilities tutorial + * Added a `descriptor download example <tutorials/examples/download_descriptor.html>`_ * Added a `relay connection summary example <tutorials/examples/relay_connections.html>`_
.. _version_1.6: diff --git a/docs/tutorials/double_double_toil_and_trouble.rst b/docs/tutorials/double_double_toil_and_trouble.rst index 48d665aa..6701f1dc 100644 --- a/docs/tutorials/double_double_toil_and_trouble.rst +++ b/docs/tutorials/double_double_toil_and_trouble.rst @@ -110,6 +110,10 @@ Relays Descriptors -----------
+* `Download Descriptors <examples/download_descriptor.html>`_ + + Download a descriptor from a Tor relay's ORPort or DirPort. + * `List Outdated Relays <examples/outdated_relays.html>`_
Prints contact information for relays prior to a given version. diff --git a/docs/tutorials/examples/download_descriptor.rst b/docs/tutorials/examples/download_descriptor.rst new file mode 100644 index 00000000..615eef7d --- /dev/null +++ b/docs/tutorials/examples/download_descriptor.rst @@ -0,0 +1,27 @@ +Download Tor Descriptors +======================== + +.. image:: /_static/buttons/back.png + :target: ../double_double_toil_and_trouble.html + +Tor relays provide a mirror for the tor relay descriptors it has cached. +These are available from its ORPort using `Tor's wire protocol +https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt`_, and optionally +with http as well from a `DirPort +https://gitweb.torproject.org/torspec.git/tree/dir-spec.txt`_. + +.. literalinclude:: /_static/example/download_descriptor.py + :language: python + +:: + + % python download_descriptor.py --type consensus --dirport 128.31.0.34:9131 + Downloading consensus descriptor from 128.31.0.34:9131... + + r moria1 lpXfw1/+uGEym58asExGOXAgzjE IpcU7dolas8+Q+oAzwgvZIWx7PA 2018-05-23 02:41:25 128.31.0.34 9101 9131 + s Authority Fast Running Stable V2Dir Valid + v Tor 0.3.3.5-rc-dev + pr Cons=1-2 Desc=1-2 DirCache=1-2 HSDir=1-2 HSIntro=3-4 HSRend=1-2 Link=1-5 LinkAuth=1,3 Microdesc=1-2 Relay=1-2 + w Bandwidth=20 Unmeasured=1 + p reject 1-65535 +
tor-commits@lists.torproject.org