[tor-commits] [stem/master] VersionsCell unpacking

atagar at torproject.org atagar at torproject.org
Sun Jan 21 02:04:04 UTC 2018


commit ba91f20beebab6e8ec0496f75bfef37c1c124c52
Author: Damian Johnson <atagar at torproject.org>
Date:   Thu Jan 11 17:54:08 2018 -0800

    VersionsCell unpacking
    
    Implementing our first cell unpack function.
---
 stem/client/cell.py      | 29 ++++++++++++++++++++++++++---
 test/unit/client/cell.py |  5 +++++
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/stem/client/cell.py b/stem/client/cell.py
index 7a1644b3..e29e404f 100644
--- a/stem/client/cell.py
+++ b/stem/client/cell.py
@@ -36,15 +36,16 @@ Messages communicated over a Tor relay's ORPort.
     +- unpack - Decodes bytes for this cell class.
 """
 
-import collections
 import inspect
 import sys
 
 from stem import UNDEFINED
 from stem.client import ZERO, Size
 
+MAX_FIXED_PAYLOAD_LEN = 509
 
-class Cell(collections.namedtuple('Cell', ['name', 'value', 'fixed_size', 'for_circuit'])):
+
+class Cell(object):
   """
   Metadata for ORPort cells.
 
@@ -109,7 +110,14 @@ class Cell(collections.namedtuple('Cell', ['name', 'value', 'fixed_size', 'for_c
 
     circ_id, content = Size.LONG.pop(content) if link_version > 3 else Size.SHORT.pop(content)
     command, content = Size.CHAR.pop(content)
-    return Cell.by_value(command)._unpack(content, link_version, circ_id)
+    cls = Cell.by_value(command)
+
+    if cls.IS_FIXED_SIZE:
+      payload_len = MAX_FIXED_PAYLOAD_LEN
+    else:
+      payload_len, content = Size.SHORT.pop(content)
+
+    return cls._unpack(content, link_version, circ_id)
 
   @classmethod
   def _pack(cls, link_version, payload, circ_id = 0):
@@ -234,12 +242,17 @@ class CreatedFastCell(CircuitCell):
 class VersionsCell(Cell):
   """
   Link version negotiation cell.
+
+  :var list versions: link versions
   """
 
   NAME = 'VERSIONS'
   VALUE = 7
   IS_FIXED_SIZE = False
 
+  def __init__(self, versions):
+    self.versions = versions
+
   @classmethod
   def pack(cls, versions):
     """
@@ -256,6 +269,16 @@ class VersionsCell(Cell):
     payload = b''.join([Size.SHORT.pack(v) for v in versions])
     return cls._pack(3, payload)
 
+  @classmethod
+  def _unpack(cls, content, circ_id, link_version):
+    link_versions = []
+
+    while content:
+      version, content = Size.SHORT.pop(content)
+      link_versions.append(version)
+
+    return VersionsCell(link_versions)
+
 
 class NetinfoCell(Cell):
   NAME = 'NETINFO'
diff --git a/test/unit/client/cell.py b/test/unit/client/cell.py
index 857cab84..9502975e 100644
--- a/test/unit/client/cell.py
+++ b/test/unit/client/cell.py
@@ -35,3 +35,8 @@ class TestCell(unittest.TestCase):
     self.assertEqual('\x00\x00\x07\x00\x00', VersionsCell.pack([]))
     self.assertEqual('\x00\x00\x07\x00\x02\x00\x01', VersionsCell.pack([1]))
     self.assertEqual('\x00\x00\x07\x00\x06\x00\x01\x00\x02\x00\x03', VersionsCell.pack([1, 2, 3]))
+
+  def test_versions_unpack(self):
+    self.assertEqual([], Cell.unpack('\x00\x00\x07\x00\x00', 2).versions)
+    self.assertEqual([1], Cell.unpack('\x00\x00\x07\x00\x02\x00\x01', 2).versions)
+    self.assertEqual([1, 2, 3], Cell.unpack('\x00\x00\x07\x00\x06\x00\x01\x00\x02\x00\x03', 2).versions)





More information about the tor-commits mailing list