summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl7
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java2
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java107
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java43
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/StatusListener.java31
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java4
6 files changed, 128 insertions, 66 deletions
diff --git a/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl b/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl
index b73284bb..cbcb0181 100644
--- a/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl
+++ b/main/src/main/aidl/de/blinkt/openvpn/core/IServiceStatus.aidl
@@ -3,13 +3,14 @@ package de.blinkt.openvpn.core;
// Declare any non-default types here with import statements
import de.blinkt.openvpn.core.IStatusCallbacks;
-
+import android.os.ParcelFileDescriptor;
interface IServiceStatus {
/**
- * Registers to receive OpenVPN Status Updates
+ * Registers to receive OpenVPN Status Updates and gets a
+ * ParcelFileDescript back that contains the log up to that point
*/
- void registerStatusCallback(in IStatusCallbacks cb);
+ ParcelFileDescriptor registerStatusCallback(in IStatusCallbacks cb);
/**
* Remove a previously registered callback interface.
diff --git a/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
index 7d10063f..4220b2be 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java
@@ -24,8 +24,6 @@ public class ICSOpenVPNApplication extends Application {
super.onCreate();
PRNGFixes.apply();
- VpnStatus.initLogCache(getApplicationContext().getCacheDir());
-
mStatus = new StatusListener();
mStatus.init(getApplicationContext());
}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java b/main/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java
index 6add8ae0..aec6b3c6 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/LogFileHandler.java
@@ -136,7 +136,7 @@ class LogFileHandler extends Handler {
readCacheContents(new FileInputStream(logfile));
- } catch (java.io.IOException | java.lang.RuntimeException e ) {
+ } catch (java.io.IOException | java.lang.RuntimeException e) {
VpnStatus.logError("Reading cached logfile failed");
VpnStatus.logException(e);
e.printStackTrace();
@@ -146,69 +146,70 @@ class LogFileHandler extends Handler {
protected void readCacheContents(InputStream in) throws IOException {
+ try {
+ BufferedInputStream logFile = new BufferedInputStream(in);
+
+ byte[] buf = new byte[16384];
+ int read = logFile.read(buf, 0, 5);
+ int itemsRead = 0;
- BufferedInputStream logFile = new BufferedInputStream(in);
+ readloop:
+ while (read >= 5) {
+ int skipped = 0;
+ while (buf[skipped] != MAGIC_BYTE) {
+ skipped++;
+ if (!(logFile.read(buf, skipped + 4, 1) == 1) || skipped + 10 > buf.length) {
+ VpnStatus.logDebug(String.format(Locale.US, "Skipped %d bytes and no a magic byte found", skipped));
+ break readloop;
+ }
+ }
+ if (skipped > 0)
+ VpnStatus.logDebug(String.format(Locale.US, "Skipped %d bytes before finding a magic byte", skipped));
- byte[] buf = new byte[16384];
- int read = logFile.read(buf, 0, 5);
- int itemsRead = 0;
+ int len = ByteBuffer.wrap(buf, skipped + 1, 4).asIntBuffer().get();
+ // Marshalled LogItem
+ int pos = 0;
+ byte buf2[] = new byte[buf.length];
- readloop:
- while (read >= 5) {
- int skipped = 0;
- while (buf[skipped] != MAGIC_BYTE) {
- skipped++;
- if (!(logFile.read(buf, skipped + 4, 1) == 1) || skipped + 10 > buf.length) {
- VpnStatus.logDebug(String.format(Locale.US, "Skipped %d bytes and no a magic byte found", skipped));
- break readloop;
- }
- }
- if (skipped > 0)
- VpnStatus.logDebug(String.format(Locale.US, "Skipped %d bytes before finding a magic byte", skipped));
-
- int len = ByteBuffer.wrap(buf, skipped+1, 4).asIntBuffer().get();
-
- // Marshalled LogItem
- int pos = 0;
- byte buf2[] = new byte[buf.length];
-
- while (pos < len) {
- byte b = (byte) logFile.read();
- if (b == MAGIC_BYTE) {
- VpnStatus.logDebug(String.format(Locale.US, "Unexpected magic byte found at pos %d, abort current log item", pos));
- read = logFile.read(buf, 1, 4) + 1;
- continue readloop;
- } else if (b == MAGIC_BYTE + 1) {
- b = (byte) logFile.read();
- if (b == 0)
- b = MAGIC_BYTE;
- else if (b == 1)
- b = MAGIC_BYTE + 1;
- else {
- VpnStatus.logDebug(String.format(Locale.US, "Escaped byte not 0 or 1: %d", b));
+ while (pos < len) {
+ byte b = (byte) logFile.read();
+ if (b == MAGIC_BYTE) {
+ VpnStatus.logDebug(String.format(Locale.US, "Unexpected magic byte found at pos %d, abort current log item", pos));
read = logFile.read(buf, 1, 4) + 1;
continue readloop;
+ } else if (b == MAGIC_BYTE + 1) {
+ b = (byte) logFile.read();
+ if (b == 0)
+ b = MAGIC_BYTE;
+ else if (b == 1)
+ b = MAGIC_BYTE + 1;
+ else {
+ VpnStatus.logDebug(String.format(Locale.US, "Escaped byte not 0 or 1: %d", b));
+ read = logFile.read(buf, 1, 4) + 1;
+ continue readloop;
+ }
}
+ buf2[pos++] = b;
}
- buf2[pos++] = b;
- }
- restoreLogItem(buf2, len);
+ restoreLogItem(buf2, len);
- //Next item
- read = logFile.read(buf, 0, 5);
- itemsRead++;
- if (itemsRead > 2 * VpnStatus.MAXLOGENTRIES) {
- VpnStatus.logError("Too many logentries read from cache, aborting.");
- read = 0;
- }
+ //Next item
+ read = logFile.read(buf, 0, 5);
+ itemsRead++;
+ if (itemsRead > 2 * VpnStatus.MAXLOGENTRIES) {
+ VpnStatus.logError("Too many logentries read from cache, aborting.");
+ read = 0;
+ }
+ }
+ VpnStatus.logDebug(R.string.reread_log, itemsRead);
+ } finally {
+ VpnStatus.readFileLog = true;
+ VpnStatus.readFileLock.notifyAll();
}
- VpnStatus.logDebug(R.string.reread_log, itemsRead);
-
-
}
protected void restoreLogItem(byte[] buf, int len) throws UnsupportedEncodingException {
@@ -219,11 +220,11 @@ class LogFileHandler extends Handler {
} else {
VpnStatus.logError(String.format(Locale.getDefault(),
"Could not read log item from file: %d: %s",
- len, bytesToHex(buf, Math.max(len, 80))));
+ len, bytesToHex(buf, Math.max(len, 80))));
}
}
- final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
+ private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes, int len) {
len = Math.min(bytes.length, len);
diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java
index 24ae7704..afac749c 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNStatusService.java
@@ -10,11 +10,15 @@ import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Pair;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
import java.lang.ref.WeakReference;
import de.blinkt.openvpn.api.ExternalOpenVPNService;
@@ -59,8 +63,45 @@ public class OpenVPNStatusService extends Service implements VpnStatus.LogListen
private static final IServiceStatus.Stub mBinder = new IServiceStatus.Stub() {
@Override
- public void registerStatusCallback(IStatusCallbacks cb) throws RemoteException {
+ public ParcelFileDescriptor registerStatusCallback(IStatusCallbacks cb) throws RemoteException {
+ final LogItem[] logbuffer = VpnStatus.getlogbuffer();
mCallbacks.register(cb);
+ try {
+ final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+ new Thread("pushLogs") {
+ @Override
+ public void run() {
+ DataOutputStream fd = new DataOutputStream(new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]));
+ try {
+ synchronized (VpnStatus.readFileLock) {
+ if (!VpnStatus.readFileLog) {
+ VpnStatus.readFileLock.wait();
+ }
+ }
+ } catch (InterruptedException e) {
+ VpnStatus.logException(e);
+ }
+ try {
+
+ for (LogItem logItem : logbuffer) {
+ byte[] bytes = logItem.getMarschaledBytes();
+ fd.writeShort(bytes.length);
+ fd.write(bytes);
+ }
+ // Mark end
+ fd.writeShort(0x7fff);
+ fd.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+ }.start();
+ return pipe[0];
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RemoteException(e.getMessage());
+ }
}
@Override
diff --git a/main/src/main/java/de/blinkt/openvpn/core/StatusListener.java b/main/src/main/java/de/blinkt/openvpn/core/StatusListener.java
index 8df1dfed..19a2668d 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/StatusListener.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/StatusListener.java
@@ -10,13 +10,19 @@ import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+
/**
* Created by arne on 09.11.16.
*/
-public class StatusListener {
+public class StatusListener {
+ private File mCacheDir;
private ServiceConnection mConnection = new ServiceConnection() {
@@ -29,12 +35,25 @@ public class StatusListener {
/* Check if this a local service ... */
if (service.queryLocalInterface("de.blinkt.openvpn.core.IServiceStatus") == null) {
VpnStatus.setConnectedVPNProfile(serviceStatus.getLastConnectedVPN());
- serviceStatus.registerStatusCallback(mCallback);
-
+ ParcelFileDescriptor pfd = serviceStatus.registerStatusCallback(mCallback);
+ DataInputStream fd = new DataInputStream(new ParcelFileDescriptor.AutoCloseInputStream(pfd));
+
+ short len = fd.readShort();
+ byte[] buf = new byte[4095];
+ while (len != 0x7fff) {
+ fd.readFully(buf, 0, len);
+ LogItem logitem = new LogItem(buf, len);
+ VpnStatus.newLogItem(logitem, false);
+ len = fd.readShort();
+ }
+ fd.close();
+ } else {
+ VpnStatus.initLogCache(mCacheDir);
}
- } catch (RemoteException e) {
+ } catch (RemoteException | IOException e) {
e.printStackTrace();
+ VpnStatus.logException(e);
}
}
@@ -45,11 +64,11 @@ public class StatusListener {
};
- void init(Context c)
- {
+ void init(Context c) {
Intent intent = new Intent(c, OpenVPNStatusService.class);
intent.setAction(OpenVPNService.START_SERVICE);
+ mCacheDir = c.getCacheDir();
c.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
diff --git a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
index 84cb4719..cd0e3e4f 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java
@@ -23,7 +23,7 @@ import de.blinkt.openvpn.VpnProfile;
public class VpnStatus {
- public static LinkedList<LogItem> logbuffer;
+ private static final LinkedList<LogItem> logbuffer;
private static Vector<LogListener> logListener;
private static Vector<StateListener> stateListener;
@@ -39,6 +39,8 @@ public class VpnStatus {
private static HandlerThread mHandlerThread;
private static String mLastConnectedVPNUUID;
+ static boolean readFileLog =false;
+ final static java.lang.Object readFileLock = new Object();
public static void logException(LogLevel ll, String context, Exception e) {
StringWriter sw = new StringWriter();