Nheko-Reborn / nheko

Desktop client for Matrix using Qt and C++20.
https://nheko-reborn.github.io/
GNU General Public License v3.0
1.92k stars 201 forks source link

Retry with ipv4 when ipv6 fails. #1586

Open ghost opened 1 year ago

ghost commented 1 year ago

Describe the bug

Very many ISPs have ipv6 available, but mis-configured.

When nheko tries to log in, it tries the first available address, which is usually ipv6, since it is the correct thing in most cases, but if if Autodiscovery failed., it does not retry with ipv4, which results in a login failure.

To Reproduce

  1. Setup broken ipv6 on your machine by, say, adding a bogus address to eth0.
  2. Try to log into matrix.
  3. Observe failure.

What happened?

No response

Expected behavior

No response

Screenshots

No response

Version

master

Operating system

Linux

Installation method

Local build

Qt version

No response

C++ compiler

No response

Desktop Environment

No response

Did you use profiles?

Relevant log output

No response

Backtrace

No response

deepbluev7 commented 11 months ago

Since we just use curl, I would expect curl to already do that automatically?

deepbluev7 commented 11 months ago

Maybe it is this issue? https://serverfault.com/questions/932796/curl-does-not-fall-back-to-ipv4

ghost commented 11 months ago

I don't think so. Curl is a debugging tool, which is expected to fail when things are misconfigured. I.e., a developer uses curl to test his website, and gets an error if ipv6 dns is set up, but the website is broken. Presumably, the developer would either report, or fix that error.

Nheko is a user-facing application, and is expected to have some sort of fallback, especially since addresses being broken is ofter out of reach for a user. For example, when ipv6 is misconfigured on the ISP side.

ghost commented 11 months ago

Maybe it is this issue? https://serverfault.com/questions/932796/curl-does-not-fall-back-to-ipv4

Mentioning this issue is correct, and the explanation there is correct.

Since the connection has entered the ESTABLISHED state, curl deems this as a successful connection to the IPv6 host, and it is correct.

Curl is at the wrong level of abstraction to find out about such errors.

deepbluev7 commented 11 months ago

Curl is using a happy eyeballs approach to connecting to the server: https://curl-library.cool.haxx.narkive.com/o3hZ0e3q/patch-add-happy-eyeballs-for-ipv4-ipv6#

This means the first connection wins. If you ipv6 is so misconfigured, that you can connect, but not receive responses, I don't think there is much we can do. Unless you know how to modify the libcurl behaviour in such a way, that it would work on your stack.

Curl is not a tool to find out about such errors, it is the http library we use, so if it doesn't work, Nheko won't work.

deepbluev7 commented 11 months ago

See also https://curl.se/libcurl/c/CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS.html

ghost commented 11 months ago

Unless you know how to modify the libcurl behaviour in such a way, that it would work on your stack.

Sure. Just make two connections at the same time, and choose the one which actually connects to a Matrix server.

if it doesn't work, Nheko won't work.

This kind of leaky abstractions has to be solved where it can be solved. What we are discussing here is still an heuristic, which can be resolved on the application level, and cannot be solved on the protocol level.

You can compare it with realtime audio communication via a cellular ISP. You might assume that your IP will be fixed all the time, but in reality it will not, it will change when you walk from one base station coverage are to another. And you somehow have to switch the TCP/UDP connection underneath the voice stream while maintaining the call.

deepbluev7 commented 11 months ago

Nheko is already connecting to both at the same time and choosing the one which actually connects, see the links I provided. If that doesn't work, then the problem is that the socket connects, but doesn't serve anything, which is a different issue and much harder to mitigate, since we can't tell, if that is intentional or not.

Can you verify using curl, that the server does NOT connect using ipv6? (Specifically connect, not return the right content)