[tor-commits] [stem/master] Correct ipv6 little-endian conversion

atagar at torproject.org atagar at torproject.org
Tue Jan 26 17:08:09 UTC 2016


commit 88ecc4270799d65a64ec8d52be16297ec932b705
Author: Damian Johnson <atagar at torproject.org>
Date:   Tue Jan 26 09:07:48 2016 -0800

    Correct ipv6 little-endian conversion
    
    Fixing how we convert little-endian ipv6 addresses, thanks to yawning and
    cypherpunks...
    
      https://trac.torproject.org/projects/tor/ticket/18079#comment:24
---
 stem/util/proc.py      |   31 ++++++++++++++++++++-----------
 test/unit/util/proc.py |   12 +++---------
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/stem/util/proc.py b/stem/util/proc.py
index d519e6f..2b16ccb 100644
--- a/stem/util/proc.py
+++ b/stem/util/proc.py
@@ -431,8 +431,10 @@ def _decode_proc_address_encoding(addr, is_ipv6):
   ::
 
     "0500000A:0016" -> ("10.0.0.5", 22)
+    "F804012A4A5190010000000002000000:01BB" -> ("2a01:4f8:190:514a::2", 443)
 
   :param str addr: proc address entry to be decoded
+  :param bool is_ipv6: if we should treat the address as ipv6
 
   :returns: **tuple** of the form **(addr, port)**, with addr as a string and port an int
   """
@@ -441,17 +443,24 @@ def _decode_proc_address_encoding(addr, is_ipv6):
 
   port = int(port, 16)  # the port is represented as a two-byte hexadecimal number
 
-  # The IP address portion is a little-endian four-byte hexadecimal number.
-  # That is, the least significant byte is listed first, so we need to reverse
-  # the order of the bytes to convert it to an IP address.
-  #
-  # This needs to account for the endian ordering as per...
-  #
-  # http://code.google.com/p/psutil/issues/detail?id=201
-  # https://trac.torproject.org/projects/tor/ticket/4777
-
-  ip_encoded = base64.b16decode(ip)[::-1] if sys.byteorder == 'little' else base64.b16decode(ip)
-  ip = socket.inet_ntop(socket.AF_INET6 if is_ipv6 else socket.AF_INET, ip_encoded)
+  if not is_ipv6:
+    ip_encoded = base64.b16decode(ip)[::-1] if sys.byteorder == 'little' else base64.b16decode(ip)
+    ip = socket.inet_ntop(socket.AF_INET, ip_encoded)
+  else:
+    if sys.byteorder == 'little':
+      # Group into eight characters, then invert in pairs...
+      #
+      #   https://trac.torproject.org/projects/tor/ticket/18079#comment:24
+
+      inverted = []
+
+      for i in range(4):
+        grouping = ip[8 * i:8 * (i + 1)]
+        inverted += [grouping[2 * i:2 * (i + 1)] for i in range(4)][::-1]
+
+      ip = ''.join(inverted)
+
+    ip = socket.inet_ntop(socket.AF_INET6, base64.b16decode(ip))
 
   return (ip, port)
 
diff --git a/test/unit/util/proc.py b/test/unit/util/proc.py
index 4b7d37f..f852820 100644
--- a/test/unit/util/proc.py
+++ b/test/unit/util/proc.py
@@ -247,16 +247,12 @@ class TestProc(unittest.TestCase):
     pid = 1111
 
     listdir_mock.side_effect = lambda param: {
-      '/proc/%s/fd' % pid: ['1', '2', '3', '4'],
+      '/proc/%s/fd' % pid: ['1', '2'],
     }[param]
 
     readlink_mock.side_effect = lambda param: {
       '/proc/%s/fd/1' % pid: 'socket:[42088802]',
       '/proc/%s/fd/2' % pid: 'socket:[41691357]',
-      '/proc/%s/fd/3' % pid: 'socket:[41878761]',
-      '/proc/%s/fd/4' % pid: 'socket:[41825895]',
-      '/proc/%s/fd/5' % pid: 'socket:[41512577]',
-      '/proc/%s/fd/6' % pid: 'socket:[14347030]',  # this shouldn't be present due to being unestablished
     }[param]
 
     path_exists_mock.side_effect = lambda param: {
@@ -271,10 +267,8 @@ class TestProc(unittest.TestCase):
     }[param]
 
     expected_results = [
-      ('0:2::190:514a:2a01:4f8', 443, 'ffff:189::a000:4140:2001:638', 40435, 'tcp', True),
-      ('0:2::190:514a:2a01:4f8', 443, '563b:1526:aabb:0:2:2:2001:858', 44469, 'tcp', True),
-      ('509:9e4b:0:ffff::', 5222, '4e36:8621:0:ffff::', 38330, 'tcp', True),
-      ('0:2::190:514a:2a01:4f8', 5269, '0:26::126f:11:2001:6f8', 50594, 'tcp', True),
+      ('2a01:4f8:190:514a::2', 443, '2001:638:a000:4140::ffff:189', 40435, 'tcp', True),
+      ('2a01:4f8:190:514a::2', 443, '2001:858:2:2:aabb:0:563b:1526', 44469, 'tcp', True),
     ]
 
     self.assertEqual(expected_results, proc.connections(pid))



More information about the tor-commits mailing list