[tor-commits] [stem/master] Allowing for IPv4 'a' lines in router status entries

atagar at torproject.org atagar at torproject.org
Mon Feb 4 06:16:09 UTC 2013


commit c6a9cde0f4eb5c627f5ba41f9d263be0c5854ae8
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Feb 3 22:14:20 2013 -0800

    Allowing for IPv4 'a' lines in router status entries
    
    Karsten reports on ticket #8036 that IPv4 addresses are indeed allowed on a
    router status entry's 'a' line. This is a little unfortunate since it means a
    less friendly attribute but not a big whoop.
---
 stem/descriptor/router_status_entry.py      |   34 +++++++++++++++-----------
 stem/descriptor/server_descriptor.py        |    5 +--
 test/unit/descriptor/router_status_entry.py |   19 ++++++++-------
 3 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/stem/descriptor/router_status_entry.py b/stem/descriptor/router_status_entry.py
index 2cd6632..d22dfa3 100644
--- a/stem/descriptor/router_status_entry.py
+++ b/stem/descriptor/router_status_entry.py
@@ -298,8 +298,8 @@ class RouterStatusEntryV3(RouterStatusEntry):
   Information about an individual router stored within a version 3 network
   status document.
 
-  :var dict addresses_v6: **\*** relay's IPv6 OR addresses, this is a mapping
-    of IPv6 addresses to a tuple with the ports it accepts
+  :var list addresses_v6: **\*** relay's OR addresses, this is a tuple listing
+    of the form (address (**str**), port (**int**), is_ipv6 (**bool**))
   :var str digest: **\*** router's digest
 
   :var int bandwidth: bandwidth claimed by the relay (in kb/s)
@@ -318,7 +318,7 @@ class RouterStatusEntryV3(RouterStatusEntry):
   """
 
   def __init__(self, content, validate = True, document = None):
-    self.addresses_v6 = {}
+    self.addresses_v6 = []
     self.digest = None
 
     self.bandwidth = None
@@ -521,21 +521,27 @@ def _parse_a_line(desc, value, validate):
 
     raise ValueError("%s 'a' line must be of the form '[address]:[ports]': a %s" % (desc._name(), value))
 
-  address, port_label = value.rsplit(':', 1)
+  address, ports = value.rsplit(':', 1)
+  is_ipv6 = address.startswith("[") and address.endswith("]")
 
-  if validate and not stem.util.connection.is_valid_ipv6_address(address, allow_brackets = True):
-    raise ValueError("%s 'a' line must start with an IPv6 address: a %s" % (desc._name(), value))
+  if is_ipv6:
+    address = address[1:-1]  # remove brackets
 
-  address = address.lstrip('[').rstrip(']')
-  ports = []
+  if not ((not is_ipv6 and stem.util.connection.is_valid_ip_address(address)) or
+          (is_ipv6 and stem.util.connection.is_valid_ipv6_address(address))):
+    if not validate:
+      return
+    else:
+      raise ValueError("%s 'a' line must start with an IPv6 address: a %s" % (desc._name(), value))
 
-  for port in port_label.split(','):
-    if stem.util.connection.is_valid_port(port):
-      ports.append(int(port))
-    elif validate:
-      raise ValueError("%s 'a' line had an invalid port (%s): a %s" % (desc._name(), port, value))
+  for port in ports.split(','):
+    if not stem.util.connection.is_valid_port(port):
+      if not validate:
+        continue
+      else:
+        raise ValueError("%s 'a' line had an invalid port (%s): a %s" % (desc._name(), port, value))
 
-  desc.addresses_v6[address] = tuple(ports)
+    desc.addresses_v6.append((address, int(port), is_ipv6))
 
 
 def _parse_s_line(desc, value, validate):
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py
index 95a4ef0..be63ddf 100644
--- a/stem/descriptor/server_descriptor.py
+++ b/stem/descriptor/server_descriptor.py
@@ -514,8 +514,7 @@ class ServerDescriptor(stem.descriptor.Descriptor):
             else:
               raise ValueError("or-address line missing a colon: %s" % line)
 
-          div = entry.rfind(":")
-          address, ports = entry[:div], entry[div + 1:]
+          address, ports = entry.rsplit(':', 1)
           is_ipv6 = address.startswith("[") and address.endswith("]")
 
           if is_ipv6:
@@ -531,7 +530,7 @@ class ServerDescriptor(stem.descriptor.Descriptor):
           for port in ports.split(","):
             if not stem.util.connection.is_valid_port(port):
               if not validate:
-                break
+                continue
               else:
                 raise ValueError("or-address line has malformed ports: %s" % line)
 
diff --git a/test/unit/descriptor/router_status_entry.py b/test/unit/descriptor/router_status_entry.py
index b9d3649..b994f23 100644
--- a/test/unit/descriptor/router_status_entry.py
+++ b/test/unit/descriptor/router_status_entry.py
@@ -312,10 +312,11 @@ class TestRouterStatusEntry(unittest.TestCase):
     """
 
     test_values = {
-      "[2607:fcd0:daaa:101::602c:bd62]:443": {
-        '2607:fcd0:daaa:101::602c:bd62': (443,)},
-      "[2607:fcd0:daaa:101::602c:bd62]:80,443": {
-        '2607:fcd0:daaa:101::602c:bd62': (80, 443)},
+      "[2607:fcd0:daaa:101::602c:bd62]:443": [
+        ('2607:fcd0:daaa:101::602c:bd62', 443, True)],
+      "[2607:fcd0:daaa:101::602c:bd62]:80,443": [
+        ('2607:fcd0:daaa:101::602c:bd62', 80, True),
+        ('2607:fcd0:daaa:101::602c:bd62', 443, True)]
     }
 
     for a_line, expected in test_values.items():
@@ -328,10 +329,11 @@ class TestRouterStatusEntry(unittest.TestCase):
     content += "\na [2607:fcd0:daaa:101::602c:bd62]:80,443"
     content += "\na [1148:fcd0:daaa:101::602c:bd62]:80"
 
-    expected = {
-      '2607:fcd0:daaa:101::602c:bd62': (80, 443),
-      '1148:fcd0:daaa:101::602c:bd62': (80,),
-    }
+    expected = [
+      ('2607:fcd0:daaa:101::602c:bd62', 80, True),
+      ('2607:fcd0:daaa:101::602c:bd62', 443, True),
+      ('1148:fcd0:daaa:101::602c:bd62', 80, True),
+    ]
 
     entry = RouterStatusEntryV3(content)
     self.assertEquals(expected, entry.addresses_v6)
@@ -340,7 +342,6 @@ class TestRouterStatusEntry(unittest.TestCase):
 
     test_values = (
       "",
-      "127.0.0.1:80",
       "[1148:fcd0:daaa:101::602c:bd62]:80000",
     )
 



More information about the tor-commits mailing list