Decision on how to move forward with IPv6 connectivity setup

Bug #1506210 reported by eMTee
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
DC++
Fix Released
Undecided
Unassigned

Bug Description

Recently we have added a bunch of code containing IPv6 improvements. The code originates from AirDC which iceman50 modified for Dice++.
In his initial commit http://sourceforge.net/p/dcplusplus/code/ci/a783fa70a1a616a5d74c829a80d75ca810876665/ we can basically see the
way he used/modified this code for Dice++. It introduces a bunch of new settings but some of them has only defaults and aren't propagated in the UI.

Above a few small bugs the main problem with the initial commit is that it breaks the zero configuration (so one magic switch does everything and the user should not need to configure anything in most cases) logic for auto connectivity setup that we've implemented for DC++ before and which has proven to be highly successful throughout the DC community.

Notably the patch adds *two* (one more) checkboxes for Automatic Connectivity Detection, one for each protocol (v4/v6). This layout would require the average user to know about IP protocols and such to decide things, a requirement of special knowledge of networking to set up connectivity at times, which we have already avoided years ago.

Hence a decision made to make things easier to the user and not to break the existing layout, see commit http://sourceforge.net/p/dcplusplus/code/ci/f8c7501e096576e0e04066da81f0a4c0058b303e/

At the same time there was a (not too fruitful) discussion about improving the added IPv6 auto setup (since the implementation in the patch doesn't do much, e.g. don't run mappers at all and knowledge about the necessity of mapping / hole-punching on v6 is missing/ambigous among the people discussing the problem) which ended up with a change in the v6 IP comparsion in the detection code (see the comments in the source in the commit).

It turned out later that these later changes cause connectivity issues in both an auto detected or in a manual setup on an IPv4 only environment.

After some investigation while exmining the AirDC source code and connectivity setup UI layout it has become evident that they use a different logic in connectivity setup than we do. They have only one pane in the settings dialog (called ProtocolPage in their source) where you can separately set the auto detection/manual setup for both v4 and v6 protocols as well as there's settings to completly disable the connectivity of any of the protocols. Moreover in their setup, the manual enable/disable switch has an effect to the automatic detection: if the manual connectivity is set to disabled for a protocol then it also blocks the auto detection for the said protocol.
This logic is completly different to ours, however, the code supporting this logic is already added to DC++ through the initial commit. Basically this, with the later changes committed, causes C-C connectivity issues in the tip revision of DC++ as of the day this report is posted.

AirDC also propagates all manual connectivity settings for v6 something which we should add to our UI anyway. The following patch from Pretorian does most of it: http://pastie.org/10479684

However, we should decide in what way do we implement our v6 connectivity setup. Basically I can think of two ways, as follows:

#1
We keep our old logic so there's only one checkbox for Automatic Connectivity Setup. This either runs detection for both protocol or only for v4 for the time beeing. For the new manual v6 connectivity settings we set the v6 connectivity disabled by default.

Advantage: no change from the user's point of view. Still zero config setup that's easy to support.
Disadvantages:
- no way to set the auto detection to run for one protocol while use manual config for the other.
- requires changes to the ConnectivityManager code in added from AirDC

#2
We switch to a pair of auto detect checkboxes for one both protocols.
Advantages:
- the initial patch can be used more or less, with the exception of the manual enable/disable connectivity switches have effect on the automatic detection. We clearly don't need that.
- there's a way to set the auto detection to run for one protocol while use manual config for the other.
Disadvantage: change from the simple UI/logic we used to have which can make support cases more difficult at times.

Any of the two ways we choose I suggest keeping the v6 detection/manual connectivity disabled by default until we know more about topologies, mapping, what's when we got a public IP but we're behind a firewall, etc... since we already experienced that wrongly enabled v6 connectivity can cause C-C connectivity issues on ADC hubs.

Ideas, opinions, suggestions welcome!

eMTee (realprogger)
description: updated
description: updated
eMTee (realprogger)
description: updated
Revision history for this message
poy (poy) wrote :

Personally, I would attempt to keep the noob / experienced distinction between automatic and manual connectivity settings.

That means:

- Only 1 "magic" check-box in automatic settings, that does both IPv4 & IPv6 detections (or only the IPv4 one while the IPv6 one is not yet polished / known not to have conflicts with the IPv4 one).

- 2 setting groups (or even possibly 2 setting pages) for manual connectivity.

I have no opinion on disabling IPv4 / IPv6 via manual connectivity settings; if it works, let's add it.

One point of attention: check how port mappers react when receiving requests for both IPv6 & IPv4 ports... Should work as long as it's for separate ports...

Revision history for this message
eMTee (realprogger) wrote :

I think it's better to disable IPv6 via manual connectivity settings by default. If it's enabled and the user doesn't have public v6 IP (or she does but is firewalled) then DC++ will try to connect to certain set of clients though IPv6 in ADC hubs, which obviously fails in the above cases. People who know what they're doing can always enable it for themselves.

(Another thing to investigate why would DC++ connect to only DC++'s in v6 and not to other capable clients - as that's the case at the moment.)

The IPv6 auto detection code never runs any mapper in the current implementation we got from AirDC (unreachable code). Reason is not clear but as I mentioned after a lengthy discussion we couldn't think of any possible way of what would be the best logic of the v6 detection. There were too many questions that the people discussing and web searches could not answer straight.

Revision history for this message
eMTee (realprogger) wrote :

Correction:
I am not sure what clients DC++ connects to or not when IPV6 is set up correctly (I don't have such connection, probably it works for all) but when there's only V4 connectivity available and v6 is set to errorously enabled in DC++ then strange things happen: DC++ tries to connect though IPv6 (and fails) to other DC++'s while it successfully connects through IPv4 to other clients like AirDC, StrongDC++, etc... (ones that have different IPv6 low level socket code implementation than us).
This is what I meant to be investigated.

Revision history for this message
maksis (maksis) wrote :

"while it successfully connects through IPv4 to other clients like AirDC, StrongDC++, etc... (ones that have different IPv6 low level socket code implementation than us)."

The low-level socket implementation in AirDC++ should be very similar as in DC++.

"If it's enabled and the user doesn't have public v6 IP (or she does but is firewalled) then DC++ will try to connect to certain set of clients though IPv6 in ADC hubs, which obviously fails in the above cases."

The socket implementation already allows connecting via both protocols in parallel. Given that the client has support for HBRI connectivity, it won't matter if IPv6 fails. Naturally there are cases when the users to a hub via IPv6 while only having passive IPv4 connectivity functional for transfers, but...

You should also consider the case when users connect to a hub via IPv6. If you decide not to have hybrid connectivity, that would make the clients show as only having passive IPv6 connectivity, which isn't good either.

I think that AirDC++ has dozens of possible connectivity combinations between the clients (I made a table of those once), so it's not simple at all.

Revision history for this message
eMTee (realprogger) wrote :

Changes that largely implements what's discussed above is committed.
Problems still to solve (above what's described in comment #4):
- Ports and mapper settings still shared between v4 and v6 although SettingsManager items and GUI parts added for the separate v6 settings (unused/disabled respectively for now)
- IPv4 'Disabled' state has no effect on NMDC connections
- Switching off Automatic detection does not restore manual incoming ports settings despite the autoSettings map is correctly erased. A subsequent settings save or a restart needed to get the correct manually set values back.

Changed in dcplusplus:
status: Confirmed → In Progress
Revision history for this message
poy (poy) wrote :

I have a fix for the last issue (port settings not honored after disabling auto-detection), that hopefully does not introduce any regression. The code in question is quite convoluted; hard to be confident about a change in there... Please test.

The other issues are in my opinion "acceptable" for now and should not be blocking a release; what do you think?

Revision history for this message
eMTee (realprogger) wrote :

Tested, looks OK.
Switching Auto Conn Setup on/off results the correct ports (manually forwarded vs. randomly chosen by upnp) shown when invoking /connection chat command and the protocol log also shows that the correct ports are actually used for IPv4 C-C connections.

Generally this means we're at where we were before the changes, I'd rather call the rest of the "issues" are missing or beta state features which can be also indicated in the changelog.

Assuming this code now stays for the next release I'll go on with docs update and removal of some traces of WinXP support, etc...

Revision history for this message
poy (poy) wrote :

good. the only regression I am wary off is about IPv6 being disabled by default; I hope this version does not inadvertently disable IPv6 connections that previously used to work "off the shelf".

Revision history for this message
eMTee (realprogger) wrote :

Well the feature isn't anywhere near to complete and now will change/improve with the new version. From now it should work "off the shelf" as before if someone sets Auto Conn Setup on which is the expected logic anyway.
If it's not an option for some then there's new manual setup just like in case of IPv4.
But honestly IPv6 C-C connections are still very limited (see comment #4) so I don't think these changes would hit huge number of people hard...

Revision history for this message
eMTee (realprogger) wrote :

Refreshing my memory by examining the current logic I understand poy's concern more and what's written in comment #9 is actually the desired behaviour after the whole thing is feature complete.

The IPv6 "auto detection" is currently cannot be enabled in the GUI, it was made unavailable because of several reasons like the whole thing is just a copy of the v4 code structure but does not really do anything useful right now. It's not even decided what should it do or how should it work, hence this bug report was made.

So to see the current implementation work "off the shelf" as previously, we should set the INCOMING_CONNECTIONS6 setting to SettingsManager::INCOMING_ACTIVE by default.

Revision history for this message
poy (poy) wrote :

I wanted to prevent 2 port mappers from running in parallel, so I restored the MappingManager singleton and implemented IPv6 port mapping slightly differently; then one change led to another and before I knew it I had rewritten quite a good chunk of the connectivity / port mapping code. :P

I have restored IPv6 port mappings (they went to disabled before); port mapping runs once after auto-detection is done (for IPv4 / IPv6 / IPv4 + IPv6).
Also cleaned up some unused settings.

Works fine as far as I could test; hope it's all good...

Revision history for this message
Francisco Blas Izquierdo Riera (klondike) (klondike) wrote :

Hi guys, I have been reading this and I'm a bit confused regarding the port mappers and IPv6. In case it helps here is my knowledge about it:
* UPnP has a draft for IPv6 https://tools.ietf.org/html/draft-bnss-v6ops-upnp-01 To my knowledge UPnP is the most extended solution for this task but I doubt many routers actually support the solutions propossed on that draft.
* NAT-PMP has no IPv6 support https://tools.ietf.org/html/rfc6886 but its successor, PCP, does https://tools.ietf.org/html/rfc6887

Personally I don't think implementing port mapping on IPv6 matters much at this stage:
* Most IPv6 users are either technically experienced or have a system setup made by a technically experienced user. Either way they can open the port themselves or request somebody to do it.
* The ones that don't follow the above premise usually have a fully open firewall for IPv6 and rely on things like privacy extensions to be hard to locate.

This is likely to change in the future though.

I hope this input can be of help to you :)

Revision history for this message
maksis (maksis) wrote :

Yeah, automatic detection in AirDC++ won't do any port mapping because of the reasons above. It's unclear to me that who's using NAT with IPv6 but I still implemented port mapping code for manual (experimental) use since MiniUPNPc had support for IPv6. Maybe it can be used for opening ports from the firewall in future.

I still find the current behavior in AirDC++ to be reasonable: disable (=avoid, http://www.airdcpp.net/forum/viewtopic.php?f=13&t=4374) IPv6 when there is only a link-local (fe80) v6 address available. Unique local addresses (https://en.wikipedia.org/wiki/Unique_local_address) will also require manual configuration at the moment as I'm not sure that where/how those are being used (I don't think that any home router should be using those...).

Note that Util::isPrivateIp may not work as expected for v6 as it will return true only for link-local addresses. I reworked the code a while ago: https://github.com/airdcpp/airgit/blob/775bdc1fc1a58a2d0720cc4a8122f3e85897b8b6/airdcpp/airdcpp/Util.h#L543-L555

Revision history for this message
eMTee (realprogger) wrote :

Maksis' logic is right and setting ipv6 manually as active by default breaks the connectivity for me on ADC to those who have v6 (I don't have v6 connectivity at all).
It's not the way DC++ worked off the shelf before and I am now unsure how it was before.
A release with INCOMING_CONNECTIONS6 setting to SettingsManager::INCOMING_ACTIVE by default will break things for people with similar setup, v4 only connectivity with manual port forwarding.
They have to disable v6 connectivity to get things fully work and there's a little issue with that which should be added to the list of things to fix later: currently to manually enable/disable ipv6 connectivity it's not enough to save/close the settings dialog, a restart needed for the changes to take effect.

Revision history for this message
poy (poy) wrote :

thanks klondike, will keep PCP in mind! no worries about NAT-PMP; only UPnP is used for IPv6. as maksis explained, it's available in our lib so there's little effort in adding that support. :)
(assuming the lib does work - I couldn't test with my ISP-provided box.)

thanks for the Util::isPrivateIp fix also; I was wondering why it was telling me my v6 IP is public when testing...

regarding default settings, of course, disable if there's an issue (I wasn't aware there were).

about live enabling / disabling, isn't it enough to disconnect / reconnect hubs?

Revision history for this message
eMTee (realprogger) wrote :

Yes it is enough to disconnect / reconnect hubs. So no restart needed then.

Revision history for this message
poy (poy) wrote :

thanks maksis, I've brought some of your changes back into DC++. it looks to me the version we have of your connectivity improvements is not the latest, so I'm slighly worried we may be missing other stuff...

in particular, I notice your getBindAdapters / getDisplayAdapters is not the same as our getIpAddresses... should that also be copied?

this is all a bit over my head; would be much easier if you maintained these parts directly in DC++. :)

Revision history for this message
maksis (maksis) wrote :

Apart from https://github.com/airdcpp/airgit/commit/775bdc1fc1a58a2d0720cc4a8122f3e85897b8b6, I haven't really made notable changes to detection-related code during the last few years. I just noticed that there was a need to make some of the functions a bit more "universal" after reading your detection logic changes :p

I don't currently have plans to make other changes to that code (except maybe adding support for binding to an actual network adapter instead of an IP address: http://www.airdcpp.net/forum/viewtopic.php?t=4477).

poy (poy)
Changed in dcplusplus:
status: In Progress → Fix Committed
Revision history for this message
poy (poy) wrote :

Fixed in DC++ 0.860.

Changed in dcplusplus:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.