the8472 / mldht

Bittorrent Mainline DHT implementation in java
Mozilla Public License 2.0
147 stars 45 forks source link

IPv6 not working on version 1.5.9 #6

Closed tiagop717 closed 6 years ago

tiagop717 commented 7 years ago

I didn't know another way to contact the people responsible for the plugin, so I'm writing here. I'm sorry if this isn't the right place.

Basically I tried everything to make mlDHT IPv6 to go past "Stopped" but nothing fixed it (disabling firewall, checking NAT settings, changing ports etc). So now I decided to try the previous version (1.5.7) and it suddently started "Running" again.

I just thought you should know. It doesn't seem to be an issue with my connection/system because the previous version starts running as soon as Vuze starts, while 1.5.9 starts "Stopped" and stays like this with no change no matter how much time passes.

Thanks.

P.S: IPv4 has no issues on either the versions.

the8472 commented 7 years ago

This project is a fork of the vuze plugin. The plugin source can be found at http://dev.vuze.com/ You should to report issues with the plugin at https://forum.vuze.com/

I'll leave this issue open since I might try to unify the projects eventually, but that's unlikely to happen in the short-term.

As a workaround you could open the .jar file of the previous working version and edit it to have a higher version number so it doesn't auto-update

parg commented 7 years ago

Hey, parg here :) If you get a chance perhaps you could check out https://github.com/BiglySoftware and https://github.com/BiglySoftware/BiglyBT-plugin-mlDHT - unification would be awesome!

the8472 commented 7 years ago

The idea would be stripping the plugin the DHT implementation itself, just leaving the UI, peer source integration and scheduling and deferring to this repo for the heavy lifting.

parg commented 7 years ago

Agreed - I've been vaguely maintaining the plugin over the years, only enough to keep things running really. At least BiglyBT is Java 8 as well...

parg commented 7 years ago

Just for fun I deleted the 'kad' package and DHTConfiguration.java from the Vuze/BiglyBT plugin and linked it to your latest and greatest and there were only 31 errors - would you have a few cycles to take a look at them? If not I'll start working through them to see what I can figure out.

the8472 commented 7 years ago

If you have specific questions I can help, but beyond that I have little spare capacity.

parg commented 7 years ago

Totally understand :)

The one area that I currently could do with some help with is the ability to specify restricted bind-ips.

In the Vuze plugin AddressUtils uses

InetAddress[] allBindAddresses = NetworkAdmin.getSingleton().getAllBindAddresses(true);

as the starting point for figuring out what to use.

In your repo AddressUtils has, I think, two methods that would need to respect the required bind ips:

getAvailableGloballyRoutableAddrs and getDefaultRoute

Is this right? What do you think is the best way of dealing with this?

For the available routable addresses I guess they could be filtered by the required IP set?

For the default route this could perhaps just be set to (one of) the required bind ips?

cheers

the8472 commented 7 years ago

AddressUtils are low-level stuff that reflect what the machine actually supports. It's used by the RPCServerManager to choose bind addresses. The latter currently has no notion of a whitelist.

I think the right approach is to extend DHTConfiguration so it can return a Predicate which will be used to filter down the available addresses to what is allowed.

the8472 commented 7 years ago

I have implemented that approach in in 02a832872ca088b81faef74726528f4c0ac4d301 Didn't have time to test it though. See if it works for you.

parg commented 7 years ago

Great! I'm away for a few days but will hack around with it when I get back

On Fri, Aug 4, 2017 at 9:40 PM, the8472 notifications@github.com wrote:

I have implemented that approach in in 02a8328 https://github.com/the8472/mldht/commit/02a832872ca088b81faef74726528f4c0ac4d301 Didn't have time to test it though. See if it works for you.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/the8472/mldht/issues/6#issuecomment-320348237, or mute the thread https://github.com/notifications/unsubscribe-auth/AAYIHfu7vDexYtbovnWqQfoDIq_qoSl5ks5sU4GtgaJpZM4N13Ph .

atomashpolskiy commented 7 years ago

@the8472 , hi! I've tested your change, and it works fine. There's one subtle gotcha with this approach, if the library user decides to use equality check as a predicate, then he has to know that in terms of Java objects IPv4 any-local is not equal to IPv6 any-local (due to how Inet4Address#equals and Inet6Address#equals methods behave). At the same time other JDK networking classes can use these two types of addresses interchangeably, so it can be a bit confusing. So the predicate has to be a bit complicated, as you may see in b43fa86. Probably it could be done in mldht (for instance, if predicate returns true for 0.0.0.0, then assume that :: can also be used and do not bother asking). Hope it makes sense

the8472 commented 7 years ago

then he has to know that in terms of Java objects IPv4 any-local is not equal to IPv6 any-local (due to how Inet4Address#equals and Inet6Address#equals methods behave).

This is actually intentional. If you have a whitelist of allowed bind addresses, netmasks and interface names, e.g. eth0, 0.0.0.0, fe80::/10 and translate this list to a predicate then the normalized version of the predicate will allow any IPv4 bind address while only whitelisting specific v6 addresses.

This is a common pattern in daemon configuration files.

At the same time other JDK networking classes can use these two types of addresses interchangeably

That's actually platform and configuration-specific. openjdk certainly tries to use dual-stack sockets by default, but it doesn't guarantee it. You can also explicitly specify a ProtocolFamily when opening a socket, mldht does this because the address family matters greatly to the DHT (BEP5 and BEP32 are separate networks).

But for privacy-conscious users this can matter too, e.g. they might have a IPv4 default route through a VPN but the VPN does not support IPv6 at all or just add one route among many, making the host multi-homed. In that case 0.0.0.0 would be perfectly fine, but :: wouldn't.

atomashpolskiy commented 7 years ago

Thank you for the explanation, I didn't even think about multihoming and complex configurations.

atomashpolskiy commented 7 years ago

I was thinking of doing something similar in my project, and realized that Predicate does not allow ordering of rules. Maybe it would make sense to sacrifice some performance and provide a list of rules, that would be checked in the order of appearance to select the matching addresses? It's going to be O(mn) as compared to O(n) for current approach, but is arguably more versatile. Of course, it only makes sense if the maximum number of bindings is bound, otherwise it's equivalent to a simple predicate.

the8472 commented 7 years ago

There might be some use-cases for preference-ordered binding, but I can't think of one right now. For ipv6 multi-homing is easy anyway. there's not much of a reason not to bind to all allowed interfaces. IPv4 is what's hard because you can't be sure whether different internal addresses correspond to separate external addresses or not. I have spelled out most concerns from the DHT perspective in BEP 45. Binding for the core protocol is a bit different since there are no concerns about node identity, so it's usually easier to bind to the wildcard address there.

atomashpolskiy commented 7 years ago

E.g. when I'm at work, I don't want to be a jerk and prefer to exclusively use a 4G modem for torrents. But if I ran out of money, I still need to watch my Game of Thrones S8E10, so I fall back to employer's Wi-Fi. Though it may sound a bit artificial :D

the8472 commented 7 years ago

In the case of single-homing you can simply tell mldht to use that single address. You can change the predicate as needed, mldht doesn't cache it. And in the case of multi-homing preference order does not make sense, you want to use all the interfaces in parallel after all.

atomashpolskiy commented 7 years ago

Of course, but the point was exactly that no configuration change would be required.

If we put my case in a more formal way:

Then it can be described with a list of two predicates: 1) (addr) -> addr.equals(modemAddress) 2) (addr) -> Optional.ofNullable(NetworkInterface.getByInetAddress(addr)).filter(iface -> iface.getName().equals("en0")).isPresent()

Which can then be statically defined in the application-level configuration, so I don't need to think about this matter each time I launch the app.

For sure, switching between rules can be handled on the application level, but it will effectively require re-implementing what is already present in the library (I can see that there is a scheduled periodic task for updating bindings on the fly). But yeah, it's definitely possible to perform analogous checks in the application and restart mldht (or update the DHTConfiguration instance).

the8472 commented 7 years ago

mldht already has a fairly complicated internal ruleset for interface selection in single-homed mode because the goal is to avoid binding to the wildcard address whenever possible and the approaches differ for ipv4 and ipv6. I want to avoid pushing application level concerns into that.

the8472 commented 6 years ago

@psychic717 next BiglyBT mldht plugin version (2.2 presumably) will use this library again, so if you still see ipv6 problems with that I can help.

parg commented 6 years ago

2.2 is live for beta users

the8472 commented 6 years ago

Closing, please reopen if you still are facing ipv6 issues.