[tor-commits] [stem/master] Example script for downloading descriptors

atagar at torproject.org atagar at torproject.org
Wed May 23 19:08:56 UTC 2018


commit ee3bca1e15e4bc927a296b52df5c2706ce087b52
Author: Damian Johnson <atagar at 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
+



More information about the tor-commits mailing list