Skip to content

Conversation

mruddy
Copy link
Contributor

@mruddy mruddy commented Feb 21, 2016

Adds support for binding and listening, as well as connecting to, scoped IPv6 addresses.

I wanted to be able to use IPv6 link-local addresses on 4.2+ GNU/Linux (sin6_scope_id was added in 2.4). So, that's what I've tested. It seems to work. If I missed something, please let me know and I'll fix it.
I haven't tried with Windows or Mac, but I think the support is present in many versions of those systems too.
Hopefully, this does not simply fail for the automated Windows build (fingers crossed).
IPv6 scoped addresses are also known as link-local and site-local addresses.
The Linux docs say, "Linux supports it [sin6_scope_id] only for link-local addresses". Windows may support site-local addresses.

Note that if you test this, it's easier to see the bound address with something like: sudo netstat -pantu --wide | grep bitcoin
Also, here's an example of an easy way to find nodes accessible on your local link: ping6 -I eth0 -n ff02::1

Basically, commands similar to these should work now, instead of failing with "Unable to bind to [fe80::1234:5ff:fe67:89ab]:8333 on this computer (bind returned error Invalid argument (22))" or "socket send error Broken pipe (32)":

  • bitcoin-qt/bitcoind -listen -bind/-whitebind='[fe80::1234:5ff:fe67:89ab%eth0]:8333'
  • bitcoin-qt/bitcoind -connect='[fe80::1234:5ff:fe67:89ab%eth0]:8333'

This should still fail due to missing the scope ID:

  • bitcoin-qt/bitcoind -listen -bind/-whitebind='[fe80::1234:5ff:fe67:89ab]:8333'

This should still fail due to the scope id being misplaced:

  • bitcoin-qt/bitcoind -listen -bind/-whitebind='[fe80::1234:5ff:fe67:89ab]%eth0:8333'

References:
http://man7.org/linux/man-pages/man7/ipv6.7.html
http://research.microsoft.com/en-us/um/redmond/projects/msripv6/docs/config.htm
https://msdn.microsoft.com/en-us/library/windows/desktop/ms739166(v=vs.85).aspx
https://tools.ietf.org/html/draft-ietf-ipv6-scope-api-00

@laanwj
Copy link
Member

laanwj commented Feb 24, 2016

Potential nit, haven't looked at the code in detail: by their local nature there's no way that scoped addresses can work in the P2P address advertising logic - so from a privacy angle, does this make sure that these can't leak to the P2P network?

@mruddy
Copy link
Contributor Author

mruddy commented Feb 25, 2016

For the link-local addresses I believe that is accounted for already because CNetAddr::IsRFC4862 matches them and thus CNetAddr::IsRoutable returns false for them.

About the site-local category of scoped addresses, upon more investigation, their usage is already deprecated by RFC 3879 (https://www.ietf.org/rfc/rfc3879.txt) and Linux does not support them. I only mentioned them because the Windows documents mentioned them and I'm inclined to think that we don't need to concern ourselves with them. If we do, then we could maybe add another method to match them and then make that part of the IsRoutable check too.

@laanwj laanwj added the Feature label Feb 29, 2016
@mruddy mruddy changed the title Net: Add IPv6 Scoped Address Support Net: Add IPv6 Link-Local Address Support Mar 29, 2016
@mruddy mruddy force-pushed the ipv6-link-local branch 3 times, most recently from 57ae377 to 70add6c Compare March 30, 2016 12:05
@petertodd
Copy link
Contributor

Concept ACK

@mruddy mruddy force-pushed the ipv6-link-local branch from 70add6c to eda3d92 Compare April 5, 2016 22:45
@mruddy
Copy link
Contributor Author

mruddy commented Apr 5, 2016

I rebased and re-worked this commit to make it easier to review.
Previously, I tried to be complete. This only changes the minimum needed to get it to work.

Also, circling back on the site-local addresses...
Their original behavior has been deprecated for many years.
I tested fec0/10 and fec0/64 addresses with Bitcoin Core 0.12.0, and it already binds them with no problem and does not treat them as local (it advertises them).
That existing behavior is in line with RFC guidance:
https://tools.ietf.org/html/rfc4291#section-2.5.7

"The special behavior of this prefix defined in [RFC3513] must no longer be supported in new implementations (i.e., new implementations must treat this prefix as Global Unicast)."

That's good. It means this PR only has to concern itself with link-local (which was the original intent).

The link-local fe80/64 [https://tools.ietf.org/html/rfc4291#section-2.5.6] addresses are treated as being local/non-routable/non-advertisable already.
Discovery of our own addresses does not add/include link-locals.
As stated before, CNetAddr::IsRFC4862 matches link-locals and thus CNetAddr::IsRoutable returns false for them. This ultimately stops them from being advertised.

The motivation for this change is to make it easier to deploy and manage a cluster of nodes on a local network.
For example, I was spinning up multiple nodes on an adhoc WIFI network for a simulation and IPv6 link-local addressing made that process easier by a few steps for each node.

@laanwj
Copy link
Member

laanwj commented Apr 6, 2016

Thanks for the explanation. I was indeed curious what one would use this for in practice.

utACK eda3d92

@sipa
Copy link
Member

sipa commented Apr 6, 2016

utACK eda3d92

@laanwj laanwj merged commit eda3d92 into bitcoin:master Apr 8, 2016
laanwj added a commit that referenced this pull request Apr 8, 2016
eda3d92 Net: Add IPv6 Link-Local Address Support (mruddy)
@mruddy mruddy deleted the ipv6-link-local branch April 8, 2016 16:48
codablock pushed a commit to codablock/dash that referenced this pull request Dec 20, 2017
eda3d92 Net: Add IPv6 Link-Local Address Support (mruddy)
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants