mirror of
https://github.com/emanuele-f/PCAPdroid.git
synced 2026-06-16 21:10:57 +08:00
Show fatal errors in the gui and terminate vpn
This commit is contained in:
parent
6d47d75805
commit
c78aba0dae
@ -28,6 +28,7 @@ import android.net.ConnectivityManager;
|
||||
import android.net.VpnService;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
@ -42,6 +43,7 @@ public class CaptureService extends VpnService implements Runnable {
|
||||
private static final String TAG = "CaptureService";
|
||||
private static final String VpnSessionName = "PCAPdroid VPN";
|
||||
private ParcelFileDescriptor mParcelFileDescriptor = null;
|
||||
private Handler mHandler;
|
||||
private Thread mThread;
|
||||
private String vpn_ipv4;
|
||||
private String vpn_dns;
|
||||
@ -95,6 +97,8 @@ public class CaptureService extends VpnService implements Runnable {
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Context app_ctx = getApplicationContext();
|
||||
|
||||
mHandler = new Handler();
|
||||
|
||||
if (intent == null) {
|
||||
Log.d(CaptureService.TAG, "NULL intent onStartCommand");
|
||||
return super.onStartCommand(null, flags, startId);
|
||||
@ -392,6 +396,12 @@ public class CaptureService extends VpnService implements Runnable {
|
||||
mHttpServer.pushData(data);
|
||||
}
|
||||
|
||||
public void reportError(String msg) {
|
||||
mHandler.post(() -> {
|
||||
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
|
||||
});
|
||||
}
|
||||
|
||||
public static native void runPacketLoop(int fd, CaptureService vpn, int sdk);
|
||||
public static native void stopPacketLoop();
|
||||
public static native void askConnectionsDump();
|
||||
|
||||
@ -161,6 +161,10 @@ public class MainActivity extends AppCompatActivity implements LoaderManager.Loa
|
||||
if (status.equals(CaptureService.SERVICE_STATUS_STARTED) && (mState == AppState.starting)) {
|
||||
appStateRunning();
|
||||
} else if (status.equals(CaptureService.SERVICE_STATUS_STOPPED)) {
|
||||
// The service may still be active (on premature native termination)
|
||||
if (CaptureService.isServiceActive())
|
||||
CaptureService.stopService();
|
||||
|
||||
appStateReady();
|
||||
}
|
||||
}
|
||||
@ -168,6 +172,14 @@ public class MainActivity extends AppCompatActivity implements LoaderManager.Loa
|
||||
}, new IntentFilter(CaptureService.ACTION_SERVICE_STATUS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
if(mMenu != null)
|
||||
initAppState();
|
||||
}
|
||||
|
||||
private void notifyAppState() {
|
||||
for(AppStateListener listener: mStateListeners)
|
||||
listener.appStateChanged(mState);
|
||||
|
||||
@ -27,6 +27,33 @@
|
||||
#include <malloc.h>
|
||||
|
||||
static int loglevel = 0;
|
||||
static JNIEnv *cur_env = NULL;
|
||||
static jclass vpnclass = 0;
|
||||
static jclass vpn_inst = 0;
|
||||
static jmethodID reportError = NULL;
|
||||
|
||||
jmethodID jniGetMethodID(JNIEnv *env, jclass cls, const char *name, const char *signature);
|
||||
int jniCheckException(JNIEnv *env);
|
||||
void DeleteLocalRef(JNIEnv *env, jobject *jresource);
|
||||
|
||||
/* ******************************************************* */
|
||||
|
||||
void init_log(int lvl, JNIEnv *env, jclass _vpnclass, jclass _vpn_inst) {
|
||||
loglevel = lvl;
|
||||
cur_env = env;
|
||||
vpnclass = _vpnclass;
|
||||
vpn_inst = _vpn_inst;
|
||||
reportError = jniGetMethodID(cur_env, vpnclass, "reportError", "(Ljava/lang/String;)V");
|
||||
}
|
||||
|
||||
/* ******************************************************* */
|
||||
|
||||
void finish_log() {
|
||||
cur_env = NULL;
|
||||
vpnclass = 0;
|
||||
vpn_inst = 0;
|
||||
reportError = 0;
|
||||
}
|
||||
|
||||
/* ******************************************************* */
|
||||
|
||||
@ -37,8 +64,22 @@ void log_android(int prio, const char *fmt, ...) {
|
||||
|
||||
va_start(argptr, fmt);
|
||||
vsnprintf(line, sizeof(line), fmt, argptr);
|
||||
__android_log_print(prio, "VPNProxy", "%s", line);
|
||||
va_end(argptr);
|
||||
|
||||
__android_log_print(prio, "VPNProxy", "%s", line);
|
||||
|
||||
if((prio >= ANDROID_LOG_FATAL) && (cur_env != NULL) && (reportError != NULL)) {
|
||||
// This is a fatal error, report it to the gui
|
||||
jobject info_string = (*cur_env)->NewStringUTF(cur_env, line);
|
||||
|
||||
if((jniCheckException(cur_env) != 0) || (info_string == NULL))
|
||||
return;
|
||||
|
||||
(*cur_env)->CallVoidMethod(cur_env, vpn_inst, reportError, info_string);
|
||||
jniCheckException(cur_env);
|
||||
|
||||
DeleteLocalRef(cur_env, info_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -638,9 +638,11 @@ static int net2tap(zdtun_t *tun, char *pkt_buf, int pkt_size, const zdtun_conn_t
|
||||
if(errno == EIO) {
|
||||
log_android(ANDROID_LOG_INFO, "Got I/O error (terminating?)");
|
||||
running = false;
|
||||
} else
|
||||
log_android(ANDROID_LOG_ERROR,
|
||||
"tap write (%d) failed [%d]: %s", pkt_size, errno, strerror(errno));
|
||||
} else {
|
||||
log_android(ANDROID_LOG_FATAL,
|
||||
"tap write (%d) failed [%d]: %s", pkt_size, errno, strerror(errno));
|
||||
running = false;
|
||||
}
|
||||
} else if(rv != pkt_size)
|
||||
log_android(ANDROID_LOG_WARN,
|
||||
"partial tap write (%d / %d)", rv, pkt_size);
|
||||
@ -830,7 +832,7 @@ static int connect_dumper(vpnproxy_data_t *proxy) {
|
||||
dumper_socket = socket(AF_INET, proxy->pcap_dump.tcp_socket ? SOCK_STREAM : SOCK_DGRAM, 0);
|
||||
|
||||
if (!dumper_socket) {
|
||||
log_android(ANDROID_LOG_ERROR,
|
||||
log_android(ANDROID_LOG_FATAL,
|
||||
"could not open UDP pcap dump socket [%d]: %s", errno,
|
||||
strerror(errno));
|
||||
return(-1);
|
||||
@ -845,7 +847,7 @@ static int connect_dumper(vpnproxy_data_t *proxy) {
|
||||
servaddr.sin_addr.s_addr = proxy->pcap_dump.collector_addr;
|
||||
|
||||
if(connect(dumper_socket, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
|
||||
log_android(ANDROID_LOG_ERROR,
|
||||
log_android(ANDROID_LOG_FATAL,
|
||||
"connection to the PCAP receiver failed [%d]: %s", errno,
|
||||
strerror(errno));
|
||||
return(-2);
|
||||
@ -867,6 +869,8 @@ static int run_tun(JNIEnv *env, jclass vpn, int tapfd, jint sdk) {
|
||||
time_t last_connections_dump = (time(NULL) * 1000) - CONNECTION_DUMP_UPDATE_FREQUENCY_MS + 1000 /* update in a second */;
|
||||
jclass vpn_class = (*env)->GetObjectClass(env, vpn);
|
||||
|
||||
init_log(ANDROID_LOG_DEBUG, env, vpn_class, vpn);
|
||||
|
||||
zdtun_parse_pkt(mitmproxy_pkt_buffer, sizeof(mitmproxy_pkt_buffer)-1, &mitm_pkt);
|
||||
|
||||
/* Classes */
|
||||
@ -972,7 +976,7 @@ static int run_tun(JNIEnv *env, jclass vpn, int tapfd, jint sdk) {
|
||||
proxy.java_dump.buffer_idx = 0;
|
||||
|
||||
if(!proxy.java_dump.buffer) {
|
||||
log_android(ANDROID_LOG_ERROR, "malloc(java_dump.buffer) failed with code %d/%s",
|
||||
log_android(ANDROID_LOG_FATAL, "malloc(java_dump.buffer) failed with code %d/%s",
|
||||
errno, strerror(errno));
|
||||
running = false;
|
||||
}
|
||||
@ -1099,6 +1103,8 @@ housekeeping:
|
||||
}
|
||||
|
||||
notifyServiceStatus(&proxy, "stopped");
|
||||
|
||||
finish_log();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user