[tor-commits] [stem/master] Fully parsing transport lines

atagar at torproject.org atagar at torproject.org
Mon Aug 6 03:17:22 UTC 2012


commit ac5be8cee5f58517c09217fd6860f7ef483dacc2
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Aug 5 20:14:18 2012 -0700

    Fully parsing transport lines
    
    The extrainfo descriptor's new transport lines were a little funny in that
    they're only relevant to bridges, and when they apprear in bridges they're
    scrubbed of everything except the transport name. This in turn meant that they
    only appeared with transport names in the wild.
    
    However, now that transport lines can appear in non-bridge relays I'll
    sometimes see complete transport lines, so parsing and validating them
    properly.
---
 stem/descriptor/extrainfo_descriptor.py      |   41 ++++++++++++++++++++++---
 test/unit/descriptor/extrainfo_descriptor.py |    4 +-
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/stem/descriptor/extrainfo_descriptor.py b/stem/descriptor/extrainfo_descriptor.py
index 8d66df6..a589139 100644
--- a/stem/descriptor/extrainfo_descriptor.py
+++ b/stem/descriptor/extrainfo_descriptor.py
@@ -179,7 +179,7 @@ class ExtraInfoDescriptor(stem.descriptor.Descriptor):
   :var str fingerprint: **\*** identity key fingerprint
   :var datetime published: **\*** time in GMT when this descriptor was made
   :var str geoip_db_digest: sha1 of geoIP database file
-  :var list transport: transport method recognized by the bridge (ex. obfs3)
+  :var dict transport: **\*** mapping of transport methods to their (address, port, args) tuple, these usually appeear on bridges in which case all of those are None
   
   **Bi-directional connection usage:**
   
@@ -288,7 +288,7 @@ class ExtraInfoDescriptor(stem.descriptor.Descriptor):
     self.fingerprint = None
     self.published = None
     self.geoip_db_digest = None
-    self.transport = None
+    self.transport = {}
     
     self.conn_bi_direct_end = None
     self.conn_bi_direct_interval = None
@@ -432,10 +432,41 @@ class ExtraInfoDescriptor(stem.descriptor.Descriptor):
         # on non-bridges in the wild when the relay operator configured it this
         # way.
         
-        if self.transport is None:
-          self.transport = []
+        name, address, port, args = None, None, None, None
         
-        self.transport.append(value)
+        if not ' ' in value:
+          # scrubbed
+          name = value
+        else:
+          # not scrubbed
+          value_comp = value.split()
+          
+          if len(value_comp) < 1:
+            raise ValueError("Transport line is missing its transport name: %s" % line)
+          else:
+            name = value_comp[0]
+          
+          if len(value_comp) < 2:
+            raise ValueError("Transport line is missing its address:port value: %s" % line)
+          elif not ":" in value_comp[1]:
+            raise ValueError("Transport line's address:port entry is missing a colon: %s" % line)
+          else:
+            address, port_str = value_comp[1].split(':', 1)
+            
+            if not stem.util.connection.is_valid_ip_address(address) or \
+                   stem.util.connection.is_valid_ipv6_address(address):
+              raise ValueError("Transport line has a malformed address: %s" % line)
+            elif not stem.util.connection.is_valid_port(port_str):
+              raise ValueError("Transport line has a malformed port: %s" % line)
+            
+            port = int(port_str)
+          
+          if len(value_comp) >= 3:
+            args = value_comp[2:]
+          else:
+            args = []
+        
+        self.transport[name] = (address, port, args)
       elif keyword == "cell-circuits-per-decile":
         # "cell-circuits-per-decile" num
         
diff --git a/test/unit/descriptor/extrainfo_descriptor.py b/test/unit/descriptor/extrainfo_descriptor.py
index 1008af7..54d6bf8 100644
--- a/test/unit/descriptor/extrainfo_descriptor.py
+++ b/test/unit/descriptor/extrainfo_descriptor.py
@@ -527,12 +527,12 @@ class TestExtraInfoDescriptor(unittest.TestCase):
     
     desc_text = _make_descriptor({"transport": "obfs3"}, is_bridge = True)
     desc = BridgeExtraInfoDescriptor(desc_text)
-    self.assertEquals(["obfs3"], desc.transport)
+    self.assertEquals({"obfs3": (None, None, None)}, desc.transport)
     self.assertEquals([], desc.get_unrecognized_lines())
     
     desc_text = _make_descriptor({"transport": "obfs2 83.212.96.201:33570"})
     desc = RelayExtraInfoDescriptor(desc_text)
-    self.assertEquals(["obfs2 83.212.96.201:33570"], desc.transport)
+    self.assertEquals({"obfs2": ("83.212.96.201", 33570, [])}, desc.transport)
     self.assertEquals([], desc.get_unrecognized_lines())
   
   def _expect_invalid_attr(self, desc_text, attr = None, expected_value = None):



More information about the tor-commits mailing list