Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle dial prioritisation for well known prefix IPv4 embedded IPv6 addresses #2349

Closed
sukunrt opened this issue Jun 12, 2023 · 5 comments · Fixed by #2392
Closed

Handle dial prioritisation for well known prefix IPv4 embedded IPv6 addresses #2349

sukunrt opened this issue Jun 12, 2023 · 5 comments · Fixed by #2392

Comments

@sukunrt
Copy link
Member

sukunrt commented Jun 12, 2023

When implementing happy eyeballs logic to prefer QUIC IPv6 over QUIC IPv4 addresses, I've observed that a lot of the dial failures to IPv6 addresses are for addresses of this form 64:ff9b::192.0.2.33. These are https://datatracker.ietf.org/doc/html/rfc6052#section-3.1 addresses.

In most cases these nodes also report 192.0.2.33 as their address and the subsequent dial to that address succeeds.
Can we just skip the dial to 64:ff9b::192.0.2.33?

If we cannot skip them, we should probably still rank them the same as IPv4 addresses and not prefer them to other IPv4 addresses.

@Jorropo
Copy link
Contributor

Jorropo commented Jun 12, 2023

It doesn't make sense for peoples to advertise things like 64:ff9b::192.0.2.33, on windows, linux, android, ios and macos (I havn't checked the rest) the os takes care of rewriting 64:ff9b::/96 addresses to IPv4 ones if you are using NAT64,
I think what should happen is that when adding addresses to the peerstore if an ip6 component is in the 64:ff9b::/96 range multiaddr should actually store or load it as an ip4 component.

Note: I don't know who advertise this in the first place, might be a bug somewhere (golang encode ipv4 as 16 bytes 64:ff9b::/96).
That smell someone doing:

switch len(ipaddr) {
case 4:
  // handle as ipv4
case 16:
  // handle as ipv6
}

@sukunrt
Copy link
Member Author

sukunrt commented Jun 14, 2023

What's happening here is:
A is behind a NAT64 router R. B is a publicly reachable IPv4 only node with IPv4 addr 192.0.2.33

A connects to B via NAT64 router R
From _A_s perspective it sees the address of B as 64:ff9b::192.0.2.33. It informs B about this address via identify. B will believe A that its address is this IPv6 address.

Note: B shouldn't believe this, but that's a separate issue in identify. Will open a separate issue for that.

@Jorropo Can you explain how the OS takes care of the rewrite? Let's only consider linux and go-libp2p.
My understanding so far is that this requires some DNS64 like system for A to get a IPv4-converted IPv6 address like 64:ff9b::192.0.2.33

I ask because according to my understanding, A does need the address in the converted form to make the call to B. However if the system can be configured to do this automatically it is safe to drop this.

@sukunrt
Copy link
Member Author

sukunrt commented Jun 14, 2023

@marten-seemann Not taking this up for #2365 . We can handle this case in a follow up PR.

@Jorropo
Copy link
Contributor

Jorropo commented Jun 15, 2023

Can you explain how the OS takes care of the rewrite? Let's only consider linux and go-libp2p.
My understanding so far is that this requires some DNS64 like system for A to get a IPv4-converted IPv6 address like 64:ff9b::192.0.2.33

There is this feature called 464XLAT CLAT (Customer side tranLATor) which instead of using a "lying" DNS layer which give you NAT64 compatible IPv6 addresses, the edge clients just do the rewriting themselves.
I was under the impression this was widely available on updated OS, seems like I was wrong, this was mainly deployed for cecular mobile carriers but having it being used in all networks has been catching on and phones also support on wifi not just cellular.
It is still based on NAT64 except now instead of relying on DNS64 rewriting, the host OS (computer, phone, ...) just knows it should rewrite it to an 64:ff9b address and just do it.
In the wild deploying 464XLAT is as easy as having a valid route for your NAT64 64:ff9b which gets nated and phones and computers will try it if they see they lack ipv4 connectivity.

After digging:

  • Android supports it since 4.3 (forever ago)
  • I've seen reports latest macos and ios supports it idk about when this was introduced.
  • I don't know about windows.
  • Seems like this does not ship by default on most linux distros (what a shame).

Note there are details about how you combine different XLAT and do ipv6 over ipv4 back to ipv6 but for the final machine it's as easy as just sending ipv6 packets with the 64:ff9b header and terminated with an IPv4 address.
*actually there might be some dhcp dark magic in enabling CLAT, I'm not exactly sure, overall last time I tried with an android phone it "just worked" with whatever default dhcp6 config I had setup.

@sukunrt
Copy link
Member Author

sukunrt commented Jun 26, 2023

NAT64 only nodes who are solely reliant on DNS64 will want to dial these addresses. So I propose:

  1. We filter these addresses when we receive them in identify. identify: filter nat64 well-known prefix ipv6 addresses #2392
  2. We rank these addresses lower than IPv4 addresses in dial ranking. swarm: rank nat64 well-known prefix addresses lower #2393

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants