[tor-bugs] #23819 [Core Tor/Tor]: Support IPv6 link-local interface addresses

Tor Bug Tracker & Wiki blackhole at torproject.org
Sun Oct 29 14:49:04 UTC 2017


#23819: Support IPv6 link-local interface addresses
-----------------------------+------------------------------------
 Reporter:  Zakhar           |          Owner:  (none)
     Type:  enhancement      |         Status:  needs_revision
 Priority:  Medium           |      Milestone:  Tor: 0.3.3.x-final
Component:  Core Tor/Tor     |        Version:
 Severity:  Normal           |     Resolution:
 Keywords:  ipv6 link-local  |  Actual Points:  1
Parent ID:                   |         Points:  1
 Reviewer:                   |        Sponsor:
-----------------------------+------------------------------------

Comment (by Zakhar):

 So here is a new patch.

 I hope it is more compliant with coding standards.

 Here is what I did:
 - removed a tab (spotted by make check-spaces)
 - split the assignment in 2 lines to stick to max line length
 - (Note since nothing is said in the "coding style" if the assignment
 operator is to be at the end of the first line, or beginning of the
 second, I tried to find other examples and followed them: assignment
 operator at the end of first line, just before LF)
 - provided a change description, categorized as "Minor feature".
 - The change ticket describes itself as "Initial support"... because we
 know there is more work to do on link-local addresses!

 What I didn't do:
 - I didn't change the ''man''/documentation. Rationale: in the ''man'', I
 couldn't find any explanation on how to specify ipv6 addresses: enclosing
 them with square brackets, semi colons, abbreviations, etc... That is
 because it is "the standard way" to do it, hence it does not need
 documentation. Since we follow here "the standard way" to specify a link-
 local address, I didn't feel the urge to add anything in the
 documentation.
 - I left the in6_full as my original patch for the moment (more below)
 - Indeed link-local addresses are tricky! Probably, it would be best to
 open a discussion on the mailing list about the correct way to handle
 them.
 - My understanding is that they only have a meaning locally to a host.
 There is no provision in the ipv6 header to ever route a link-local ipv6
 address, you have to use a ULA or global address. But, ipv6 addresses used
 in a "local/host" context (such as when binding) can require this
 scope_id. On the other hand, ipv6 addresses used for routing traffic do
 never need that since you can't put the scope_id in the ipv6 header!
 - This distinction was not needed with ipv4, thus is not coded!
 - To my opinion, the proper modification would probably be to create a new
 structure instead of tor_addr_t, like: tor_local_addr_t, when we use an
 address locally (binding for instance). This tor_local_addr_t will
 definitely needs 20 bytes for ipv6, whereas the previous tor_addr_t do not
 need that since we are routing.
 - Doing that properly would probably be a '''Major''' architecture change
 in tor: distinguishing between local stuff, and routed stuff.
 - The questions you asked in your code review about knowing whether it is
 a AF_INET6/full or AF_INET6/partial is only for local stuff since for
 routing there is no scope_id. For local addresses, the simpler is to
 consider they always have a scope, be it zero when not needed.

 - '''Alternate hack:''' if bumping the tor_addr_t to 20 bytes is too much,
 and you don't want to undertake any '''Major''' architecture change,
 BSD/OSX is using a (horrible) hack to specify link_local address. Instead
 of having fe80::3%1 (1 being the interface number as seen by the local
 system), they use: fe80:1::3. The second 16bits word is used for the
 interface.
 - This is definitely a (horrible) hack with possible severe implications
 in the future. It produces an illegal link-local address since
 https://tools.ietf.org/html/rfc4291#section-2.5.6 defines the remaining 54
 bits of the fe80/10 subnet to be 0. Should the norm change, this hack will
 fail.
 - There is also a limitation since the scope_id is 32bits and we use
 16bits only here. We don't know the kernel algorithm to allocate interface
 numbers, and 16bits could fail.

 - Because there are only 2 places where I touched address.c: one to save
 the scope_id, one to restore the scope_id before we bind, I could produce
 a patch using the BSD ''alternate'' method of specifying scope_id.
 - The save part would store in the second 16bits of the address (failing
 if scope_id >65535)
 - The restore part would test if we have fe80/10 and if so, restore the
 scope_id from the second 16bits and zero it in the copy.
 - We would not need in6_full (since it is the purpose of the hack)
 - There are potential unknown impacts if a function I didn't touch uses
 this "illegal" ipv6 link-local address. More testing to plan!

 What's left to be done
 - Print the full ipv6 link-local address including the interface in the
 message to report the status of the bind operation (currently the patch
 does not address that, and the message is printed out without the
 interface part)
 - Test on systems other than Linux! Since getaddrinfo conforms to
 POSIX.1-2001 and POSIX.1-2008, the patch should work also on BSD and OSX.
 The Win32 documentation show an API with the same parameters and the same
 ipv6 structure including ip6 scope_id, so I presume it might work, but I
 have no way to test that.


 '''Questions:''' (the way forward)

 - Do you wish I deliver also the '''alternate hack''' patch so that you
 can choose the one your prefer?
 - Do you wish I open another 'low priority' ticket for what is still not
 implemented with link-local (such as printing nicely the interface part of
 the address)?

--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/23819#comment:6>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online


More information about the tor-bugs mailing list