From f9b1f1f3092e7de4db092c5a5602eadc0b9fd163 Mon Sep 17 00:00:00 2001 From: M66B Date: Sun, 25 Oct 2015 16:16:20 +0100 Subject: [PATCH] Simplify black hole service Solves threading issues, but needs testing --- README.md | 2 + app/src/main/AndroidManifest.xml | 2 +- .../faircode/netguard/BlackHoleService.java | 133 ++++++++---------- .../{BootReceiver.java => Receiver.java} | 4 +- 4 files changed, 61 insertions(+), 80 deletions(-) rename app/src/main/java/eu/faircode/netguard/{BootReceiver.java => Receiver.java} (84%) diff --git a/README.md b/README.md index 9d3cbf64..4cf0a06f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,9 @@ Features * No root required * Simple to use * Free and open source +* No extra battery usage * No calling home +* No tracking (analytics) * No ads Usage diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 60031ae7..e78803ce 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -30,7 +30,7 @@ - + diff --git a/app/src/main/java/eu/faircode/netguard/BlackHoleService.java b/app/src/main/java/eu/faircode/netguard/BlackHoleService.java index 5820d39b..a85b1faa 100644 --- a/app/src/main/java/eu/faircode/netguard/BlackHoleService.java +++ b/app/src/main/java/eu/faircode/netguard/BlackHoleService.java @@ -6,6 +6,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.VpnService; @@ -13,13 +14,12 @@ import android.os.ParcelFileDescriptor; import android.preference.PreferenceManager; import android.util.Log; -import java.io.FileInputStream; import java.io.IOException; -public class BlackHoleService extends VpnService implements Runnable { - private static final String TAG = "NetGuard.BlackHole"; +public class BlackHoleService extends VpnService { + private static final String TAG = "NetGuard.Service"; - private Thread thread = null; + private ParcelFileDescriptor vpn = null; public static final String EXTRA_COMMAND = "Command"; public enum Command {start, reload, stop} @@ -30,29 +30,68 @@ public class BlackHoleService extends VpnService implements Runnable { boolean enabled = prefs.getBoolean("enabled", false); Command cmd = (intent == null ? Command.start : (Command) intent.getSerializableExtra(EXTRA_COMMAND)); - Log.i(TAG, "Start intent=" + intent + " command=" + cmd + " enabled=" + enabled + " running=" + (thread != null)); + Log.i(TAG, "Start intent=" + intent + " command=" + cmd + " enabled=" + enabled + " vpn=" + (vpn != null)); if (cmd == Command.reload || cmd == Command.stop) { - if (thread != null) { - Log.i(TAG, "Stopping thread=" + thread); - thread.interrupt(); - } + if (vpn != null) + vpnStop(); if (cmd == Command.stop) stopSelf(); } if (cmd == Command.start || cmd == Command.reload) { - if (enabled && (thread == null || thread.isInterrupted())) { + if (enabled && vpn == null) { Log.i(TAG, "Starting"); - thread = new Thread(this, "BlackHoleThread"); - thread.start(); - Log.i(TAG, "Started thread=" + thread); + vpnStart(); } } return START_STICKY; } + private void vpnStart() { + Log.i(TAG, "Starting"); + + // Check if Wi-Fi connection + ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo ni = cm.getActiveNetworkInfo(); + boolean wifi = (ni != null && ni.getType() == ConnectivityManager.TYPE_WIFI); + Log.i(TAG, "wifi=" + wifi); + + // Build VPN service + final Builder builder = new Builder(); + builder.setSession("BlackHoleService"); + builder.addAddress("10.1.10.1", 32); + builder.addRoute("0.0.0.0", 0); + builder.setBlocking(false); + + // Add list of allowed applications + for (Rule rule : Rule.getRules(this)) + if (!(wifi ? rule.wifi_blocked : rule.other_blocked)) { + Log.i(TAG, "Allowing " + rule.info.packageName); + try { + builder.addDisallowedApplication(rule.info.packageName); + } catch (PackageManager.NameNotFoundException ignored) { + } + } + + Intent configure = new Intent(this, ActivityMain.class); + PendingIntent pi = PendingIntent.getActivity(this, 0, configure, PendingIntent.FLAG_UPDATE_CURRENT); + builder.setConfigureIntent(pi); + + // Start VPN service + vpn = builder.establish(); + } + + private void vpnStop() { + Log.i(TAG, "Stopping"); + try { + vpn.close(); + vpn = null; + } catch (IOException ignored) { + } + } + private BroadcastReceiver connectivityChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -79,10 +118,8 @@ public class BlackHoleService extends VpnService implements Runnable { @Override public void onDestroy() { Log.i(TAG, "Destroy"); - if (thread != null) { - Log.i(TAG, "Interrupt thread=" + thread); - thread.interrupt(); - } + if (vpn != null) + vpnStop(); unregisterReceiver(connectivityChangedReceiver); super.onDestroy(); } @@ -90,68 +127,10 @@ public class BlackHoleService extends VpnService implements Runnable { @Override public void onRevoke() { Log.i(TAG, "Revoke"); - if (thread != null) { - Log.i(TAG, "Interrupt thread=" + thread); - thread.interrupt(); - } + if (vpn != null) + vpnStop(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); prefs.edit().putBoolean("enabled", false).apply(); super.onRevoke(); } - - @Override - public synchronized void run() { - Log.i(TAG, "Run thread=" + Thread.currentThread()); - ParcelFileDescriptor pfd = null; - try { - // Check if Wi-Fi connection - ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo ni = cm.getActiveNetworkInfo(); - boolean wifi = (ni != null && ni.getType() == ConnectivityManager.TYPE_WIFI); - Log.i(TAG, "wifi=" + wifi); - - // Build VPN service - final Builder builder = new Builder(); - builder.setSession("BlackHoleService"); - builder.addAddress("10.1.10.1", 32); - builder.addRoute("0.0.0.0", 0); - builder.setBlocking(false); - - // Add list of allowed applications - for (Rule rule : Rule.getRules(this)) - if (!(wifi ? rule.wifi_blocked : rule.other_blocked)) { - Log.i(TAG, "Allowing " + rule.info.packageName); - builder.addDisallowedApplication(rule.info.packageName); - } - - Intent intent = new Intent(this, ActivityMain.class); - PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - builder.setConfigureIntent(pi); - - // Start VPN service - pfd = builder.establish(); - - // Drop all packets - Log.i(TAG, "Loop start thread=" + Thread.currentThread()); - FileInputStream in = new FileInputStream(pfd.getFileDescriptor()); - while (!Thread.currentThread().isInterrupted() && pfd.getFileDescriptor().valid()) - if (in.skip(32768) < 0) - try { - Thread.sleep(1000); - } catch (InterruptedException ignored) { - } - Log.i(TAG, "Loop exit thread=" + Thread.currentThread()); - - } catch (Throwable ex) { - Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); - - } finally { - if (pfd != null) - try { - pfd.close(); - } catch (IOException ex) { - Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex)); - } - } - } } diff --git a/app/src/main/java/eu/faircode/netguard/BootReceiver.java b/app/src/main/java/eu/faircode/netguard/Receiver.java similarity index 84% rename from app/src/main/java/eu/faircode/netguard/BootReceiver.java rename to app/src/main/java/eu/faircode/netguard/Receiver.java index 716a34bb..53f248b8 100644 --- a/app/src/main/java/eu/faircode/netguard/BootReceiver.java +++ b/app/src/main/java/eu/faircode/netguard/Receiver.java @@ -6,8 +6,8 @@ import android.content.Intent; import android.net.VpnService; import android.util.Log; -public class BootReceiver extends BroadcastReceiver { - private static final String TAG = "NetGuard.Boot"; +public class Receiver extends BroadcastReceiver { + private static final String TAG = "NetGuard.Receiver"; @Override public void onReceive(final Context context, Intent intent) {