Directory
*********

Directories that provide relay descriptor information. At a very high
level tor works as follows…

1. Volunteer starts a new tor relay, during which it sends a server
   descriptor to each of the directory authorities.

2. Each hour the directory authorities make a vote  that says who
   they think the active relays are in the network and some attributes
   about them.

3. The directory authorities send each other their votes, and
   compile that into the consensus. This document is very similar to
   the votes, the only difference being that the majority of the
   authorities agree upon and sign this document. The idividual relay
   entries in the vote or consensus is called router status entries.

4. Tor clients (people using the service) download the consensus
   from an authority, fallback, or other mirror to determine who the
   active relays in the network are. They then use this to construct
   circuits and use the network.

   Directory - Relay we can retrieve descriptor information from
     | |- from_cache - Provides cached information bundled with Stem.
     | +- from_remote - Downloads the latest directory information from tor.
     |
     |- Authority - Tor directory authority
     +- Fallback - Mirrors that can be used instead of the authorities

New in version 1.7.0.

class stem.directory.Directory(address, or_port, dir_port, fingerprint, nickname, orport_v6)

   Bases: "object"

   Relay we can contact for descriptor information.

   Our "from_cache()" and "from_remote()" functions key off a
   different identifier based on our subclass…

      * "Authority" keys off the nickname.

      * "Fallback" keys off fingerprints.

   This is because authorities are highly static and canonically known
   by their names, whereas fallbacks vary more and don’t necessarily
   have a nickname to key off of.

   Variables:
      * **address** (*str*) – IPv4 address of the directory

      * **or_port** (*int*) – port on which the relay services relay
        traffic

      * **dir_port** (*int*) – port on which directory information
        is available

      * **fingerprint** (*str*) – relay fingerprint

      * **nickname** (*str*) – relay nickname

      * **orport_v6** (*str*) – **(address, port)** tuple for the
        directory’s IPv6 ORPort, or **None** if it doesn’t have one

   static from_cache()

      Provides cached Tor directory information. This information is
      hardcoded into Tor and occasionally changes, so the information
      provided by this method may not necessarily match the latest
      version of tor.

      New in version 1.5.0.

      Changed in version 1.7.0: Support added to the "Authority"
      class.

      Returns:
         **dict** of **str** identifiers to "Directory" instances

   static from_remote(timeout=60)

      Reads and parses tor’s directory data from
      gitweb.torproject.org. Note that while convenient, this reliance
      on GitWeb means you should alway call with a fallback, such as…

         try:
           authorities = stem.directory.Authority.from_remote()
         except IOError:
           authorities = stem.directory.Authority.from_cache()

      New in version 1.5.0.

      Changed in version 1.7.0: Support added to the "Authority"
      class.

      Parameters:
         **timeout** (*int*) – seconds to wait before timing out the
         request

      Returns:
         **dict** of **str** identifiers to their "Directory"

      Raises:
         **IOError** if unable to retrieve the fallback directories

class stem.directory.Authority(address=None, or_port=None, dir_port=None, fingerprint=None, nickname=None, orport_v6=None, v3ident=None, is_bandwidth_authority=False)

   Bases: "stem.directory.Directory"

   Tor directory authority, a special type of relay hardcoded into tor
   to enumerate the relays in the network.

   Changed in version 1.3.0: Added the is_bandwidth_authority
   attribute.

   Changed in version 1.7.0: Added the orport_v6 attribute.

   Deprecated since version 1.7.0: The is_bandwidth_authority
   attribute is deprecated and will be removed in the future.

   Variables:
      **v3ident** (*str*) – identity key fingerprint used to sign
      votes and consensus

   static from_cache()

      Provides cached Tor directory information. This information is
      hardcoded into Tor and occasionally changes, so the information
      provided by this method may not necessarily match the latest
      version of tor.

      New in version 1.5.0.

      Changed in version 1.7.0: Support added to the "Authority"
      class.

      Returns:
         **dict** of **str** identifiers to "Directory" instances

   static from_remote(timeout=60)

      Reads and parses tor’s directory data from
      gitweb.torproject.org. Note that while convenient, this reliance
      on GitWeb means you should alway call with a fallback, such as…

         try:
           authorities = stem.directory.Authority.from_remote()
         except IOError:
           authorities = stem.directory.Authority.from_cache()

      New in version 1.5.0.

      Changed in version 1.7.0: Support added to the "Authority"
      class.

      Parameters:
         **timeout** (*int*) – seconds to wait before timing out the
         request

      Returns:
         **dict** of **str** identifiers to their "Directory"

      Raises:
         **IOError** if unable to retrieve the fallback directories

class stem.directory.Fallback(address=None, or_port=None, dir_port=None, fingerprint=None, nickname=None, has_extrainfo=False, orport_v6=None, header=None)

   Bases: "stem.directory.Directory"

   Particularly stable relays tor can instead of authorities when
   bootstrapping. These relays are hardcoded in tor.

   For example, the following checks the performance of tor’s fallback
   directories…

      import time
      from stem.descriptor.remote import get_consensus
      from stem.directory import Fallback

      for fallback in Fallback.from_cache().values():
        start = time.time()
        get_consensus(endpoints = [(fallback.address, fallback.dir_port)]).run()
        print('Downloading the consensus took %0.2f from %s' % (time.time() - start, fallback.fingerprint))

      % python example.py
      Downloading the consensus took 5.07 from 0AD3FA884D18F89EEA2D89C019379E0E7FD94417
      Downloading the consensus took 3.59 from C871C91489886D5E2E94C13EA1A5FDC4B6DC5204
      Downloading the consensus took 4.16 from 74A910646BCEEFBCD2E874FC1DC997430F968145
      ...

   New in version 1.5.0.

   Changed in version 1.7.0: Added the has_extrainfo and header
   attributes which are part of the second version of the fallback
   directories.

   Variables:
      * **has_extrainfo** (*bool*) – **True** if the relay should be
        able to provide extrainfo descriptors, **False** otherwise.

      * **header** (*collections.OrderedDict*) – metadata about the
        fallback directory file this originated from

   static from_cache(path='/builddir/build/BUILD/stem-1.8.0/stem/cached_fallbacks.cfg')

      Provides cached Tor directory information. This information is
      hardcoded into Tor and occasionally changes, so the information
      provided by this method may not necessarily match the latest
      version of tor.

      New in version 1.5.0.

      Changed in version 1.7.0: Support added to the "Authority"
      class.

      Returns:
         **dict** of **str** identifiers to "Directory" instances

   static from_remote(timeout=60)

      Reads and parses tor’s directory data from
      gitweb.torproject.org. Note that while convenient, this reliance
      on GitWeb means you should alway call with a fallback, such as…

         try:
           authorities = stem.directory.Authority.from_remote()
         except IOError:
           authorities = stem.directory.Authority.from_cache()

      New in version 1.5.0.

      Changed in version 1.7.0: Support added to the "Authority"
      class.

      Parameters:
         **timeout** (*int*) – seconds to wait before timing out the
         request

      Returns:
         **dict** of **str** identifiers to their "Directory"

      Raises:
         **IOError** if unable to retrieve the fallback directories
