libtorrent icon indicating copy to clipboard operation
libtorrent copied to clipboard

Feature: NAT64 Support for IPv6-only Networks

Open tiagogaspar8 opened this issue 3 years ago • 7 comments

libtorrent version (or branch): any platform/architecture: any compiler and compiler version: any

Currently BitTorrent can't be fully used in IPv6-Only networks because many peers reported by trackers are only accessible via IPv4 and are reported as literal IPv4 addresses which means they cannot be translated to a mapped v6 prefix via DNS64.

Most IPv6-only networks have a NAT64 service deployed that allows access to the IPv4 world via a /96 IPv6 prefix that maps the entire IPv4 internet. I think libtorrent could utilize a NAT64 gateway to bridge the gap between the IPv4 and IPv6 BitTorrent worlds. By rewriting IPv4 addresses received from torrent trackers (and from other sources) as an IPv6 address in the NAT64 prefix, libtorrent could download and upload to and from IPv4 peers via a NAT64 gateway while only having IPv6 internet access.

This NAT64 prefix could either be automatically detected by querying the ipv4only.arpa zone (hard) or hard-coded via a checkbox and text field in a settings pane (easy).

The auto-detection workflow could look something like the following:

  • Detect if libtorrent is currently running IPv6 only (get addresses, if no IPv4 -> IPv6 only)
  • Resolve ipv4only.arpa AAAA record and extract the first available NAT64 prefex (See RFC8880)
  • Configure the client to translate any IPv4 peer addresses to IPv6 peer addresses
  • Optionally, this logic could also be applied to the IP address of torrent trackers but those ususally use DNS names and can therefore be transparently translated to IPv6 via DNS64.

NOTE: "Forwarded" from https://github.com/qbittorrent/qBittorrent/issues/14690

tiagogaspar8 avatar Jan 03 '22 11:01 tiagogaspar8

is this something that's normally built into applications? I would have thought it to be a lot more practical to do as a virtual network interface, with an IPv4 address.

arvidn avatar Jan 23 '22 12:01 arvidn

Usually, it isn't necessary, because normal applications like chrome use dns, for example:

  1. Chrome wants to access example.com
  2. System does a dns lookup to example.com
  3. The network DNS respods with a nat64 fabricated address like 64:ff9b::1.2.3.4
  4. Chrome accesses 64:ff9b::1.2.3.4 via ipv5 which is nat64ed into 1.2.3.4
  5. The rest of the conversation continues and the website is loaded

The issue with bittorrent clients is that the IP addresses of peers aren't provided by dns but though the DHT network (or something else) so the network DNS isn't able to do the conversion.

There are some alternatives:

  • Do 464CLAT ath the client side, converting IPv4 requested by apps in IPv6 and vice versa, while this is the easiest it's not plug n play because it requires configuration and setup on the client side, and, that I'm aware of, only iOS and Android Have the detection system and are prepared to do the conversion on the fly transparently without user configuration
  • Convert apps to be IPv6 ready which generaly means, don't bind to IPv4 or bind to IPv4 or/and IPv6, whichever is available and use DNS which lets the conversion be made seamlessly

In the case of libtorrent, the second one isn't possible because, as stated previously, libtorrent doesn't use DNS, so it just needs to make a simple query AAAA query to ipv4only.arpa and get the prefix, so that every time a peer IPv4 address is given, it can be converted to NAT64 fabricated addresses and accessed over nat64.

In case you need any more help just say so!

tiagogaspar8 avatar Jan 23 '22 13:01 tiagogaspar8

I believe I could pass an IPv4 address string to getaddrinfo(), would that be sufficient to perform the conversion? Or is this conversion implemented in an actual DNS server? I would expect DNS client libraries wouldn't ask the server when they have the IP address already, but perhaps they do.

arvidn avatar Jan 23 '22 14:01 arvidn

I believe I could pass an IPv4 address string to getaddrinfo(), would that be sufficient to perform the conversion?

If I'm correct from what I read getaddrinfo is a function that performs dns lookups of a string provided, be it an address or a domain. If that's correct then it wouldn't work since the DNS would respond to a query for example for 1.1.1.1 with the domain one.one.one.one

Or is this conversion implemented in an actual DNS server?

The only conversion the DNS server does is from a IPv4-only hostname to a synthesized IPv6 address, that's the only occasion that the DNS modifies responses.

I would expect DNS client libraries wouldn't ask the server when they have the IP address already, but perhaps they do.

They don't, hence what needs to happen is:

  1. When starting, libtorrent would bind to the addresses, as it does. That wouldn't change
  2. Then, it does a dns lookup of type AAAA for the domain ipv4only.arpa
  3. If there is a response jump to step 4 otherwise if it's a nxdomain proceed as it's currently coded
  4. Since the response was true, from the response which should be 64:ff9b::c000:aa (unless the network uses non-standard ipv6 prefix for nat64) libtorrent must extract the nat64. To do this we take the response given, which we know is nat64_prefix::192.0.0.170 or nat64_prefix::192.0.0.171 and we remove the ipv4-converted address which is ::c000:00aa or ::c000:00ab and what remais is 64:ff9b::/96 which is our nat64 network address
  5. After we have our network address, every time there's a need to connect to a IPv4 peer we create a IPv6 address putting nat64_prefix::IPv4 (usualy there are libaries that do the conversion between octal and hexadecimal) and the nat64 takes care of the rest

Things to note: The prefix is always a /96 since 96 from the prefix plus the 32 from the ipv4 equals to 128 which is a full ipv6 address Even though the IP's are synthesized the connection should happen like any other IPv6 connection would Unfortunately I have no coding knowledge, so I can't help you directly, yet if you explain what it does maybe I can help 😄 Any doubt you have just reach out, I'm here to help!

Some useful links (proabably): https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/UnderstandingandPreparingfortheIPv6Transition/UnderstandingandPreparingfortheIPv6Transition.html#//apple_ref/doc/uid/TP40010220-CH213-DontLinkElementID_4 https://www.rfc-editor.org/rfc/rfc7050

tiagogaspar8 avatar Jan 23 '22 18:01 tiagogaspar8

Hi @arvidn

I found this, that might also be helpful in developing this feature https://datatracker.ietf.org/doc/html/rfc7225

tiagogaspar8 avatar Apr 16 '22 12:04 tiagogaspar8

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jul 30 '22 18:07 stale[bot]

Hi,

This should remain open as it's an important feature.

Thanks.

tiagogaspar8 avatar Jul 30 '22 19:07 tiagogaspar8

Things to note: The prefix is always a /96 since 96 from the prefix plus the 32 from the ipv4 equals to 128 which is a full ipv6 address

That's not true, the NAT64 prefix can have sizes other than /96, and if that happens, the IPv4 address is inserted at another place/offset in the IPv6 address as mentioned in RFC 6052, so you can't just append the IPv4 at the end.

I also agree that that would be a useful feature for torrent clients to have.

Leseratte10 avatar Jan 21 '23 12:01 Leseratte10