[tor-commits] [stem/master] Initial Relay class

atagar at torproject.org atagar at torproject.org
Wed Feb 7 19:44:51 UTC 2018


commit db52d5fcf38127c107399065768e710b297378c8
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Feb 3 14:03:00 2018 -0800

    Initial Relay class
    
    Clearly from all the todos just a start.
---
 stem/__init__.py        |  2 ++
 stem/client/__init__.py |  9 ++++---
 stem/control.py         |  2 +-
 stem/relay.py           | 71 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/stem/__init__.py b/stem/__init__.py
index 2741cee7..2d2e1c6d 100644
--- a/stem/__init__.py
+++ b/stem/__init__.py
@@ -485,6 +485,7 @@ __url__ = 'https://stem.torproject.org/'
 __license__ = 'LGPLv3'
 
 __all__ = [
+  'client',
   'descriptor',
   'response',
   'util',
@@ -493,6 +494,7 @@ __all__ = [
   'exit_policy',
   'prereq',
   'process',
+  'relay',
   'socket',
   'version',
   'ControllerError',
diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index cbeed403..9f4217c5 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -2,10 +2,11 @@
 # See LICENSE for licensing information
 
 """
-Interaction with a Tor relay's ORPort. :class:`~stem.client.Relay` is
-a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
-:class:`~stem.control.Controller` provides higher level functions for
-:class:`~stem.socket.ControlSocket`.
+Support for `Tor's ORPort protocol
+<https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt>`_.
+
+**This module only consists of low level components, and is not intended for
+users.** See our :class:`~stem.relay.Relay` the API you probably want.
 
 .. versionadded:: 1.7.0
 
diff --git a/stem/control.py b/stem/control.py
index 94ad5eaf..123e3b20 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -989,7 +989,7 @@ class BaseController(object):
 
 class Controller(BaseController):
   """
-  Communicates with a control socket. This is built on top of the
+  Connection with Tor's control socket. This is built on top of the
   BaseController and provides a more user friendly API for library users.
   """
 
diff --git a/stem/relay.py b/stem/relay.py
new file mode 100644
index 00000000..7d1e8282
--- /dev/null
+++ b/stem/relay.py
@@ -0,0 +1,71 @@
+# Copyright 2018, Damian Johnson and The Tor Project
+# See LICENSE for licensing information
+
+"""
+Interaction with a Tor relay's ORPort. :class:`~stem.relay.Relay` is
+a wrapper for :class:`~stem.socket.RelaySocket`, much the same way as
+:class:`~stem.control.Controller` provides higher level functions for
+:class:`~stem.socket.ControlSocket`.
+
+.. versionadded:: 1.7.0
+
+::
+
+  Relay - Connection with a tor relay's ORPort.
+    | +- connect - Establishes a connection with a relay.
+"""
+
+import stem.client
+import stem.client.cell
+import stem.socket
+import stem.util.connection
+
+DEFAULT_LINK_VERSIONS = (3, 4, 5)
+
+
+class Relay(object):
+  """
+  Connection with a Tor relay's ORPort.
+  """
+
+  def __init__(self, orport):
+    self._orport = orport
+
+  @staticmethod
+  def connect(address, port, link_versions = DEFAULT_LINK_VERSIONS):
+    """
+    Establishes a connection with the given ORPort.
+
+    :param str address: ip address of the relay
+    :param int port: ORPort of the relay
+    :param tuple link_versions: acceptable link protocol versions
+
+    :raises:
+      * **ValueError** if address or port are invalid
+      * :class:`stem.SocketError` if we're unable to establish a connection
+    """
+
+    if stem.util.connection.is_valid_ipv4_address(address):
+      addr_type = stem.client.AddrType.IPv4
+    elif stem.util.connection.is_valid_ipv6_address(address):
+      addr_type = stem.client.AddrType.IPv6
+    else:
+      raise ValueError("'%s' isn't an IPv4 or IPv6 address" % address)
+
+    if not stem.util.connection.is_port(port):
+      raise ValueError("'%s' isn't a valid port" % port)
+
+    conn = stem.socket.RelaySocket(address, port)
+    conn.send(stem.client.cell.VersionsCell(link_versions).pack())
+    versions_reply = stem.client.cell.Cell.pop(conn.recv(), 2)[0]
+
+    # TODO: determine the highest common link versions
+    # TODO: we should fill in our address, right?
+    # TODO: what happens if we skip the NETINFO?
+
+    link_version = 3
+    conn.send(stem.client.cell.NetinfoCell(stem.client.Address(address, addr_type), []).pack(link_version))
+
+    # TODO: what if no link protocol versions are acceptable?
+
+    return Relay(conn)





More information about the tor-commits mailing list