[tor-commits] [orbot/master] fix VPN code to support dynamic DNS port for Tor

n8fr8 at torproject.org n8fr8 at torproject.org
Tue Apr 28 21:05:00 UTC 2020


commit 9ff0b00cb26b0f4c09e9420ad4d992fa7de26c82
Author: n8fr8 <nathan at guardianproject.info>
Date:   Tue Jul 9 14:28:11 2019 -0400

    fix VPN code to support dynamic DNS port for Tor
---
 .../org/torproject/android/service/TorService.java |  55 +++----
 .../android/service/TorServiceConstants.java       |   3 +
 .../android/service/vpn/OrbotVpnManager.java       | 180 +++++++++++----------
 .../android/service/vpn/TorVpnService.java         |  42 +++++
 .../torproject/android/service/vpn/VpnUtils.java   |  26 ++-
 orbotservice/src/main/res/values/pdnsd.xml         |   4 +-
 6 files changed, 180 insertions(+), 130 deletions(-)

diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorService.java b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
index be1e18e2..c83c252e 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorService.java
@@ -811,11 +811,8 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
         	reply.setPackage(packageName);
         	sendBroadcast(reply);
         }
-        else
-        {
-            LocalBroadcastManager.getInstance(this).sendBroadcast(reply);
 
-        }
+        LocalBroadcastManager.getInstance(this).sendBroadcast(reply);
 
     }
 
@@ -1105,21 +1102,22 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
 
                         String confDns = conn.getInfo("net/listeners/dns");
                         st = new StringTokenizer(confDns," ");
-
-                        confDns = st.nextToken().split(":")[1];
-                        confDns = confDns.substring(0,confDns.length()-1);
-                        mPortDns = Integer.parseInt(confDns);
-                        getSharedPrefs(getApplicationContext()).edit().putInt(VpnPrefs.PREFS_DNS_PORT, mPortDns).apply();
-
+                        if (st.hasMoreTokens()) {
+                            confDns = st.nextToken().split(":")[1];
+                            confDns = confDns.substring(0, confDns.length() - 1);
+                            mPortDns = Integer.parseInt(confDns);
+                            getSharedPrefs(getApplicationContext()).edit().putInt(VpnPrefs.PREFS_DNS_PORT, mPortDns).apply();
+                        }
 
                         String confTrans = conn.getInfo("net/listeners/trans");
                         st = new StringTokenizer(confTrans," ");
+                        if (st.hasMoreTokens()) {
+                            confTrans = st.nextToken().split(":")[1];
+                            confTrans = confTrans.substring(0, confTrans.length() - 1);
+                            mPortTrans = Integer.parseInt(confTrans);
+                        }
 
-                        confTrans = st.nextToken().split(":")[1];
-                        confTrans = confDns.substring(0,confTrans.length()-1);
-                        mPortTrans = Integer.parseInt(confTrans);
-
-                        sendCallbackPorts(mPortSOCKS, mPortHTTP);
+                        sendCallbackPorts(mPortSOCKS, mPortHTTP, mPortDns, mPortTrans);
 
                         return Integer.parseInt(torProcId);
                         
@@ -1434,13 +1432,15 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
 
     }
 
-    private void sendCallbackPorts (int socksPort, int httpPort)
+    private void sendCallbackPorts (int socksPort, int httpPort, int dnsPort, int transPort)
     {
 
         Intent intent = new Intent(LOCAL_ACTION_PORTS);
         // You can also include some extra data.
-        intent.putExtra("socks",socksPort);
-        intent.putExtra("http",httpPort);
+        intent.putExtra(EXTRA_SOCKS_PROXY_PORT,socksPort);
+        intent.putExtra(EXTRA_HTTP_PROXY_PORT,httpPort);
+        intent.putExtra(EXTRA_DNS_PORT,dnsPort);
+        intent.putExtra(EXTRA_TRANS_PORT,transPort);
 
         LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
 
@@ -1970,21 +1970,10 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
 
     private void startVPNService ()
     {
-        if (mPortSOCKS != -1) {
-            Intent intentVpn = new Intent(this, TorVpnService.class);
-            intentVpn.setAction("start");
-            intentVpn.putExtra("torSocks", mPortSOCKS);
-            startService(intentVpn);
-        }
-        else
-        {
-            mHandler.postDelayed(new Runnable() {
-                public void run ()
-                {
-                    startVPNService();
-                }
-            },5000);
-        }
+        Intent intentVpn = new Intent(this, TorVpnService.class);
+        intentVpn.setAction("start");
+        startService(intentVpn);
+
     }
 
 
diff --git a/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java b/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java
index 8fd9eeca..b805cd6a 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/TorServiceConstants.java
@@ -65,6 +65,9 @@ public interface TorServiceConstants {
     String EXTRA_HTTP_PROXY_HOST = "org.torproject.android.intent.extra.HTTP_PROXY_HOST";
     String EXTRA_HTTP_PROXY_PORT = "org.torproject.android.intent.extra.HTTP_PROXY_PORT";
 
+    String EXTRA_DNS_PORT = "org.torproject.android.intent.extra.DNS_PORT";
+    String EXTRA_TRANS_PORT = "org.torproject.android.intent.extra.TRANS_PORT";
+
     String LOCAL_ACTION_LOG = "log";
     String LOCAL_ACTION_BANDWIDTH = "bandwidth";
     String LOCAL_EXTRA_LOG = "log";
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
index 7233159f..cf9b8b71 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/OrbotVpnManager.java
@@ -19,8 +19,10 @@ package org.torproject.android.service.vpn;
 import android.annotation.TargetApi;
 import android.app.PendingIntent;
 import android.app.Service;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.VpnService;
@@ -29,6 +31,7 @@ import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
+import android.support.v4.content.LocalBroadcastManager;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -36,12 +39,15 @@ import com.runjva.sourceforge.jsocks.protocol.ProxyServer;
 import com.runjva.sourceforge.jsocks.server.ServerAuthenticatorNone;
 
 import org.torproject.android.service.R;
+import org.torproject.android.service.TorService;
+import org.torproject.android.service.TorServiceConstants;
 import org.torproject.android.service.util.CustomNativeLoader;
 
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintStream;
@@ -63,30 +69,25 @@ public class OrbotVpnManager implements Handler.Callback {
     private ParcelFileDescriptor mInterface;
 
     private int mTorSocks = -1;
+	private int mTorDns = -1;
 
-    public static int sSocksProxyServerPort = -1;
+	public static int sSocksProxyServerPort = -1;
     public static String sSocksProxyLocalhost = null;
     private ProxyServer mSocksProxyServer;
 
     private final static int VPN_MTU = 1500;
     
     private final static boolean mIsLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
-    
-    //this is the actual DNS server we talk to over UDP or TCP (now using Tor's DNS port)
-    //private final static String DEFAULT_ACTUAL_DNS_HOST = "127.0.0.1";
-    //private final static int DEFAULT_ACTUAL_DNS_PORT = TorServiceConstants.TOR_DNS_PORT_DEFAULT;
-
 
-
-	File filePdnsd = null;
+	private File filePdnsd = null;
 
 	private final static String PDNSD_BIN = "pdnsd";
-	private final static int PDNSD_PORT = 8091;
 
 	private boolean isRestart = false;
     
     private VpnService mService;
     
+	private Builder mLastBuilder;
 
     public OrbotVpnManager (VpnService service) throws IOException, TimeoutException {
     	mService = service;
@@ -96,6 +97,7 @@ public class OrbotVpnManager implements Handler.Callback {
 
 		Tun2Socks.init();
 
+
 	}
    
     //public int onStartCommand(Intent intent, int flags, int startId) {
@@ -107,40 +109,45 @@ public class OrbotVpnManager implements Handler.Callback {
 	    	
 	    	if (action.equals("start"))
 	    	{
-		
 		        // Stop the previous session by interrupting the thread.
-		        if (mThreadVPN == null || (!mThreadVPN.isAlive()))
-		        {
-		        	Log.d(TAG,"starting OrbotVPNService service!");
-
-		        	mTorSocks = intent.getIntExtra("torSocks", -1);
-			    	
-		        	if (!mIsLollipop)
-		        	{
-		        		startSocksBypass();
-		        	}
-		        	
-		            setupTun2Socks(builder);               
-		        }
+		        if (mThreadVPN != null && mThreadVPN.isAlive())
+		        	stopVPN();
+
+				mLastBuilder = builder;
+
+				if (mTorSocks != -1)
+				{
+					if (!mIsLollipop)
+					{
+						startSocksBypass();
+					}
+
+					setupTun2Socks(builder);
+				}
+
+
 	    	}
 	    	else if (action.equals("stop"))
 	    	{
 	    		Log.d(TAG,"stop OrbotVPNService service!");
 	    		
-	    		stopVPN();    		
-	    		//if (mHandler != null)
-	    			//mHandler.postDelayed(new Runnable () { public void run () { stopSelf(); }}, 1000);
-	    	}
-	    	else if (action.equals("refresh"))
-	    	{
-	    		Log.d(TAG,"refresh OrbotVPNService service!");
-	    		
-	    		if (!mIsLollipop)
-	    		  startSocksBypass();
-	    		
-	    		if (!isRestart)
-	    			setupTun2Socks(builder);
+	    		stopVPN();
 	    	}
+	    	else if (action.equals(TorServiceConstants.LOCAL_ACTION_PORTS))
+			{
+				Log.d(TAG,"starting OrbotVPNService service!");
+
+				mTorSocks = intent.getIntExtra(TorService.EXTRA_SOCKS_PROXY_PORT,-1);
+				mTorDns = intent.getIntExtra(TorService.EXTRA_DNS_PORT,-1);
+
+				if (!mIsLollipop)
+				{
+					startSocksBypass();
+				}
+
+				setupTun2Socks(builder);
+			}
+
     	}
      
         
@@ -204,27 +211,7 @@ public class OrbotVpnManager implements Handler.Callback {
         
         
     }
-    
-    /**
-    @Override
-	public void onCreate() {
-		super.onCreate();
-		
-		// Set the locale to English (or probably any other language that^M
-        // uses Hindu-Arabic (aka Latin) numerals).^M
-        // We have found that VpnService.Builder does something locale-dependent^M
-        // internally that causes errors when the locale uses its own numerals^M
-        // (i.e., Farsi and Arabic).^M
-		Locale.setDefault(new Locale("en"));
-		
-	}
-
 
-	@Override
-    public void onDestroy() {
-    	stopVPN();
-    }*/
-    
     private void stopVPN ()
     {
     	if (mIsLollipop)
@@ -248,15 +235,11 @@ public class OrbotVpnManager implements Handler.Callback {
                 Log.d(TAG,"error stopping tun2socks",e);
             }   
         }
+
+        stopDns();
         
         Tun2Socks.Stop();
-        
-        try {
-        	killProcess(filePdnsd);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        
+
         mThreadVPN = null;
         
 
@@ -278,10 +261,11 @@ public class OrbotVpnManager implements Handler.Callback {
         {
         	isRestart = true;
         	Tun2Socks.Stop();
+
+			stopDns();
+
         }
 
-		final int localDns = getSharedPrefs(this.mService.getApplicationContext()).getInt(VpnPrefs.PREFS_DNS_PORT, 0);
-        
     	mThreadVPN = new Thread ()
     	{
     		
@@ -306,23 +290,20 @@ public class OrbotVpnManager implements Handler.Callback {
 		    		final String defaultRoute = "0.0.0.0";
 		    		
 		    		final String localSocks = localhost + ':' + mTorSocks;
-		    		
-		    		final String localDNS = virtualGateway + ':' + PDNSD_PORT;
 
-		    		final boolean localDnsTransparentProxy = true;
-		        	
-			        builder.setMtu(VPN_MTU);
+					builder.setMtu(VPN_MTU);
 			        builder.addAddress(virtualGateway,32);
 			        
-			        builder.setSession(vpnName);		        
+			        builder.setSession(vpnName);
+
+					//route all traffic through VPN (we might offer country specific exclude lists in the future)
+					builder.addRoute(defaultRoute,0);
 
 			        builder.addDnsServer(dummyDNS);
 			        builder.addRoute(dummyDNS,32);
-				        
-			        //route all traffic through VPN (we might offer country specific exclude lists in the future)
-			        builder.addRoute(defaultRoute,0);	
-			        
-			        //handle ipv6
+
+
+					//handle ipv6
 			        //builder.addAddress("fdfe:dcba:9876::1", 126);
 					//builder.addRoute("::", 0);
 			        
@@ -346,9 +327,11 @@ public class OrbotVpnManager implements Handler.Callback {
 		        	isRestart = false;
 
 					//start PDNSD daemon pointing to actual DNS
-					startDNS(filePdnsd.getCanonicalPath(), "127.0.0.1",localDns);
+					int pdnsdPort = 8091;
+					startDNS(filePdnsd.getCanonicalPath(), localhost,mTorDns, "0.0.0.0", pdnsdPort);
+					final boolean localDnsTransparentProxy = true;
 
-					Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , localDnsTransparentProxy);
+					Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , virtualGateway + ":" + pdnsdPort , localDnsTransparentProxy);
 
 
 				}
@@ -406,13 +389,10 @@ public class OrbotVpnManager implements Handler.Callback {
     
     }
 
-
-    private void startDNS (String pdnsPath, String dns, int port) throws IOException, TimeoutException
+    private void startDNS (String pdnsPath, String torDnsHost, int torDnsPort, String pdnsdHost, int pdnsdPort) throws IOException, TimeoutException
     {
 
-		File fileConf = makePdnsdConf(mService, dns, port,mService.getFilesDir());
-    	
-      //  ArrayList<String> customEnv = new ArrayList<String>();
+		File fileConf = makePdnsdConf(mService, mService.getFilesDir(), torDnsHost, torDnsPort, pdnsdHost, pdnsdPort);
 
         String[] cmdString = {pdnsPath,"-c",fileConf.toString()};
         ProcessBuilder pb = new ProcessBuilder(cmdString);
@@ -424,21 +404,46 @@ public class OrbotVpnManager implements Handler.Callback {
 
         if (proc.exitValue() != 0)
         {
-
             BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
 
             String line = null;
             while ((line = br.readLine ()) != null) {
                 Log.d(TAG,"pdnsd: " + line);
             }
-
         }
 
         
     }
+
+    private boolean stopDns ()
+	{
+		File filePid = new File(mService.getFilesDir(),"pdnsd.pid");
+		String pid = null;
+
+		if (filePid.exists())
+		{
+
+			try {
+				BufferedReader reader = new BufferedReader(new FileReader(filePid));
+				pid = reader.readLine().trim();
+
+				VpnUtils.killProcess(pid,"-9");
+				filePid.delete();
+				return true;
+
+			} catch (Exception e) {
+				Log.e(TAG,"error killing DNS Process: " + pid,e);
+			}
+		}
+
+		return false;
+
+	}
     
-    public static File makePdnsdConf(Context context, String dns, int port, File fileDir) throws FileNotFoundException, IOException {
-        String conf = String.format(context.getString(R.string.pdnsd_conf), dns, port, fileDir.getCanonicalPath());
+    public static File makePdnsdConf(Context context,  File fileDir, String torDnsHost, int torDnsPort, String pdnsdHost, int pdnsdPort) throws FileNotFoundException, IOException {
+        String conf = String.format(context.getString(R.string.pdnsd_conf), torDnsHost, torDnsPort, fileDir.getCanonicalPath(), pdnsdHost, pdnsdPort);
+
+        Log.d(TAG,"pdsnd conf:" + conf);
 
         File f = new File(fileDir,"pdnsd.conf");
 
@@ -464,5 +469,6 @@ public class OrbotVpnManager implements Handler.Callback {
         return f;
 	}
 
+
     
 }
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
index b02fd71a..e70753f6 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/TorVpnService.java
@@ -1,8 +1,15 @@
 package org.torproject.android.service.vpn;
 
 import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.net.VpnService;
+import android.support.v4.content.LocalBroadcastManager;
+
+import org.torproject.android.service.TorService;
+import org.torproject.android.service.TorServiceConstants;
 
 import java.io.IOException;
 import java.util.concurrent.TimeoutException;
@@ -23,6 +30,10 @@ public class TorVpnService extends VpnService {
         } catch (TimeoutException e) {
             e.printStackTrace();
         }
+
+        LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
+        lbm.registerReceiver(mLocalBroadcastReceiver,
+                new IntentFilter(TorServiceConstants.LOCAL_ACTION_PORTS));
     }
 
     /* (non-Javadoc)
@@ -34,4 +45,35 @@ public class TorVpnService extends VpnService {
 
         return Service.START_STICKY;
     }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+
+        LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
+        lbm.unregisterReceiver(mLocalBroadcastReceiver);
+    }
+
+    /**
+     * The state and log info from {@link TorService} are sent to the UI here in
+     * the form of a local broadcast. Regular broadcasts can be sent by any app,
+     * so local ones are used here so other apps cannot interfere with Orbot's
+     * operation.
+     */
+    private BroadcastReceiver mLocalBroadcastReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action == null)
+                return;
+
+            if (action.equals(TorServiceConstants.LOCAL_ACTION_PORTS)) {
+
+                mVpnManager.handleIntent(new Builder(),intent);
+            }
+        }
+    };
+
+
 }
diff --git a/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java b/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java
index ce862b04..5a9901ff 100644
--- a/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java
+++ b/orbotservice/src/main/java/org/torproject/android/service/vpn/VpnUtils.java
@@ -58,6 +58,22 @@ public class VpnUtils {
                         ());
             } catch (IOException ioe) {
             }
+            killProcess(pidString, signal);
+
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                // ignored
+            }
+
+            if (killAttempts > 4)
+                throw new Exception("Cannot kill: " + fileProcBin.getAbsolutePath());
+        }
+    }
+
+    public static void killProcess(String pidString, String signal) throws Exception {
+
+
             try {
                 getRuntime().exec("toolbox kill " + signal + " " + pidString);
             } catch (IOException ioe) {
@@ -71,14 +87,8 @@ public class VpnUtils {
             } catch (IOException ioe) {
             }
 
-            try {
-                Thread.sleep(1000);
-            } catch (InterruptedException e) {
-                // ignored
-            }
 
-            if (killAttempts > 4)
-                throw new Exception("Cannot kill: " + fileProcBin.getAbsolutePath());
-        }
+
+
     }
 }
diff --git a/orbotservice/src/main/res/values/pdnsd.xml b/orbotservice/src/main/res/values/pdnsd.xml
index 89122ebc..ce4609bc 100644
--- a/orbotservice/src/main/res/values/pdnsd.xml
+++ b/orbotservice/src/main/res/values/pdnsd.xml
@@ -4,8 +4,8 @@
 global {
 	perm_cache=0;
 	cache_dir="%3$s";
-	server_port = 8091;
-	server_ip = 192.168.200.1;
+	server_port = %5$d;
+	server_ip = %4$s;
 	query_method=udp_only;
 	min_ttl=1m;
 	max_ttl=1w;





More information about the tor-commits mailing list