Conversation
| private native int runMain(); | ||
|
|
||
|
|
||
| public native static boolean fatal(); |
There was a problem hiding this comment.
we can remove this fatal() method and the corresponding C method JNIEXPORT jboolean JNICALL Java_org_torproject_jni_TorService_fatal(JNIEnv *env, jobject thisObj);. This is just temporarily here for testing
5d73f6d to
ba73a7f
Compare
|
What branch should I be looking at for the required changes to Tor? |
|
For tor-android it's this branch I think if you run this in tor-android it should add my fork as a remote, and then automatically grab the branch. Not 100% certain right now.: cd external/tor
git remote add bitmold https://github.com/bitmold/tor
git fetch bitmold
cd ../...
./tor-droid-make.sh fetch -c I don't have a modified version of Orbot online yet. I didn't change it much, I was just printing debug logs in |
|
Thanks. I just cherry picked your commit since I have additional changes that I want to keep. |
|
One thing I have noticed since Tor is now running in it's own process is when Android is under heavy load, lowmemory killer can sometimes kill Orbot's process. But, when that happens, the Tor service now becomes zombified. Simply restarting Orbot does not work in this case. I have to go into android developer settings, and then select running services and manually stop the remaining cached Orbot processes before Orbot will run properly again. |
da4c889 to
51e6203
Compare
Moving
torinto its own process has helped Orbot not completely crash whenever there's an error intor- these often come fromtorrerr.h'stor_raw_abort_(void)method.When this happens, Orbot gets into so many broken states. You have to reopen it, see that it's broken, and force stop the app. It's not really clear to the user that the background process stopped, other than that the VPN died. if users don't have "always-on VPN" and "block connections without VPN" they might not even realize that Orbot suddenly broke in the background and are now browsing in the clear...
With a small method inserted into
tor_raw_abortwe can actually quickly invoke a method inTorServicethat can be used to tell Orbot, hey, the tor process is about to be killed. This can allow users to automatically recover from the process, and can also be used to inform the user that Tor had a technical difficulty and will be back online shortly. This is so much better than users having to reopen the app, force stop & restart it/etc.This works by:
JNI_GetCreatedJavaVMs- which you normally need a min API of 31 to access, but it's often been present on Android devices throughout the years just not officially included in what the NDK exposes. We can use this method to grab a reference to the JVM. I've found that some huge libraries do attempt this kind of approach. So even thoughJNI_GetCreatedJavaVMsisn't linked into apps building against the NDK, it's often found in shared objects that are on Android devices and can be dynamically loaded. Most devices have at least one of:[libnativehelper.so](https://android.googlesource.com/platform/libnativehelper/+/HEAD/include_jni/jni.h?autodive=0#1103),libart.so,libdvm.sowith a working implementation of this method.dlopen()any of these shared objects. If you can't find it after trying all of them if the JNI method isn't found, just give up and lettor_raw_abort()do what it does.TorServicejava class. If you can load theTorServicein the JVM, we can invoke a new static method that I've defined inTorServiceto quickly blurt out anIntentto the main Obrot app saying thattor's about to die, right before it theabort()takes place.TorService, justreturnand go back to theabort(). Again, when this new apporach fails, you just fall back to the behavior we have today. You'll hittor_raw_abort_,torwill crash, and users will be a bit confused with Orbot...C-> Javapathway isn't possible, it fails gracefully. If for some reason this new C code causes some unforeseen problem that brings about a crash, well.... that's still what was about to happen anyway. (this happened a bit before I finished debugging this implementation...) 🤷♀️ So even if normally this mentality of "idk it shouldn't crash but it might" 🤷♀️ is completely unacceptable, it's actually something useful and harmless here because one way or the other everything's just going to fatally crash & go up in flames all the same 😈Here's the changes to
tor'sliberr.c(putting#imports and stuff here just to make everything visible on this page in one place, it's one new method that we invoke once intor_raw_abort()):^ we need this kind of nonsense because you can't start from C and jump into Java. Under normal circumstances, it is possible to go from
Java -> C -> Java, but you are always starting from Java. When you go fromJava -> Cyour C method has aJNIEnvpointer as one of its parameters, this is the critical thing you need to then go about invoking arbitrary Java code from within a C method..So with the normal constraints (which are otherwise sensible) it's impossible to deliver the news to Orbot. We have to do this cursed ritual in order to pull the necessary
JNIEnvpointer out of thin air.I've been testing this in Orbot by creating a method in
TorService's C code that callstor_raw_abort_(). I wired it into a button on the main screen and have been using it to crash the app on demand. I've been consistently had success running some Java just before tor'sabort()nukes everything...