NetGuard/app/src/main/java/eu/faircode/netguard/BlackHoleService.java

144 lines
4.9 KiB
Java
Raw Normal View History

2015-10-24 18:01:55 +00:00
package eu.faircode.netguard;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.VpnService;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
2015-10-24 19:50:29 +00:00
import android.preference.PreferenceManager;
2015-10-24 18:01:55 +00:00
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";
private Thread thread;
public static final String EXTRA_START = "Start";
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
2015-10-24 19:50:29 +00:00
Log.i(TAG, "Start intent=" + intent);
2015-10-24 18:01:55 +00:00
if (thread != null)
thread.interrupt();
2015-10-24 19:50:29 +00:00
boolean enabled = (intent != null &&
intent.hasExtra(EXTRA_START) &&
intent.getBooleanExtra(EXTRA_START, false));
2015-10-24 18:01:55 +00:00
if (enabled) {
Log.i(TAG, "Starting");
thread = new Thread(this, "BlackHoleThread");
thread.start();
}
// TODO: check if start sticky is enough to keep the VPN service alive
return START_STICKY;
}
private BroadcastReceiver connectivityChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
2015-10-24 19:50:29 +00:00
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean("enabled", false))
if (intent.hasExtra(ConnectivityManager.EXTRA_NETWORK_TYPE) &&
intent.getIntExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, ConnectivityManager.TYPE_DUMMY) == ConnectivityManager.TYPE_WIFI) {
Intent service = new Intent(BlackHoleService.this, BlackHoleService.class);
service.putExtra(BlackHoleService.EXTRA_START, true);
Log.i(TAG, "Start service=" + service);
startService(service);
}
2015-10-24 18:01:55 +00:00
}
};
@Override
public void onCreate() {
super.onCreate();
2015-10-24 19:50:29 +00:00
Log.i(TAG, "Create");
2015-10-24 18:01:55 +00:00
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(connectivityChangedReceiver, intentFilter);
}
@Override
public void onDestroy() {
Log.i(TAG, "Destroy");
if (thread != null)
thread.interrupt();
unregisterReceiver(connectivityChangedReceiver);
super.onDestroy();
}
@Override
public void onRevoke() {
Log.i(TAG, "Revoke");
if (thread != null)
thread.interrupt();
super.onRevoke();
}
@Override
public void run() {
Log.i(TAG, "Run");
ParcelFileDescriptor pfd = null;
try {
2015-10-24 19:50:29 +00:00
// Check if Wi-Fi connection
2015-10-24 18:01:55 +00:00
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);
2015-10-24 19:50:29 +00:00
// Build VPN service
2015-10-24 18:01:55 +00:00
final Builder builder = new Builder();
builder.setSession("BlackHoleService");
builder.addAddress("10.1.10.1", 32);
builder.addRoute("0.0.0.0", 0);
builder.setBlocking(true);
// 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);
2015-10-24 19:50:29 +00:00
// Start VPN service
2015-10-24 18:01:55 +00:00
pfd = builder.establish();
2015-10-24 19:50:29 +00:00
// Drop all packets
2015-10-24 18:01:55 +00:00
Log.i(TAG, "Loop start");
2015-10-24 19:50:29 +00:00
FileInputStream in = new FileInputStream(pfd.getFileDescriptor());
2015-10-24 18:01:55 +00:00
while (!thread.isInterrupted())
in.skip(32768);
Log.i(TAG, "Loop exit");
} 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));
}
thread = null;
stopSelf();
}
}
}