Project

General

Profile

Issue #1792

WiFi connection established via RepWifi not correctly reported by the Android Framework to user-space apps

Added by Fil Bergamo 6 months ago. Updated about 2 months ago.

Status:
Resolved
Priority:
Normal
Assignee:
Category:
Wi-Fi
Target version:
Start date:
04/12/2017
Due date:
09/01/2017
% Done:

100%

Resolution:
fixed
Device:

Description

It is a suggested best practice for Android apps to check for the connectivity status of the device before performing any network-related task.
To do so, the Android Framework exposes some methods that apps can use to retrieve the available network connections, and their status.

When a WiFi connection is established via RepWifi app, although perfectly working (ping, dns resolution, web browsing), the framework still presents the WiFi connection as disabled or disconnected to the user-space apps.
This misleads apps that rely on this mechanism, so that they prevent the user from doing network-related tasks.

E.g. F-Droid prevents the user from updating the repos while connected to WiFi via RepWifi app, because it detects the WiFi connection as inactive.

A possible solution is to modify the designated system service in the Android Framework that reports the connection status to client apps.
Some research has already been done in this field.
A promising approach seems to properly modify the class "com.android.ConnectivityService.java" to read the ip routing tables, and detect the route established by RepWifi, and if present, modify the status of the corresponding "NetworkInfo" instance returned to calling applications.

0001-Fix-RepWifi-connection-not-correctly-reported-to-use.patch View (5.13 KB) Wolfgang Wiedmeyer, 08/13/2017 08:02 PM

History

#1 Updated by Wolfgang Wiedmeyer 6 months ago

Thanks for summarizing the issue!

The same issue affects USB networking (reverse tethering) and it's likely that a fix for this can be used to fix the issue for USB networking as well.

#3 Updated by Fil Bergamo 6 months ago

  • % Done changed from 0 to 10

Got everything set up to do the job.
I'm expecting to start working on it in one week. This doesn't guarantee any successful or quick resolution, though.

#4 Updated by Fil Bergamo 5 months ago

  • % Done changed from 10 to 20

Debugging Android Java framework in Eclipse works well enough, following this tutorial and this one
Thanks to that I'm now working on the issue fast and comfortably enough, and I'm now able to say that workarounds are definitely possible.
What I plan to do is create a subclass of NetworkInfo, designing it to specifically report the connection created via RepWifi, and override the default behaviour of the "proxy" methods in ConnectivityManager so that if a wifi connection on interface wlan0 is active, it gets added to the ones returned by the underlying system service.
This workaround should be enough to intercept the vast majority of Apps querying the system for connectivity status.

A deeper (and smarter) fix would need investigating the inner workings of the underlying system services, which can be done, but requires time and concentration, and I currently lack both, unfortunately.
So I will limit myself in putting up the aforementioned workaround, for now.

To summarize, I'm very optimistic about overcoming this issue.
Updates are coming.

#5 Updated by Fil Bergamo 5 months ago

  • Status changed from New to In Progress

#6 Updated by Fil Bergamo 5 months ago

  • % Done changed from 20 to 50

Just a quick update.
It works.
Changes to the "ConnectivityService" do compile, and they do work as expected.
I was able to have F-Droid update the repos via the wifi connection established by RepWifi.
So, yes. It can be done.
In the upcoming days, I'll be working on cleaning up my test code, to make it suitable for production.

#7 Updated by Fil Bergamo 5 months ago

  • Due date changed from 05/12/2017 to 05/19/2017
  • % Done changed from 50 to 80

Good GNUs, everybody!
Everything works here!

I did the following:
  • Added an internal class RepWifiConnection to the class NetworkInfo, under frameworks/base/core/java/android/net.
  • RepWifiConnection has a static method getNetworkInfo that returns an instance of NetworkInfo, whose internal state is set up according to the state of the connection created via RepWifi.
  • The connection state is determined inside RepWifiConnection by issuing the following shell commands:
    ip link
    determines whether the dongle is plugged in or not, which translates to the NetworkInfo instance being "avalable" or not.
    pidof wpa_supplicant
    determines if wpa_supplicant is running. If it's not, then the NetworkInfo instance is presented as DISCONNECTED.
    ip route
    determines whether a route for the interface wlan0 exists. If a route exists, and it has a gateway, then the NetworkInfo instance will be presented as CONNECTED.
  • Added a public static method getRepWifiNetworkInfo to the NetworkInfo class, which is a proxy to expose the internal method RepWifiConnection.getNetworkInfo.
And finally:
  • Modified the ConnectivityService class under frameworks/base/services/core/java/com/android/server, updating the method getActiveNetworkInfo which is the one that gets called in most cases when apps query for the connection state. I added a call to NetworkInfo.getRepWifiNetworkInfo(), performed only if the default behaviour is returning no connection, otherwise the default behaviour is preserved.

ConnectivityService is the system service that answers queries about the network state coming from the Apps.
In most cases the method that gets called under the hood is getActiveNetworkInfo which I modified as reported above.

The resulting behaviour of the system service is the following (tested with F-Droid, clicking on the "update repos" button):
- when the wifi dongle is unplugged, ConnectivityService reports no connections, so F-droid shows "Cannot update. Are you connected to the internet?"
- the same happens when the dongle is plugged, but no connection has been established via RepWifi.
- when the dongle is plugged AND RepWifi has successfully put up a connection, then ConnectivityService returns to F-Droid a valid NetworkInfo instance whose state is set as CONNECTED. As such, F-Droid doesn't complain any more, and succeeds updating the repos, happily using the RepWifi connection.
- F-Droid is even able to download and install apps using the RepWifi connection (but this used to work even before).

I tried to keep modifications as compact as possible, which makes it easy to remove them and restore the "original" behaviour.

Now things must be tidied up a bit and get packed nicely.
Then some more test cases need to be brought up.
In theory the vast majority of the apps out there should be covered by these modifications, but I only tested them against F-droid, because I don't know of any other app that refuses to work well with RepWifi.

If anybody knows anything about other apps presenting the same issue, please let me know, so that I can test them to make sure they work fine with my methods.

I'm then going to submit a patch immediately after a few successful tests.

#8 Updated by jc gargma 5 months ago

If anybody knows anything about other apps presenting the same issue, please let me know, so that I can test them to make sure they work fine with my methods.

Antox and OpenVPN for Android are the other apps I know of with this issue.
Antox states "Internet not found" regardless of whether "Use only WiFi" is enabled.
OpenVPN for Android perpetually delays connection attempts stating "waiting for active internet connection"

#9 Updated by Fil Bergamo 5 months ago

  • % Done changed from 80 to 90

I did introduce some other adaptations to NetworkInfo, in order to include support for reverse-tethering.
Basically the same things explained for the connection established by RepWifi apply for the connection established via the reverse-tether scripts.

Now I have everything ready for a patch.
I'm struggling with git to make it spit out the needed diff file, but for the rest, everything is ready.

#10 Updated by Fil Bergamo 5 months ago

jc gargma wrote:

If anybody knows anything about other apps presenting the same issue, please let me know, so that I can test them to make sure they work fine with my methods.

Antox and OpenVPN for Android are the other apps I know of with this issue.
Antox states "Internet not found" regardless of whether "Use only WiFi" is enabled.
OpenVPN for Android perpetually delays connection attempts stating "waiting for active internet connection"

Thanks for suggesting those apps!
I downloaded them and tried to verify the patch against them.
I dind't go very far, as I don't have any VPN service to use with "OpenVPN for Android".
Also, I'm new to Tox, so I still have to understand how it works, make a test account and proceed with testing..
I'll post any update here.

Thanks again.

#11 Updated by Fil Bergamo 4 months ago

jc gargma wrote:

If anybody knows anything about other apps presenting the same issue, please let me know, so that I can test them to make sure they work fine with my methods.

Antox and OpenVPN for Android are the other apps I know of with this issue.
Antox states "Internet not found" regardless of whether "Use only WiFi" is enabled.
OpenVPN for Android perpetually delays connection attempts stating "waiting for active internet connection"

Sorry for being terribly late in giving an answer..
I finally tested my patch against "OpenVPN for Android", and it works!

So, yes, I think I'm able to say that my mods should work for every user-space app, making the wifi connection available to them.

Thanks for suggesting those two test-cases!

#12 Updated by Fil Bergamo 4 months ago

  • Due date changed from 05/19/2017 to 09/01/2017

I put up a patch, and submitted it to the mailing list.
Correctly, Wolfgang Wiedmeyer pointed out some things to be changed both on the security and the coding style side..

I've been unable to work on that during the last two months, but I'm planning to do all the restyling before September..
Stay tuned!

#13 Updated by Fil Bergamo 3 months ago

  • % Done changed from 90 to 100

It's done!

I've completely rebased my solution to comply to Wolfgang's sensible concerns about my previous patch.
In details:
I've removed all calls to shell commands, in order to improve reliability, security, maintainability and portability.
Everything is now pure Java, making use of the java.net.NetworkInterface class.
There's much less code involved (aprox. 55 lines vs. 250+), so that the impact on the original framework is lighter.

The groundings are basically the same as before:
when apps call getActiveNetworkInfo() on the ConnectivityManager, it looks down the usual path to retrieve "standard" connections.
If no "standard" connection is found, there comes my additional code:
java.net.NetworkInterface.getByName() gets called, looking for either "wlan0" (RepWifi) or "rndis0"(Tethering).
If any one of the two interfaces is present, getInetAddresses() is called on it, to see if it has any IP address.
If the interface has an IP address in the "local" range (e.g. 192.168.x.x), then it is considered connected. So an instance of android.net.NetworkInfo is created, and its state is set as "Connected".
Finally, that instance gets returned to the caller.

The result is that user-space apps are now able to "see" the internet connection made via RepWifi or via reverse tethering.

I tested the whole thing with "F-Droid" and "OpenVPN for Android", which were two known cases to solve.
The solution should be pretty "general-purpose", so I expect quite every app to work happily with it.

What I think of as the best achievement is that the new solution doesn't need any intervention on the public API.
Everything is preserved on the public side, so that "masters" at LineageOS are happy :)

What else to say..
Everything is done. It builds just fine. It runs smooth. It does the job and does it quite well.

I'm packing the patch right now, and hope it could get merged soon :)

#14 Updated by Fil Bergamo 3 months ago

  • File 0001-Fix-RepWifi-connection-not-correctly-reported-to-use added

#15 Updated by Fil Bergamo 3 months ago

  • File deleted (0001-Fix-RepWifi-connection-not-correctly-reported-to-use)

#16 Updated by Fil Bergamo 3 months ago

  • File 0001-Fix-RepWifi-connection-not-correctly-reported-to-use.patch added

#17 Updated by Wolfgang Wiedmeyer 2 months ago

Fil, thank you very much for the patch!
I attached the patch with my Reviewed-by and a few minor formatting improvements. I added line breaks to the commit message, removed a few minor whitespace errors and moved the changelog below the --- separator, so it's not included when the patch is applied. If you agree with the patch in this form, then I'll push it.

#18 Updated by Fil Bergamo 2 months ago

Wolfgang Wiedmeyer wrote:

Fil, thank you very much for the patch!
I attached the patch with my Reviewed-by and a few minor formatting improvements. I added line breaks to the commit message, removed a few minor whitespace errors and moved the changelog below the --- separator, so it's not included when the patch is applied. If you agree with the patch in this form, then I'll push it.

I reviewed it and that's fine for me ;)
Please, if you feel like, go on and push it!

If you confirm, I'll close this issue considering it solved.
Then I will discuss other improvements in the mailing list, maybe for future commits.

Thanks,

Fil

#19 Updated by Wolfgang Wiedmeyer about 2 months ago

All right, pushed it. Feel free to close then.

#20 Updated by Fil Bergamo about 2 months ago

  • File deleted (0001-Fix-RepWifi-connection-not-correctly-reported-to-use.patch)

#21 Updated by Fil Bergamo about 2 months ago

  • Status changed from In Progress to Resolved
  • Resolution set to fixed

The Issue is solved in the next release.
Meanwhile, a patch is available, attached to this thread.

Closing as solved.

Also available in: Atom PDF