jackBonadies / SeekerAndroid

Android client for the Soulseek peer-to-peer network
GNU General Public License v3.0
247 stars 4 forks source link

Peer Connectivity Issue #19

Closed jackBonadies closed 2 years ago

jackBonadies commented 2 years ago

There is a perplexing issue that occurs where a user can connect to the server just fine, but cannot connect to any peers either directly or indirectly regardless of either users port forwarding status. The user can login just fine, but fail to connect to my machine (which has an open port), fail to receive search results, fail to connect to any dnet parents, etc. The issue to tough as it seems to come down to .NET TcpClient.ConnectAsync(IPv4 address, port) call, where connecting to the server is a success yet connecting to a peer with an open port, for whatever reason, hangs. I don't see why the two connections would be any different.

This has happened to 2 users (both Samsung, Android 12), unfortunately I have not been able to recreate this issue (nor do I have a Samsung device running Android 12). One user did send me diagnostics here (with IPs replaced): seeker_diagnostics.txt

Any thoughts or suggestions are much appreciated. I'm just not sure what the next steps should even be.

Known occurrences on Samsung Galaxy A71 5G android 11, Galaxy S21 Ultra android 12, Galaxy Note 10+ android 12.

jpdillingham commented 2 years ago

What is likely happening is that neither user has port forwarding configured, so both users are probably attempting to connect to one another and failing.

I wouldn't be alarmed if this happens as the result of an attempt to browse someone. If it is happening after the other user has delivered search results (for example, when you try to download a file) then it is a bug, as a connection would have been established successfully to deliver the results.

I can't recall if you were able to work out port forwarding over cellular networks, but if not then connections to users who also don't have port forwarding configured are doomed to fail. I think you can probably make this work over a VPN, if the VPN supports port forwarding (for example, Mullvad).

jackBonadies commented 2 years ago

That is what I thought at first. But what makes it weird is that they cannot receive any search results (any query returns 0 results), they cannot connect to my open port, yet they can send and receive messages with the server just fine. Connecting to the server vs another client whos port is open should be the same, yet a connection can only be formed with the server for whatever reason.

jpdillingham commented 2 years ago

Yeah, that does sound strange. I'm curious whether this happens over both cellular connections and wifi; it might be some sort of filtering at the carrier level.

jackBonadies commented 2 years ago

Update - This does happen over both cellular and wifi. However, it does not happen if the user is using a VPN. Using a VPN is the only way said user can get any search results.

My best guess is that the network filtering in question refuses to make connections to ips that do not have a hostname (since thats the only thing that distinguishes connecting to the central server vs peers with an open port). Maybe it does a reverse dns check and if no hostname it drops it. Just a guess, I am not sure if such filtering is at all common, but it is the only thing I can think of.

Its also confusing where this filtering is taking place, since it is filtered for the user on both cellular and wifi. OS level? and if so how does a VPN prevent this filtering? sigh. yeah this issue is beyond my networking skill level.

jackBonadies commented 2 years ago

I believe I have found the cause and solution to this issue. When connected to an IPv6 only network (in this case Tmobile with Access Point Name protocol set to IPv6 - rather than IPv4/IPv6) one cannot connect to any IPv4 addresses. Constructing the TCP client with argument IPv6 mono (.net should be similar, though one might have to unset sockopt ipv6only) sets the socket to dual mode, automatically mapping ipv4 addresses for the network stack (and removing padding on incoming padded ipv6 mapped addresses). I'm still confused about reports of some users being able to connect to the server since the server is also ipv4, but this change does fix it for said users.