[tor-commits] [stem/master] Add IPv6 address support

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


commit 94a86b974e2d7fe4728675ee94d43bded78e4706
Author: Damian Johnson <atagar at torproject.org>
Date:   Sat Jan 20 12:05:13 2018 -0800

    Add IPv6 address support
    
    I'm a tad uncomfortable since I lack actual tor data to exercise this on, but
    taking my best stab.
---
 stem/client/__init__.py     | 10 +++++++++-
 test/unit/client/address.py |  7 +++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 217e32af..b0da7aae 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -256,7 +256,15 @@ class Address(Field):
         self.value = '.'.join([str(Size.CHAR.unpack(value[i])) for i in range(4)])
         self.value_bin = value
     elif self.type == AddrType.IPv6:
-      self.value, self.value_bin = None, None  # TODO: implement
+      if stem.util.connection.is_valid_ipv6_address(value):
+        self.value = stem.util.connection.expand_ipv6_address(value).lower()
+        self.value_bin = ''.join([Size.SHORT.pack(int(v, 16)) for v in self.value.split(':')])
+      else:
+        if len(value) != 16:
+          raise ValueError('Packed IPv6 addresses should be sixteen bytes, but was: %s' % repr(value))
+
+        self.value = ':'.join(['%04x' % Size.SHORT.unpack(value[i * 2:(i + 1) * 2]) for i in range(8)])
+        self.value_bin = value
     else:
       self.value, self.value_bin = None, None  # TODO: implement
 
diff --git a/test/unit/client/address.py b/test/unit/client/address.py
index 9e6430ff..689b77a0 100644
--- a/test/unit/client/address.py
+++ b/test/unit/client/address.py
@@ -3,6 +3,7 @@ Unit tests for stem.client.Address.
 """
 
 import collections
+import re
 import unittest
 
 from stem.client import AddrType, Address
@@ -15,8 +16,11 @@ class TestAddress(unittest.TestCase):
     test_data = (
       ((4, '\x7f\x00\x00\x01'), ExpectedAddress(AddrType.IPv4, 4, '127.0.0.1', '\x7f\x00\x00\x01')),
       ((4, 'aq\x0f\x02'), ExpectedAddress(AddrType.IPv4, 4, '97.113.15.2', 'aq\x0f\x02')),
+      ((6, ' \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)'), ExpectedAddress(AddrType.IPv6, 6, '2001:0db8:0000:0000:0000:ff00:0042:8329', ' \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)')),
       ((AddrType.IPv4, '127.0.0.1'), ExpectedAddress(AddrType.IPv4, 4, '127.0.0.1', '\x7f\x00\x00\x01')),
       ((AddrType.IPv4, '97.113.15.2'), ExpectedAddress(AddrType.IPv4, 4, '97.113.15.2', 'aq\x0f\x02')),
+      ((AddrType.IPv6, '2001:0db8:0000:0000:0000:ff00:0042:8329'), ExpectedAddress(AddrType.IPv6, 6, '2001:0db8:0000:0000:0000:ff00:0042:8329', ' \x01\r\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00B\x83)')),
+      ((AddrType.IPv6, '2001:0DB8:AC10:FE01::'), ExpectedAddress(AddrType.IPv6, 6, '2001:0db8:ac10:fe01:0000:0000:0000:0000', ' \x01\r\xb8\xac\x10\xfe\x01\x00\x00\x00\x00\x00\x00\x00\x00')),  # collaped and different case
     )
 
     for (addr_type, addr_value), expected in test_data:
@@ -26,6 +30,9 @@ class TestAddress(unittest.TestCase):
       self.assertEqual(expected.value, addr.value)
       self.assertEqual(expected.value_bin, addr.value_bin)
 
+    self.assertRaisesRegexp(ValueError, re.escape("Packed IPv4 addresses should be four bytes, but was: '\\x7f\\x00'"), Address, 4, '\x7f\x00')
+    self.assertRaisesRegexp(ValueError, re.escape("Packed IPv6 addresses should be sixteen bytes, but was: '\\x7f\\x00'"), Address, 6, '\x7f\x00')
+
   def test_pop_ipv4(self):
     addr, content = Address.pop('\x04\x04\x7f\x00\x00\x01\x01\x04\x04aq\x0f\x02\x00\x00\x00\x00')
     self.assertEqual('\x01\x04\x04aq\x0f\x02\x00\x00\x00\x00', content)





More information about the tor-commits mailing list