[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Adding get_microdescriptors() method to the Controller
commit 7f3f8722d99b2747cafd2247b14e362c743d5290
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Sat Mar 2 22:16:20 2013 -0800
Adding get_microdescriptors() method to the Controller
Controller method to fetch all microdescriptors. This is modeled after its
counterparts for server descriptors and network status documents. However, as
mentioned in 'https://trac.torproject.org/8323', the controller interface
presently lacks a method to get them.
In the meantime we're reading them from disk.
---
stem/control.py | 52 ++++++++++++++++++++++++++++++++++++++
test/integ/control/controller.py | 20 ++++++++++++++
2 files changed, 72 insertions(+), 0 deletions(-)
diff --git a/stem/control.py b/stem/control.py
index d1025b8..a342fd0 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -26,6 +26,7 @@ providing its own for interacting at a higher level.
|- get_protocolinfo - information about the controller interface
|
|- get_microdescriptor - querying the microdescriptor for a relay
+ |- get_microdescriptors - provides all presently available microdescriptors
|- get_server_descriptor - querying the server descriptor for a relay
|- get_server_descriptors - provides all presently available server descriptors
|- get_network_status - querying the router status entry for a relay
@@ -141,6 +142,7 @@ import threading
import time
import stem.descriptor.microdescriptor
+import stem.descriptor.reader
import stem.descriptor.router_status_entry
import stem.descriptor.server_descriptor
import stem.exit_policy
@@ -999,6 +1001,56 @@ class Controller(BaseController):
else:
return default
+ def get_microdescriptors(self, default = UNDEFINED):
+ """
+ Provides an iterator for all of the microdescriptors that tor presently
+ knows about.
+
+ **Tor does not expose this information via the control protocol (`ticket
+ <https://trac.torproject.org/8323>`_).** Until it does this reads the
+ microdescriptors from disk, and hence won't work remotely or if we lack
+ read permissions.
+
+ :param list default: items to provide if the query fails
+
+ :returns: iterates over
+ :class:`~stem.descriptor.microdescriptor.Microdescriptor` for relays in
+ the tor network
+
+ :raises: :class:`stem.ControllerError` if unable to query tor and no
+ default was provided
+ """
+
+ try:
+ try:
+ data_directory = self.get_conf("DataDirectory")
+ except stem.ControllerError, exc:
+ raise stem.OperationFailed(message = "Unable to determine the data directory (%s)" % exc)
+
+ cached_descriptor_path = os.path.join(data_directory, "cached-microdescs")
+
+ if not os.path.exists(data_directory):
+ raise stem.OperationFailed(message = "Data directory reported by tor doesn't exist (%s)" % data_directory)
+ elif not os.path.exists(cached_descriptor_path):
+ raise stem.OperationFailed(message = "Data directory doens't contain cached microescriptors (%s)" % cached_descriptor_path)
+
+ with stem.descriptor.reader.DescriptorReader([cached_descriptor_path]) as reader:
+ for desc in reader:
+ # It shouldn't be possible for these to be something other than
+ # microdescriptors but as the saying goes: trust but verify.
+
+ if not isinstance(desc, stem.descriptor.microdescriptor.Microdescriptor):
+ raise stem.OperationFailed(message = "BUG: Descriptor reader provided non-microdescriptor content (%s)" % type(desc))
+
+ yield desc
+ except Exception, exc:
+ if default == UNDEFINED:
+ raise exc
+ else:
+ if default is not None:
+ for entry in default:
+ yield entry
+
def get_server_descriptor(self, relay, default = UNDEFINED):
"""
Provides the server descriptor for the relay with the given fingerprint or
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 42006c4..b93b802 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -827,6 +827,26 @@ class TestController(unittest.TestCase):
self.assertEqual(md_by_fingerprint, md_by_nickname)
+ def test_get_microdescriptors(self):
+ """
+ Fetches a few descriptors via the get_microdescriptors() method.
+ """
+
+ runner = test.runner.get_runner()
+
+ if test.runner.require_control(self):
+ return
+
+ with runner.get_tor_controller() as controller:
+ count = 0
+
+ for desc in controller.get_microdescriptors():
+ self.assertTrue(desc.onion_key is not None)
+
+ count += 1
+ if count > 10:
+ break
+
def test_get_server_descriptor(self):
"""
Basic checks for get_server_descriptor().
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits