commit 88ecc4270799d65a64ec8d52be16297ec932b705 Author: Damian Johnson atagar@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))
tor-commits@lists.torproject.org