diff options
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | Readme.md | 11 | ||||
-rw-r--r-- | app/java/res/drawable/logo.png | bin | 0 -> 8963 bytes | |||
-rw-r--r-- | app/java/src/DNSProxyConnection.java | 12 | ||||
-rw-r--r-- | app/java/src/DNSProxyRunner.java | 28 | ||||
-rw-r--r-- | app/java/src/DNSProxyService.java | 76 | ||||
-rw-r--r-- | app/java/src/MainActivity.java | 13 |
7 files changed, 109 insertions, 41 deletions
@@ -2,12 +2,16 @@ build: app/java/src/*.java bazel build //app/java:dnsproxy dev: - bazel mobile-install //app/java:dnsproxy --start_app #--debug_app --java_debug + #bazel mobile-install //app/java:dnsproxy --start_app #--debug_app --java_debug + $(MAKE) build && $(MAKE) install && adb shell am start -n org.pihole.dnsproxy/org.pihole.dnsproxy.MainActivity install: - bazel mobile-install //app/java:dnsproxy - #adb install bazel-bin/app/java/dnsproxy.apk + #bazel mobile-install //app/java:dnsproxy + adb install bazel-bin/app/java/dnsproxy.apk emulate: # avdmanager create --name dnsproxy -k "system-images;android-28;google_apis_playstore;x86_64" emulator @dnsproxy -no-boot-anim + +adb_logcat: + adb logcat --pid=$(adb shell pidof -s org.pihole.dnsproxy) @@ -1,11 +1,14 @@ +## Resources used + +### VPN / Proxy - https://github.com/IngoZenz/personaldnsfilter/blob/master/app/src/main/java/dnsfilter/android/DNSFilterService.java - https://android.googlesource.com/platform/development/+/master/samples/ToyVpn/src/com/example/android/toyvpn/ToyVpnService.java +- https://github.com/Jigsaw-Code/outline-client/blob/master/src/cordova/android/OutlineAndroidLib/outline/src/main/java/org/outline/vpn/VpnTunnel.java +- https://github.com/schwabe/ics-openvpn + +### Service - https://developer.android.com/guide/components/services#StartingAService - https://developer.android.com/guide/components/services#Foreground - https://stackoverflow.com/questions/600207/how-to-check-if-a-service-is-running-on-android - https://www.vogella.com/tutorials/AndroidServices/article.html#communication-with-services - https://github.com/googlecodelabs/bazel-android-intro/blob/master/sample/mediarecorder/java/com/example/android/mediarecorder/MainActivity.java -- https://github.com/schwabe/ics-openvpn - ->:( -- https://github.com/bazelbuild/bazel/pull/12626 diff --git a/app/java/res/drawable/logo.png b/app/java/res/drawable/logo.png Binary files differnew file mode 100644 index 0000000..154b579 --- /dev/null +++ b/app/java/res/drawable/logo.png diff --git a/app/java/src/DNSProxyConnection.java b/app/java/src/DNSProxyConnection.java index f96af80..0573515 100644 --- a/app/java/src/DNSProxyConnection.java +++ b/app/java/src/DNSProxyConnection.java @@ -4,8 +4,6 @@ import android.os.ParcelFileDescriptor; import android.util.Log; -import java.io.IOException; - public class DNSProxyConnection { public static String THREAD_NAME = "org.pihole.dnsproxy.service.thread"; @@ -20,8 +18,8 @@ public class DNSProxyConnection { public void start() { DNSProxyRunner runner = new DNSProxyRunner(this.service); - runner.setOnEstablishListener(parcelFileDescriptor -> { - this.networkInterface = parcelFileDescriptor; + runner.setOnEstablishListener(tunInterface -> { + this.networkInterface = tunInterface; }); this.thread = new Thread(runner, DNSProxyConnection.THREAD_NAME); @@ -30,10 +28,10 @@ public class DNSProxyConnection { public void stop() { try { - this.thread.stop(); + this.thread.interrupt(); this.networkInterface.close(); - } catch (IOException exception) { - Log.e(DNSProxyService.LOG_TAG, "Connection failed", exception); + } catch (Exception exception) { + Log.e(DNSProxyService.LOG_TAG, "Closing VPN interface", exception); } } } diff --git a/app/java/src/DNSProxyRunner.java b/app/java/src/DNSProxyRunner.java index 0c136e8..6a45413 100644 --- a/app/java/src/DNSProxyRunner.java +++ b/app/java/src/DNSProxyRunner.java @@ -1,5 +1,7 @@ package org.pihole.dnsproxy; +import android.net.VpnService; + import android.os.ParcelFileDescriptor; import android.util.Log; @@ -14,6 +16,7 @@ import java.net.SocketAddress; import java.nio.channels.DatagramChannel; public class DNSProxyRunner implements Runnable { + public interface OnEstablishListener { void onEstablish(ParcelFileDescriptor networkInterface); } @@ -28,22 +31,15 @@ public class DNSProxyRunner implements Runnable { @Override public void run() { try { - DatagramChannel tunnel = DatagramChannel.open(); - - if(!this.service.protect(tunnel.socket())) { - throw new IllegalStateException("Cannot protect tunnel"); - } - - // SocketAddress server = new InetSocketAddress("servername", "serverport"); - // - // tunnel.connect(server); - // tunnel.configureBlocking(false); - // - // ParcelFileDescriptor networkInterface = this.handshake(tunnel); - // FileInputStream in = new FileInputStream(networkInterface.getFileDescriptor()); - // FileOutputStream out = new FileOutputStream(networkInterface.getFileDescriptor()); - } catch (IOException exception) { - Log.e(DNSProxyService.LOG_TAG, "Cannot use socket", exception); + VpnService.Builder builder = this.service.newBuilder() + .setSession("Pihole DNS Proxy") + .addAddress("10.111.222.1", 24) + .addDnsServer(DNSProxyService.PIHOLE_ADDRESS) + .setBlocking(true); + + this.onEstablishListener.onEstablish(builder.establish()); + } catch (Exception exception) { + Log.e(DNSProxyService.LOG_TAG, "Failed to establish VPN connection", exception); } } diff --git a/app/java/src/DNSProxyService.java b/app/java/src/DNSProxyService.java index 117e6fc..8911036 100644 --- a/app/java/src/DNSProxyService.java +++ b/app/java/src/DNSProxyService.java @@ -1,23 +1,45 @@ package org.pihole.dnsproxy; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; import android.app.Service; +import android.content.Context; import android.content.Intent; +import android.net.DhcpInfo; import android.net.VpnService; +import android.net.wifi.WifiManager; + +import android.util.Log; + +import java.net.InetAddress; public class DNSProxyService extends VpnService { public static String LOG_TAG = "org.pihole.dnsproxy.log"; public static String NOTIFICATION = "org.pihole.dnsproxy.service"; + public static String NOTIFICATION_CHANNEL_ID = "PiholeDNSProxy"; + public static String ACTION_START = "org.pihole.dnsproxy.service.START"; + public static String ACTION_STOP = "org.pihole.dnsproxy.service.STOP"; + + public static String PIHOLE_ADDRESS = ""; private static DNSProxyConnection connection; @Override public int onStartCommand(Intent intent, int flags, int startId) { - this.start(); + if (intent.getAction().equals(DNSProxyService.ACTION_START)) { + this.start(); - return Service.START_STICKY; + return Service.START_STICKY; + } else { + this.stop(); + + return Service.START_NOT_STICKY; + } } @Override @@ -27,14 +49,22 @@ public class DNSProxyService extends VpnService { super.onDestroy(); } + public VpnService.Builder newBuilder() { + return new VpnService.Builder(); + } + public static boolean isRunning() { return DNSProxyService.connection != null; } public void start() { + this.setPiholeAddress(); + DNSProxyService.connection = new DNSProxyConnection(this); - // DNSProxyService.connection.start(); + DNSProxyService.connection.start(); + + this.startForeground(); // send notification when started Intent notification = new Intent(DNSProxyService.NOTIFICATION); @@ -42,11 +72,49 @@ public class DNSProxyService extends VpnService { } public void stop() { - // DNSProxyService.connection.stop(); + DNSProxyService.connection.stop(); DNSProxyService.connection = null; + stopForeground(true); + // send notification when stopped Intent notification = new Intent(DNSProxyService.NOTIFICATION); sendBroadcast(notification); } + + private void setPiholeAddress() { + WifiManager manager = (WifiManager) getSystemService(WIFI_SERVICE); + DhcpInfo info = manager.getDhcpInfo(); + + byte[] addressBytes = { + (byte) (0xff & info.dns1), + (byte) (0xff & (info.dns1 >> 8)), + (byte) (0xff & (info.dns1 >> 16)), + (byte) (0xff & (info.dns1 >> 24)), + }; + + try { + DNSProxyService.PIHOLE_ADDRESS = InetAddress.getByAddress(addressBytes).toString().replaceAll("/", ""); + } catch (Exception e) { + DNSProxyService.PIHOLE_ADDRESS = ""; + } + } + + private void startForeground() { + NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + + NotificationChannel channel = new NotificationChannel( + DNSProxyService.NOTIFICATION_CHANNEL_ID, DNSProxyService.NOTIFICATION_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT + ); + manager.createNotificationChannel(channel); + + Notification notification = new Notification.Builder(this, DNSProxyService.NOTIFICATION_CHANNEL_ID) + .setSmallIcon(R.drawable.logo) + .setContentTitle("Pihole DNS Proxy") + .setContentText("Running with " + DNSProxyService.PIHOLE_ADDRESS) + // .setContentIntent(PendingIntent.getActivity(this, 0, new Intent(MainActivity.class), PendingIntent.FLAG_IMMUTABLE)) + .build(); + + startForeground(1, notification); + } } diff --git a/app/java/src/MainActivity.java b/app/java/src/MainActivity.java index f437c9d..049ee29 100644 --- a/app/java/src/MainActivity.java +++ b/app/java/src/MainActivity.java @@ -12,6 +12,8 @@ import android.net.VpnService; import android.os.Bundle; +import android.util.Log; + import android.view.TextureView; import android.view.View; @@ -30,10 +32,7 @@ public class MainActivity extends Activity { */ @Override public void onReceive(Context context, Intent intent) { - Bundle bundle = intent.getExtras(); - // if (bundle != null) { - setStateButtonStart(); - // } + setStateButtonStart(); } }; @@ -80,7 +79,7 @@ public class MainActivity extends Activity { */ public void onClickButtonStart(View view) { if (!DNSProxyService.isRunning()) { //start - Intent intent = DNSProxyService.prepare(this); + Intent intent = VpnService.prepare(this); if (intent != null) { startActivityForResult(intent, 0); @@ -108,7 +107,7 @@ public class MainActivity extends Activity { * Start DNSProxyService */ public void start() { - startService(this.dnsProxyService); + startService(this.dnsProxyService.setAction(DNSProxyService.ACTION_START)); Toast .makeText( @@ -123,7 +122,7 @@ public class MainActivity extends Activity { * Stop DNSProxyService */ public void stop() { - stopService(this.dnsProxyService); + startService(this.dnsProxyService.setAction(DNSProxyService.ACTION_STOP)); Toast .makeText( |