commit 41274f4658772cbab5a22750e56d48b1b4478b6f Author: Damian Johnson atagar@torproject.org Date: Sun Nov 3 12:54:21 2013 -0800
Adding support for CONN_BW events
New event type added in...
https://gitweb.torproject.org/torspec.git/commitdiff/6f2919a --- docs/change_log.rst | 2 ++ stem/__init__.py | 20 +++++++++++++++++++ stem/response/events.py | 45 ++++++++++++++++++++++++++++++++++++++++++ stem/version.py | 2 ++ test/unit/response/events.py | 17 ++++++++++++++++ 5 files changed, 86 insertions(+)
diff --git a/docs/change_log.rst b/docs/change_log.rst index 4184635..a55eb95 100644 --- a/docs/change_log.rst +++ b/docs/change_log.rst @@ -42,6 +42,7 @@ The following are only available within stem's `git repository * **Controller**
* Added the id attribute to the :class:`~stem.response.events.ORConnEvent` (:spec:`6f2919a`) + * Added `support for CONN_BW events <api/response.html#stem.response.events.ConnectionBandwidthEvent>`_ (:spec:`6f2919a`)
.. _version_1.1:
@@ -64,6 +65,7 @@ and a myriad of smaller improvements and fixes. * Added :func:`~stem.control.Controller.get_pid` method to the :class:`~stem.control.Controller` * :class:`~stem.response.events.StreamEvent` didn't recognize IPv6 addresses (:trac:`9181`) * :func:`~stem.control.Controller.get_conf` mistakenly cached hidden service related options (:trac:`9792`) + * Added `support for TRANSPORT_LAUNCHED events <api/response.html#stem.response.events.TransportLaunchedEvent>`_ (:spec:`48f6dd0`)
* **Descriptors**
diff --git a/stem/__init__.py b/stem/__init__.py index e87bd9f..182428f 100644 --- a/stem/__init__.py +++ b/stem/__init__.py @@ -366,6 +366,20 @@ Library for working with the tor process. **DISCARD** throwing out timeout value from when the network was down **RESUME** resumed calculations to determine the proper timeout =============== =========== + +.. data:: ConnectionType (enum) + + Purpose for a tor connection. Tor may provide types not in this enum. + + The meaning behind these values is a bit unclear, pending :trac:`10086`. + + =============== =========== + ConnectionType Description + =============== =========== + **OR** carrying traffic within the tor network + **DIR** fetching or sending tor descriptor data + **EXIT** carrying traffic between the tor network and an external destination + =============== =========== """
__version__ = '1.1.0-dev' @@ -698,3 +712,9 @@ TimeoutSetType = stem.util.enum.UppercaseEnum( "DISCARD", "RESUME", ) + +ConnectionType = stem.util.enum.UppercaseEnum( + "OR", + "DIR", + "EXIT", +) diff --git a/stem/response/events.py b/stem/response/events.py index 742bc3d..dcdefbc 100644 --- a/stem/response/events.py +++ b/stem/response/events.py @@ -926,6 +926,50 @@ class TransportLaunchedEvent(Event):
self.port = int(self.port)
+ +class ConnectionBandwidthEvent(Event): + """ + Event emitted every second with the bytes sent and received by tor on a + per-connection basis. + + The CONN_BW event was introduced in tor version 0.2.5.2-alpha. + + .. versionadded:: 1.1.0-dev + + :var str id: connection identifier + :var stem.ConnectionType type: connection type + :var long read: bytes received by tor that second + :var long written: bytes sent by tor that second + """ + + _KEYWORD_ARGS = { + "ID": "id", + "TYPE": "type", + "READ": "read", + "WRITTEN": "written", + } + + _VERSION_ADDED = stem.version.Requirement.EVENT_CONN_BW + + def _parse(self): + if not self.id: + raise stem.ProtocolError("CONN_BW event is missing its id") + elif not self.type: + raise stem.ProtocolError("CONN_BW event is missing its type") + elif not self.read: + raise stem.ProtocolError("CONN_BW event is missing its read value") + elif not self.written: + raise stem.ProtocolError("CONN_BW event is missing its written value") + elif not self.read.isdigit() or not self.written.isdigit(): + raise stem.ProtocolError("A CONN_BW event's bytes sent and received should be a positive numeric value, received: %s" % self) + elif not tor_tools.is_valid_connection_id(self.id): + raise stem.ProtocolError("Connection IDs must be one to sixteen alphanumeric characters, got '%s': %s" % (self.id, self)) + + self.read = long(self.read) + self.written = long(self.written) + + self._log_if_unrecognized('type', stem.ConnectionType) + EVENT_TYPE_TO_CLASS = { "ADDRMAP": AddrMapEvent, "AUTHDIR_NEWDESCS": AuthDirNewDescEvent, @@ -952,6 +996,7 @@ EVENT_TYPE_TO_CLASS = { "STREAM": StreamEvent, "STREAM_BW": StreamBwEvent, "TRANSPORT_LAUNCHED": TransportLaunchedEvent, + "CONN_BW": ConnectionBandwidthEvent, "WARN": LogEvent,
# accounting for a bug in tor 0.2.0.22 diff --git a/stem/version.py b/stem/version.py index 5efc1e0..fbc3f31 100644 --- a/stem/version.py +++ b/stem/version.py @@ -43,6 +43,7 @@ easily parsed and compared, for instance... **EVENT_STATUS** STATUS_GENERAL, STATUS_CLIENT, and STATUS_SERVER events **EVENT_STREAM_BW** STREAM_BW events **EVENT_TRANSPORT_LAUNCHED** TRANSPORT_LAUNCHED events + **EVENT_CONN_BW** CONN_BW events **EXTENDCIRCUIT_PATH_OPTIONAL** EXTENDCIRCUIT queries can omit the path if the circuit is zero **FEATURE_EXTENDED_EVENTS** 'EXTENDED_EVENTS' optional feature **FEATURE_VERBOSE_NAMES** 'VERBOSE_NAMES' optional feature @@ -341,6 +342,7 @@ Requirement = stem.util.enum.Enum( ("EVENT_STATUS", Version('0.1.2.3-alpha')), ("EVENT_STREAM_BW", Version('0.1.2.8-beta')), ("EVENT_TRANSPORT_LAUNCHED", Version('0.2.5.0-alpha')), + ("EVENT_CONN_BW", Version('0.2.5.2-alpha')), ("EXTENDCIRCUIT_PATH_OPTIONAL", Version("0.2.2.9")), ("FEATURE_EXTENDED_EVENTS", Version("0.2.2.1-alpha")), ("FEATURE_VERBOSE_NAMES", Version("0.2.2.1-alpha")), diff --git a/test/unit/response/events.py b/test/unit/response/events.py index aa13b5f..071f760 100644 --- a/test/unit/response/events.py +++ b/test/unit/response/events.py @@ -329,6 +329,10 @@ TRANSPORT_LAUNCHED_BAD_TYPE = "650 TRANSPORT_LAUNCHED unicorn obfs1 127.0.0.1 11 TRANSPORT_LAUNCHED_BAD_ADDRESS = "650 TRANSPORT_LAUNCHED server obfs1 127.0.x.y 1111" TRANSPORT_LAUNCHED_BAD_PORT = "650 TRANSPORT_LAUNCHED server obfs1 127.0.0.1 my_port"
+CONN_BW = "650 CONN_BW ID=11 TYPE=DIR READ=272 WRITTEN=817" +CONN_BW_BAD_WRITTEN_VALUE = "650 CONN_BW ID=11 TYPE=DIR READ=272 WRITTEN=817.7" +CONN_BW_BAD_MISSING_ID = "650 CONN_BW TYPE=DIR READ=272 WRITTEN=817" +
def _get_event(content): controller_event = mocking.get_message(content) @@ -1190,6 +1194,19 @@ class TestEvents(unittest.TestCase): self.assertRaises(ProtocolError, _get_event, TRANSPORT_LAUNCHED_BAD_ADDRESS) self.assertRaises(ProtocolError, _get_event, TRANSPORT_LAUNCHED_BAD_PORT)
+ def test_conn_bw_event(self): + event = _get_event(CONN_BW) + + self.assertTrue(isinstance(event, stem.response.events.ConnectionBandwidthEvent)) + self.assertEqual(CONN_BW.lstrip("650 "), str(event)) + self.assertEqual("11", event.id) + self.assertEqual(stem.ConnectionType.DIR, event.type) + self.assertEqual(272, event.read) + self.assertEqual(817, event.written) + + self.assertRaises(ProtocolError, _get_event, CONN_BW_BAD_WRITTEN_VALUE) + self.assertRaises(ProtocolError, _get_event, CONN_BW_BAD_MISSING_ID) + def test_unrecognized_enum_logging(self): """ Checks that when event parsing gets a value that isn't recognized by stem's
tor-commits@lists.torproject.org