API < 21 support #2
Comments
The min SDK version has been set to 21 due to the call to setBlocking(true). The VPN interface is non-blocking par default, which would be great if there was a possibility to select/poll it, but it is not possible since FileChannel is not selectable. So we have a non-blocking interface without asynchronous I/O API, which is stupid. This means that when no data is available, every read would return immediately with 0 bytes… Therefore, to avoid a busy loop with arbitrary sleep(), I had no choice but to use blocking mode and read from a different thread. However, you could set the non-blocking mode from native code in order to avoid calling this method from API 21. I didn't do it because then, the NDK would be required for building gnirehtet (and 1 apk per architecture), which IMO would be a bit overkill for this. |
so the simplest pre-21 solution (without NDK) would probably be to create a long-running thread that just polls then sleeps (maybe every 150ms) if no data is available, ie created in RelayTunnel.open and polls RelayTunnel.receive. I also noticed that pre 22 There doesn't seem to be any related android-support libraries for VPN. If this is infeasible, I can attempt the NDK solution. I learned C/C++ in college a few years ago but haven't used either since. But seeing as it should amount to setup/config and a single syscall it may be simpler. |
In principle, yes, using polling as a fallback when API < 21 is a good compromise I guess. However, what is set blocking by the API 22 is the VPN interface (used for the communication between Android and gnirehtet), not the relay tunnel (used between the gnirehtet client and the relay server). NOTE: the relay tunnel is also used in blocking mode in the client, but this design follows the fact that reading and writing are executed from separate threads, caused itself by the VPN interface beeing blocking. Therefore, you need to replace both this blocking read and this blocking write (which calls this real blocking write) by some polling. Tip: sleep only when the previous read/write returned 0 (e.g. don't wait if you just received data, maybe there are more available), otherwise performance would suffer too much. |
@xstherrera1987 as @rom1v mentioned, the main problem is non-blocking tunnel descriptor. but i use native code to put in into blocking mode. and u dont need one apk per arch, its suitable for arm, mips and x86:
|
Another solution to enable blocking mode without depending on the NDK is to call I'll probably investigate this solution. A quick test shows that if I replace the call to |
The minSdkVersion was set to 21 due to the call to VpnService.Builder.setBlocking(true). On API < 21, we can call the internal method libcore.io.IoUtils.setBlocking() using reflection: <https://android.googlesource.com/platform/libcore/+/30c669166d86d0bd133edfb67909665fb41d29b6/luni/src/main/java/libcore/io/IoUtils.java#89> Therefore, use it as a fallback and set the minSdkVersion to 14, in order to support devices from Android 4.0. Related to <#2>.
The minSdkVersion was set to 21 due to the call to VpnService.Builder.setBlocking(true). On API < 21, we can call the internal method libcore.io.IoUtils.setBlocking() using reflection: <https://android.googlesource.com/platform/libcore/+/30c669166d86d0bd133edfb67909665fb41d29b6/luni/src/main/java/libcore/io/IoUtils.java#89> Therefore, use it as a fallback and set the minSdkVersion to 14, in order to support devices from Android 4.0. Related to <#2>.
I just tried on several Android 4.x devices, unfortunately
So even if I may set the VPN interface in blocking mode, it still does not work… :-(
However, it should be possible to "revert" the connection with 2 Or we need another way to open a TCP connection between the client and the relay server… |
So I'm closing this issue as WONTFIX. |
@rom1v thanks so much for the |
I have an API 19 tablet that for whatever reason has defective/inconsistent wifi capabilities. I'd like to fork this project to provide support for API 19 at least. My question then is why is min API set at 21, is it just for UI compatability/simplicity issue or is there some network API's on 21? Im not very familiar with low-level Android network API's so any help is appreciated, thanks.
The text was updated successfully, but these errors were encountered: