commit e1ec776cb843cf5fdf5a37c299614af7dcf448df Author: Nathan Freitas nathan@freitas.net Date: Mon Jul 14 09:19:30 2014 -0400
re-arch status callbacks and improve notification --- res/layout/layout_notification_expanded.xml | 10 +- res/raw/torrc | 3 +- res/raw/torrcdiag | 7 - src/org/torproject/android/Orbot.java | 136 ++--- .../android/OrbotDiagnosticsActivity.java | 2 +- .../torproject/android/service/ITorService.aidl | 16 +- .../android/service/ITorServiceCallback.aidl | 24 - .../android/service/TorResourceInstaller.java | 7 +- src/org/torproject/android/service/TorService.java | 536 +++++++++----------- .../torproject/android/service/TorTransProxy.java | 2 +- 10 files changed, 345 insertions(+), 398 deletions(-)
diff --git a/res/layout/layout_notification_expanded.xml b/res/layout/layout_notification_expanded.xml index b61d6fe..c208583 100644 --- a/res/layout/layout_notification_expanded.xml +++ b/res/layout/layout_notification_expanded.xml @@ -114,7 +114,15 @@ android:src="@drawable/nav_refresh" /> --> </LinearLayout> - + <LinearLayout + android:layout_width="match_parent" + android:layout_height="1dp" + android:orientation="horizontal" + android:background="#999999" + android:layout_marginTop="3dp" + android:layout_marginBottom="3dp" + + /> <TextView android:id="@+id/text2" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/res/raw/torrc b/res/raw/torrc index 2a5a48a..1661704 100644 --- a/res/raw/torrc +++ b/res/raw/torrc @@ -3,5 +3,4 @@ ControlPort auto SOCKSPort 0 DNSPort 0 TransPort 0 -CookieAuthentication 1 -AvoidDiskWrites 1 \ No newline at end of file +CookieAuthentication 1 \ No newline at end of file diff --git a/res/raw/torrcdiag b/res/raw/torrcdiag deleted file mode 100644 index b8f9661..0000000 --- a/res/raw/torrcdiag +++ /dev/null @@ -1,7 +0,0 @@ -Log debug stdout -ControlPort auto -SOCKSPort 0 -DNSPort 0 -TransPort 0 -CookieAuthentication 1 -AvoidDiskWrites 1 \ No newline at end of file diff --git a/src/org/torproject/android/Orbot.java b/src/org/torproject/android/Orbot.java index 35d508e..06ffe57 100644 --- a/src/org/torproject/android/Orbot.java +++ b/src/org/torproject/android/Orbot.java @@ -9,7 +9,6 @@ import java.net.URLDecoder; import java.util.Locale;
import org.torproject.android.service.ITorService; -import org.torproject.android.service.ITorServiceCallback; import org.torproject.android.service.TorService; import org.torproject.android.service.TorServiceConstants; import org.torproject.android.service.TorServiceUtils; @@ -774,6 +773,8 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic { try { + torStatus = mService.getStatus(); + if (torStatus != TorServiceConstants.STATUS_ON) mService.processSettings(); @@ -937,7 +938,7 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic
} - else if (torStatus != newTorStatus) + else if (newTorStatus == TorServiceConstants.STATUS_OFF) { // mViewMain.setBackgroundResource(R.drawable.onionrootonlygrey); imgStatus.setImageResource(R.drawable.toroff); @@ -982,6 +983,7 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic Message msg = mHandler.obtainMessage(TorServiceConstants.ENABLE_TOR_MSG); msg.getData().putString(HANDLER_TOR_MSG, getString(R.string.status_starting_up)); mHandler.sendMessage(msg); + } else { @@ -1000,8 +1002,9 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic mService.setProfile(TorServiceConstants.PROFILE_OFF); Message msg = mHandler.obtainMessage(TorServiceConstants.DISABLE_TOR_MSG); mHandler.sendMessage(msg); + + updateStatus("");
- }
@@ -1043,61 +1046,72 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic return false;
} -
- /** - * This implementation is used to receive callbacks from the remote - * service. - * - * If we have this setup probably, we shouldn't have to poll or query status - * to the service, as it should send it as it changes or when we bind/unbind to it - * from this activity - */ - private ITorServiceCallback mCallback = new ITorServiceCallback.Stub() { - /** - * This is called by the remote service regularly to tell us about - * new values. Note that IPC calls are dispatched through a thread - * pool running in each process, so the code executing here will - * NOT be running in our main thread like most other things -- so, - * to update the UI, we need to use a Handler to hop over there. - */ - - //receive a new string vaule end-user displayable message from the ITorService - public void statusChanged(String value) { - - //pass it off to the progressDialog - Message msg = mHandler.obtainMessage(TorServiceConstants.STATUS_MSG); - msg.getData().putString(HANDLER_TOR_MSG, value); - mHandler.sendMessage(msg); + Thread threadUpdater = null; + boolean mKeepUpdating = false; + + public void initUpdates () + { + mKeepUpdating = true; + + if (threadUpdater == null || !threadUpdater.isAlive()) + { + threadUpdater = new Thread(new Runnable() + { + + public void run () + { + + while (mKeepUpdating) + { + try + { + if (mService != null) + { + for (String log : mService.getLog()) + { + Message msg = mHandler.obtainMessage(TorServiceConstants.LOG_MSG); + msg.getData().putString(HANDLER_TOR_MSG, log); + mHandler.sendMessage(msg); + } + + for (String status : mService.getStatusMessage()) + { + Message msg = mHandler.obtainMessage(TorServiceConstants.STATUS_MSG); + msg.getData().putString(HANDLER_TOR_MSG, status); + mHandler.sendMessage(msg); + } + + long[] bws = mService.getBandwidth(); + Message msg = mHandler.obtainMessage(TorServiceConstants.MESSAGE_TRAFFIC_COUNT); + msg.getData().putLong("download", bws[0]); + msg.getData().putLong("upload", bws[1]); + msg.getData().putLong("readTotal", bws[2]); + msg.getData().putLong("writeTotal", bws[3]); + mHandler.sendMessage(msg); + + try { Thread.sleep(1000); } + catch (Exception e){} + + + torStatus = mService.getStatus(); + } + } + catch (RemoteException re) + { + Log.e(TAG, "error getting service updates",re); + } + } + + } + }); + + threadUpdater.start(); + + } } - - @Override - public void logMessage(String value) throws RemoteException { - - Message msg = mHandler.obtainMessage(TorServiceConstants.LOG_MSG); - msg.getData().putString(HANDLER_TOR_MSG, value); - mHandler.sendMessage(msg); - - } - - @Override - public void updateBandwidth(long upload, long download, long written, long read) { - - Message msg = Message.obtain(); - msg.what = TorServiceConstants.MESSAGE_TRAFFIC_COUNT; - - Bundle data = new Bundle(); - data.putLong("upload", upload); - data.putLong("download", download); - data.putLong("readTotal",read); - data.putLong("writeTotal",written); - - msg.setData(data); - mHandler.sendMessage(msg); - - } - }; - + +
// this is what takes messages or values from the callback threads or other non-mainUI threads //and passes them back into the main UI thread for display to the user @@ -1177,13 +1191,13 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic // representation of that from the raw service object. mService = ITorService.Stub.asInterface(service);
- torStatus = TorServiceConstants.STATUS_OFF;
// We want to monitor the service for as long as we are // connected to it. try { - mService.registerCallback(mCallback); - + torStatus = mService.getStatus(); + initUpdates(); + if (autoStartFromIntent) { @@ -1205,15 +1219,15 @@ public class Orbot extends ActionBarActivity implements TorConstants, OnLongClic }
- -
}
public void onServiceDisconnected(ComponentName className) { + // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. + mKeepUpdating = false; mService = null; Log.d(TAG,"service was disconnected"); } diff --git a/src/org/torproject/android/OrbotDiagnosticsActivity.java b/src/org/torproject/android/OrbotDiagnosticsActivity.java index 717d3ee..4cc8c6b 100644 --- a/src/org/torproject/android/OrbotDiagnosticsActivity.java +++ b/src/org/torproject/android/OrbotDiagnosticsActivity.java @@ -119,7 +119,7 @@ public class OrbotDiagnosticsActivity extends Activity { File fileTor= new File(appBinHome, TorServiceConstants.TOR_ASSET_KEY); enableBinExec (fileTor, appBinHome); - InputStream is = getResources().openRawResource(R.raw.torrcdiag); + InputStream is = getResources().openRawResource(R.raw.torrc); File fileTorrc = new File(appBinHome, TorServiceConstants.TORRC_ASSET_KEY + "diag"); TorResourceInstaller.streamToFile(is,fileTorrc, false, false); diff --git a/src/org/torproject/android/service/ITorService.aidl b/src/org/torproject/android/service/ITorService.aidl index 4891b55..2d57c9b 100644 --- a/src/org/torproject/android/service/ITorService.aidl +++ b/src/org/torproject/android/service/ITorService.aidl @@ -1,6 +1,5 @@ package org.torproject.android.service;
-import org.torproject.android.service.ITorServiceCallback;
/** * an interface for calling on to a remote service @@ -8,16 +7,6 @@ import org.torproject.android.service.ITorServiceCallback; interface ITorService {
/** - * This allows Tor service to send messages back to the GUI - */ - void registerCallback(ITorServiceCallback cb); - - /** - * Remove registered callback interface. - */ - void unregisterCallback(ITorServiceCallback cb); - - /** * Get a simple int status value for the state of Tor **/ int getStatus(); @@ -58,4 +47,9 @@ interface ITorService { */ void newIdentity ();
+ String[] getStatusMessage (); + + String[] getLog (); + + long[] getBandwidth (); } diff --git a/src/org/torproject/android/service/ITorServiceCallback.aidl b/src/org/torproject/android/service/ITorServiceCallback.aidl deleted file mode 100644 index b7b6827..0000000 --- a/src/org/torproject/android/service/ITorServiceCallback.aidl +++ /dev/null @@ -1,24 +0,0 @@ -package org.torproject.android.service; - -/** - * Callback interface used to send - * synchronous notifications back to its clients. Note that this is a - * one-way interface so the server does not block waiting for the client. - */ -oneway interface ITorServiceCallback { - /** - * Called when the service has a something to display to the user - */ - void statusChanged(String value); - - /** - * Called when the service returns the bandwidth user to display to the user - */ - void updateBandwidth(long upload, long download, long written, long read); - - /** - * Called when the service has something to add to the log - */ - void logMessage(String value); - -} diff --git a/src/org/torproject/android/service/TorResourceInstaller.java b/src/org/torproject/android/service/TorResourceInstaller.java index 3e91ea4..923e841 100644 --- a/src/org/torproject/android/service/TorResourceInstaller.java +++ b/src/org/torproject/android/service/TorResourceInstaller.java @@ -77,12 +77,7 @@ public class TorResourceInstaller implements TorServiceConstants { outFile = new File(installFolder, TORRC_ASSET_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); streamToFile(is,outFile, false, false); - - is = context.getResources().openRawResource(R.raw.torrcdiag); - outFile = new File(installFolder, TORRCDIAG_ASSET_KEY); - shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); - streamToFile(is,outFile, false, false); - + is = context.getResources().openRawResource(R.raw.torrctether); outFile = new File(installFolder, TORRC_TETHER_KEY); shell.add(new SimpleCommand(COMMAND_RM_FORCE + outFile.getAbsolutePath())).waitForFinish(); diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java index baaa0a2..f72ba31 100644 --- a/src/org/torproject/android/service/TorService.java +++ b/src/org/torproject/android/service/TorService.java @@ -9,6 +9,7 @@ package org.torproject.android.service;
import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; @@ -16,15 +17,22 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; import java.io.PrintWriter; +import java.net.InetSocketAddress; +import java.net.Proxy; import java.net.Socket; +import java.net.URL; +import java.net.URLConnection; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Set; import java.util.StringTokenizer; import java.util.concurrent.TimeoutException; -import java.util.regex.Matcher; import java.util.regex.Pattern;
import net.freehaven.tor.control.ConfigEntry; @@ -32,6 +40,8 @@ import net.freehaven.tor.control.EventHandler; import net.freehaven.tor.control.TorControlConnection; import net.freehaven.tor.control.TorControlError;
+import org.json.JSONArray; +import org.json.JSONObject; import org.sufficientlysecure.rootcommands.Shell; import org.sufficientlysecure.rootcommands.command.SimpleCommand; import org.torproject.android.Orbot; @@ -56,9 +66,8 @@ import android.graphics.Color; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; -import android.os.Environment; +import android.os.Build; import android.os.IBinder; -import android.os.RemoteCallbackList; import android.os.RemoteException; import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat.Builder; @@ -84,9 +93,9 @@ public class TorService extends Service implements TorServiceConstants, TorConst private static final int HS_NOTIFY_ID = 4; private boolean prefPersistNotifications = true; - private String IPADDRESS_PATTERN = + private static final String IPADDRESS_PATTERN = "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; - private long exitIPTime = 0; + private final static Pattern pattern = Pattern.compile(IPADDRESS_PATTERN); private static final int MAX_START_TRIES = 3;
@@ -117,20 +126,13 @@ public class TorService extends Service implements TorServiceConstants, TorConst private NotificationManager mNotificationManager = null; private Builder mNotifyBuilder; private Notification mNotification; - private String exitIP = "";
private boolean mHasRoot = false; private boolean mEnableTransparentProxy = false; private boolean mTransProxyAll = false; private boolean mTransProxyTethering = false; -
- private ArrayList<String> callbackBuffer = new ArrayList<String>(); - private boolean inCallbackStatus = false; - private boolean inCallback = false; - - - public void logMessage(String msg) + public void debug(String msg) { if (ENABLE_DEBUG_LOG) { @@ -145,9 +147,15 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (ENABLE_DEBUG_LOG) { Log.e(TAG,msg,e); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + e.printStackTrace(new PrintStream(baos)); + + sendCallbackLogMessage(msg + '\n'+ new String(baos.toByteArray())); + } - - sendCallbackLogMessage(msg); + else + sendCallbackLogMessage(msg); +
}
@@ -212,9 +220,13 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (mNotificationManager != null) mNotificationManager.cancelAll(); + + hmBuiltNodes.clear(); + + } - @SuppressLint("NewApi") + @SuppressLint("NewApi") private void showToolbarNotification (String notifyMsg, int notifyType, int icon) { @@ -226,13 +238,44 @@ public class TorService extends Service implements TorServiceConstants, TorConst RemoteViews expandedView = new RemoteViews(this.getPackageName(), R.layout.layout_notification_expanded); + StringBuffer sbInfo = new StringBuffer(); + + if (notifyType == NOTIFY_ID) expandedView.setTextViewText(R.id.text, notifyMsg); else - expandedView.setTextViewText(R.id.text2, notifyMsg); + { + expandedView.setTextViewText(R.id.info, notifyMsg); + + } + + if (hmBuiltNodes.size() > 0) + { + sbInfo.append("Your Tor Public IPs:\n"); + Set<String> itBuiltNodes = hmBuiltNodes.keySet(); + for (String key : itBuiltNodes) + { + Node node = hmBuiltNodes.get(key); + + if (node.ipAddress != null) + sbInfo.append(node.ipAddress); + + if (node.country != null) + sbInfo.append(' ').append(node.country); + + if (node.organization != null) + sbInfo.append(" (").append(node.organization).append(')'); + + sbInfo.append('\n'); + + } + + expandedView.setTextViewText(R.id.text2, sbInfo.toString()); + } + + expandedView.setTextViewText(R.id.title, getString(R.string.app_name)); - expandedView.setTextViewText(R.id.title, getString(R.string.app_name)); - expandedView.setTextViewText(R.id.info, "Tor IP: " + exitIP); + // expandedView.setTextViewText(R.id.info, infoMessage.toString()); // expandedView.setOnClickPendingIntent(R.id._tor_notificationBT, pendIntent); expandedView.setImageViewResource(R.id.icon, icon); @@ -258,15 +301,17 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (notifyType != NOTIFY_ID) { mNotifyBuilder.setTicker(notifyMsg); - mNotifyBuilder.setLights(Color.RED, 1000, 1000); - mNotifyBuilder.setSmallIcon(R.drawable.ic_stat_notifyerr); + mNotifyBuilder.setLights(Color.GREEN, 1000, 1000); } mNotifyBuilder.setOngoing(prefPersistNotifications); mNotification = mNotifyBuilder.build(); - mNotification.bigContentView = expandedView; + if (Build.VERSION.SDK_INT >= 16) { + mNotification.bigContentView = expandedView; + } + if (mNotification == null && prefPersistNotifications) { startForeground(NOTIFY_ID, mNotification); @@ -352,9 +397,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst stopTor(); - // Unregister all callbacks. - mCallbacks.kill(); - unregisterReceiver(mNetworkStateReceiver);
} @@ -481,12 +523,12 @@ public class TorService extends Service implements TorServiceConstants, TorConst conn = null; } + else + killProcess(fileTor); - // killProcess(fileTor); killProcess(filePolipo); // killProcess(fileObfsclient); - }
private void killProcess (File fileProcBin) throws IOException @@ -586,12 +628,35 @@ public class TorService extends Service implements TorServiceConstants, TorConst String TORRC_CONTROLPORT_FILE_KEY = "ControlPortWriteToFile"; fileControlPort = new File(appBinHome,"control.txt"); - extraLines.append(TORRC_CONTROLPORT_FILE_KEY).append(' ').append(fileControlPort.getCanonicalPath()); - extraLines.append('\n'); + extraLines.append(TORRC_CONTROLPORT_FILE_KEY).append(' ').append(fileControlPort.getCanonicalPath()).append('\n'); + + String socksPort = prefs.getString(TorConstants.PREF_SOCKS, TorServiceConstants.PORT_SOCKS_DEFAULT); + + String transPort = prefs.getString("pref_transport", TorServiceConstants.TOR_TRANSPROXY_PORT_DEFAULT+""); + String dnsPort = prefs.getString("pref_dnsport", TorServiceConstants.TOR_DNS_PORT_DEFAULT+""); + + extraLines.append("RunAsDaemon 1").append('\n'); + + extraLines.append("AvoidDiskWrites 1").append('\n'); + + + extraLines.append("SOCKSPort ").append(socksPort).append('\n'); + extraLines.append("SafeSocks 0").append('\n'); + extraLines.append("TestSocks 0").append('\n'); + extraLines.append("WarnUnsafeSocks 1").append('\n'); + + extraLines.append("TransPort ").append(transPort).append('\n'); + extraLines.append("DNSPort ").append(dnsPort).append('\n'); + extraLines.append("VirtualAddrNetwork 10.192.0.0/10").append('\n'); + extraLines.append("AutomapHostsOnResolve 1").append('\n'); + + extraLines.append(prefs.getString("pref_custom_torrc", ""));
logNotice("updating torrc custom configuration...");
+ debug("torrc.custom=" + extraLines.toString()); + File fileTorRcCustom = new File(fileTorRc.getAbsolutePath() + ".custom"); boolean success = installer.updateTorConfigCustom(fileTorRcCustom, extraLines.toString()); @@ -625,7 +690,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst }
- private void updateSettings () + private void updateSettings () throws TimeoutException, IOException { SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
@@ -638,6 +703,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst Log.i(TAG,"debug logging:" + ENABLE_DEBUG_LOG);
prefPersistNotifications = prefs.getBoolean(TorConstants.PREF_PERSIST_NOTIFICATIONS, true); + + updateTorConfigFile(); }
public void initTor () throws Exception @@ -704,30 +771,29 @@ public class TorService extends Service implements TorServiceConstants, TorConst int code = 0; // Default state is "okay" - logMessage ("Transparent Proxying: clearing existing rules..."); + debug ("Transparent Proxying: clearing existing rules..."); //clear rules first mTransProxy.clearTransparentProxyingAll(this); if(proxyAll) { - showToolbarNotification(getString(R.string.setting_up_full_transparent_proxying_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_tor); + // showToolbarNotification(getString(R.string.setting_up_full_transparent_proxying_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_tor);
code = mTransProxy.setTransparentProxyingAll(this); } else { - showToolbarNotification(getString(R.string.setting_up_app_based_transparent_proxying_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_tor); + //showToolbarNotification(getString(R.string.setting_up_app_based_transparent_proxying_), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_tor);
code = mTransProxy.setTransparentProxyingByApp(this,AppManager.getApps(this, TorServiceUtils.getSharedPrefs(getApplicationContext()))); } - logMessage ("TorTransProxy resp code: " + code); + debug ("TorTransProxy resp code: " + code); if (code == 0) { - showToolbarNotification(getString(R.string.transparent_proxying_enabled), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_tor);
if (enableTether) { @@ -736,6 +802,11 @@ public class TorService extends Service implements TorServiceConstants, TorConst mTransProxy.enableTetheringRules(this); } + else + { + showToolbarNotification(getString(R.string.transparent_proxying_enabled), TRANSPROXY_NOTIFY_ID, R.drawable.ic_stat_tor); + + } } else { @@ -755,7 +826,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst private boolean disableTransparentProxy () throws Exception { - logMessage ("Transparent Proxying: disabling..."); + debug ("Transparent Proxying: disabling...");
if (mTransProxy == null) mTransProxy = new TorTransProxy(this, fileXtables); @@ -944,12 +1015,12 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (ENABLE_DEBUG_LOG) { - File fileLog = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),"orbot-control-log.txt"); - PrintWriter pr = new PrintWriter(new FileWriter(fileLog,true)); - conn.setDebugging(pr); + //File fileLog = new File(getFilesDir(),"orbot-control-log.txt"); + //PrintWriter pr = new PrintWriter(new FileWriter(fileLog,true)); + //conn.setDebugging(pr); - File fileLog2 = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),"orbot-tor-log.txt"); - conn.setConf("Log", "info file " + fileLog2.getCanonicalPath()); + File fileLog2 = new File(getFilesDir(),"orbot-tor-log.txt"); + conn.setConf("Log", "debug file " + fileLog2.getCanonicalPath()); } @@ -968,7 +1039,8 @@ public class TorService extends Service implements TorServiceConstants, TorConst catch (Exception ce) { conn = null; - logException( "Error connecting to Tor local control port",ce); + logException( "Error connecting to Tor local control port: " + ce.getMessage(),ce); + } try { @@ -1024,21 +1096,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst return result; } - private void checkAddressAndCountry () throws IOException - { - - if (TorService.ENABLE_DEBUG_LOG) - { - String torExternalAddress = conn.getInfo("address"); - String torCountry = conn.getInfo("ip-to-country/" + torExternalAddress); - - Log.d(TAG,"external address=" + torExternalAddress); - Log.d(TAG,"external country=" + torCountry); - - } - - } - /* private void getTorStatus () throws IOException { @@ -1104,36 +1161,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst return TorServiceConstants.PORT_HTTP; }
- /** - * Returns the port number that the SOCKS proxy is running on - */ - public int getSOCKSPort() throws RemoteException { - - int socksPort = -1; - - SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext()); - - String socksConfig = prefs.getString(TorConstants.PREF_SOCKS, TorServiceConstants.PORT_SOCKS_DEFAULT); - - try - { - - if (!socksConfig.equalsIgnoreCase("auto")) - if (socksConfig.contains(":")) - socksPort = Integer.parseInt(socksConfig.split(":")[1]); - else - socksPort = Integer.parseInt(socksConfig); - - } - catch (Exception e) - { - logException ("unable to parse socks config: " + socksConfig,e); - - } - - return socksPort; - } -
@@ -1258,7 +1285,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst mTotalTrafficWritten += written; mTotalTrafficRead += read; - sendCallbackStatusMessage(written, read, mTotalTrafficWritten, mTotalTrafficRead);
} @@ -1278,39 +1304,6 @@ public class TorService extends Service implements TorServiceConstants, TorConst //return count+" kB"; } - /* - class TotalUpdaterRunnable implements Runnable - { - - public void run () - { - - while (currentStatus != STATUS_OFF) - { - try - { - try - { - mTotalTrafficWritten = Long.parseLong(conn.getInfo("traffic/written")); - mTotalTrafficRead = Long.parseLong(conn.getInfo("traffic/read")); - - } - catch (Exception ioe) - { - Log.e(TAG,"error reading control port traffic",ioe); - } - - Thread.sleep(3000); //wait three seconds - } - catch (Exception e) - { - //nada - } - } - } - - }*/ - public void circuitStatus(String status, String circID, String path) { @@ -1322,14 +1315,34 @@ public class TorService extends Service implements TorServiceConstants, TorConst sb.append(": "); StringTokenizer st = new StringTokenizer(path,","); - String node = null; - String nodeName = null; + Node node = null; while (st.hasMoreTokens()) { - node = st.nextToken(); - nodeName = parseNodeName(node); - sb.append(nodeName); + String nodePath = st.nextToken(); + node = new Node(); + + String[] nodeParts; + + if (nodePath.contains("=")) + nodeParts = nodePath.split("="); + else + nodeParts = nodePath.split("~"); + + if (nodeParts.length == 1) + { + node.id = nodeParts[0].substring(1); + node.name = node.id; + } + else if (nodeParts.length == 2) + { + node.id = nodeParts[0].substring(1); + node.name = nodeParts[1]; + } + + node.status = status; + + sb.append(node.name); if (st.hasMoreTokens()) sb.append (" > "); @@ -1338,57 +1351,78 @@ public class TorService extends Service implements TorServiceConstants, TorConst logNotice(sb.toString()); //get IP from last nodename - if(status.equals("BUILT") && currentStatus==STATUS_ON){ - new getExternalIP().execute(nodeName); + if(status.equals("BUILT")){ + new getExternalIP().execute(node); + + hmBuiltNodes.put(node.id, node); + } + + if (status.equals("CLOSED")) + { + hmBuiltNodes.remove(node.id); + } } - private class getExternalIP extends AsyncTask<String, Void, String>{ + private HashMap<String,Node> hmBuiltNodes = new HashMap<String,Node>(); + + class Node + { + String status; + String id; + String name; + String ipAddress; + String country; + String organization; + } + + private class getExternalIP extends AsyncTask<Node, Void, Void>{
- private long time; @Override - protected String doInBackground(String... params) { - time = System.nanoTime(); - try { - String nodeDetails = conn.getInfo("ns/name/"+params[0]); - if (ENABLE_DEBUG_LOG) - { - Log.d(TAG,"Node Details: "+nodeDetails); - sendCallbackLogMessage("Node Details: "+nodeDetails); + protected Void doInBackground(Node... nodes) { + + if (conn != null) + { + try { + //String nodeDetails = conn.getInfo("ns/id/"+nodes[0].id); + Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8118));
- } - return nodeDetails; - } catch (TorControlError e) { - Log.d(TorService.TAG,"Error getting node details for: " + params[0]); - } catch (Exception e) { - Log.e(TorService.TAG,"Error getting node details",e); - } - return null; - } - - @Override - protected void onPostExecute(String result) { - // check if we need to update the exit IP - if(time > exitIPTime) { - exitIPTime = time; - - Pattern pattern = Pattern.compile(IPADDRESS_PATTERN); - Matcher matcher = null; - if(result!=null){ + URLConnection conn = new URL("https://onionoo.torproject.org/details?lookup=" + nodes[0].id).openConnection(proxy); + // getting JSON string from URL - sendCallbackLogMessage("Node Info: " + result); - - matcher = pattern.matcher(result); - if (matcher.find()) { - exitIP = matcher.group(); - sendCallbackLogMessage("Exit IP: "+exitIP); + StringBuffer json = new StringBuffer(); + String line = null; + BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + while ((line = reader.readLine())!=null) + json.append(line); + + JSONObject jsonNodeInfo = new org.json.JSONObject(json.toString()); + + JSONArray jsonRelays = jsonNodeInfo.getJSONArray("relays"); + if (jsonRelays.length() > 0) + { + nodes[0].ipAddress = jsonRelays.getJSONObject(0).getJSONArray("or_addresses").getString(0).split(":")[0]; + + nodes[0].country = jsonRelays.getJSONObject(0).getString("country_name"); + nodes[0].organization = jsonRelays.getJSONObject(0).getString("as_name"); + + + } + + return null; + + } catch (Exception e) { + + logException ("Error getting node details from onionoo",e); } } - } + return null; + } + } @@ -1432,28 +1466,12 @@ public class TorService extends Service implements TorServiceConstants, TorConst
} - - /** - * This is a list of callbacks that have been registered with the - * service. Note that this is package scoped (instead of private) so - * that it can be accessed more efficiently from inner classes. - */ - final RemoteCallbackList<ITorServiceCallback> mCallbacks - = new RemoteCallbackList<ITorServiceCallback>(); -
/** * The IRemoteInterface is defined through IDL */ private final ITorService.Stub mBinder = new ITorService.Stub() { - - public void registerCallback(ITorServiceCallback cb) { - if (cb != null) mCallbacks.register(cb); - } - public void unregisterCallback(ITorServiceCallback cb) { - if (cb != null) mCallbacks.unregister(cb); - } public int getStatus () { return getTorStatus(); } @@ -1607,13 +1625,15 @@ public class TorService extends Service implements TorServiceConstants, TorConst { public void run () { - try { conn.signal("NEWNYM"); + try { + + conn.signal("NEWNYM"); //checkAddressAndCountry(); } catch (IOException ioe){ - logMessage("error requesting newnym: " + ioe.getLocalizedMessage()); + debug("error requesting newnym: " + ioe.getLocalizedMessage()); } } }.start(); @@ -1632,7 +1652,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst for (String value : configBuffer) { - logMessage("removing torrc conf: " + value); + debug("removing torrc conf: " + value); } @@ -1647,7 +1667,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst for (String value : configBuffer) { - logMessage("Setting torrc conf: " + value); + debug("Setting torrc conf: " + value); } @@ -1674,111 +1694,59 @@ public class TorService extends Service implements TorServiceConstants, TorConst return false; } + + @Override + public String[] getStatusMessage() throws RemoteException { + + synchronized (mStatusBuffer) + { + String[] status = mStatusBuffer.toArray(new String[mStatusBuffer.size()]); + mStatusBuffer.clear(); + return status; + } + + } + + @Override + public String[] getLog() throws RemoteException { + + synchronized (mLogBuffer) + { + String[] status = mLogBuffer.toArray(new String[mLogBuffer.size()]); + mLogBuffer.clear(); + return status; + } + } + + public long[] getBandwidth() throws RemoteException { + + long[] bw = {lastRead,lastWritten,mTotalTrafficRead,mTotalTrafficWritten}; + return bw; + } }; - - private synchronized void sendCallbackStatusMessage (String newStatus) + private ArrayList<String> mStatusBuffer = new ArrayList<String>(); + + private void sendCallbackStatusMessage (String newStatus) { - - if (mCallbacks == null) - return; - - // Broadcast to all clients the new value. - final int N = mCallbacks.beginBroadcast(); - - inCallback = true; - - if (N > 0) - { - for (int i=0; i<N; i++) { - try { - mCallbacks.getBroadcastItem(i).statusChanged(newStatus); - - - } catch (RemoteException e) { - // The RemoteCallbackList will take care of removing - // the dead object for us. - } - } - } - - mCallbacks.finishBroadcast(); - inCallback = false; + mStatusBuffer.add(newStatus); }
- private synchronized void sendCallbackStatusMessage (long upload, long download, long written, long read) + private void sendCallbackStatusMessage (long upload, long download, long written, long read) { - if (mCallbacks == null) - return; - // Broadcast to all clients the new value. - final int N = mCallbacks.beginBroadcast(); - - inCallback = true; - - if (N > 0) - { - for (int i=0; i<N; i++) { - try { - mCallbacks.getBroadcastItem(i).updateBandwidth(upload, download, written, read); - - } catch (RemoteException e) { - // The RemoteCallbackList will take care of removing - // the dead object for us. - } - } - } - - mCallbacks.finishBroadcast(); - inCallback = false; }
+ private ArrayList<String> mLogBuffer = new ArrayList<String>();
- private synchronized void sendCallbackLogMessage (String logMessage) + + private void sendCallbackLogMessage (String logMessage) { - if (mCallbacks == null) - return; - callbackBuffer.add(logMessage); - - if (!inCallback) - { + mLogBuffer.add(logMessage);
- inCallback = true; - // Broadcast to all clients the new value. - final int N = mCallbacks.beginBroadcast(); - - - if (N > 0) - { - - Iterator<String> it = callbackBuffer.iterator(); - String status = null; - - while (it.hasNext()) - { - status = it.next(); - - for (int i=0; i<N; i++) { - try { - mCallbacks.getBroadcastItem(i).logMessage(status); - - } catch (RemoteException e) { - // The RemoteCallbackList will take care of removing - // the dead object for us. - } - } - } - - callbackBuffer.clear(); - } - - mCallbacks.finishBroadcast(); - inCallback = false; - } - }
/* @@ -1844,6 +1812,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
+ /* String socksConfig = prefs.getString(TorConstants.PREF_SOCKS, TorServiceConstants.PORT_SOCKS_DEFAULT);
enableSocks (socksConfig,false); @@ -1852,7 +1821,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst String dnsPort = prefs.getString("pref_dnsport", TorServiceConstants.TOR_DNS_PORT_DEFAULT+""); enableTransProxyAndDNSPorts(transPort, dnsPort); - + */ boolean useBridges = prefs.getBoolean(TorConstants.PREF_BRIDGES_ENABLED, false); @@ -1933,7 +1902,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst if (useBridges) { - logMessage ("Using bridges"); + debug ("Using bridges"); String bridgeCfgKey = "Bridge";
String bridgeList = prefs.getString(TorConstants.PREF_BRIDGES_LIST,null); @@ -1943,7 +1912,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst String msgBridge = getString(R.string.bridge_requires_ip) + getString(R.string.send_email_for_bridges); showToolbarNotification(msgBridge, ERROR_NOTIFY_ID, R.drawable.ic_stat_tor); - logMessage(msgBridge); + debug(msgBridge); return false; } @@ -1962,7 +1931,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst while (st.hasMoreTokens()) { String bridgeConfigLine = st.nextToken().trim(); - logMessage("Adding bridge: " + bridgeConfigLine); + debug("Adding bridge: " + bridgeConfigLine); mBinder.updateConfiguration(bridgeCfgKey, bridgeConfigLine, false);
} @@ -1974,13 +1943,13 @@ public class TorService extends Service implements TorServiceConstants, TorConst { String bridgeConfig = "obfs2,obfs3,scramblesuit exec " + fileObfsclient.getCanonicalPath(); - logMessage ("Using OBFUSCATED bridges: " + bridgeConfig); + debug ("Using OBFUSCATED bridges: " + bridgeConfig); mBinder.updateConfiguration("ClientTransportPlugin",bridgeConfig, false); } else { - logMessage ("Using standard bridges"); + debug ("Using standard bridges"); }
@@ -2077,7 +2046,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst
String hsDirPath = new File(appCacheHome,"hs" + hsPort).getCanonicalPath(); - logMessage("Adding hidden service on port: " + hsPortConfig); + debug("Adding hidden service on port: " + hsPortConfig); mBinder.updateConfiguration("HiddenServiceDir",hsDirPath, false); @@ -2104,6 +2073,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst return true; }
+ /* private void enableSocks (String socks, boolean safeSocks) throws RemoteException { mBinder.updateConfiguration("SOCKSPort", socks, false); @@ -2123,9 +2093,7 @@ public class TorService extends Service implements TorServiceConstants, TorConst mBinder.updateConfiguration("VirtualAddrNetwork","10.192.0.0/10",false); mBinder.updateConfiguration("AutomapHostsOnResolve","1",false); mBinder.saveConfiguration(); - - - } + }*/
private void blockPlaintextPorts (String portList) throws RemoteException { diff --git a/src/org/torproject/android/service/TorTransProxy.java b/src/org/torproject/android/service/TorTransProxy.java index bf3efbd..db97777 100644 --- a/src/org/torproject/android/service/TorTransProxy.java +++ b/src/org/torproject/android/service/TorTransProxy.java @@ -497,7 +497,7 @@ public class TorTransProxy implements TorServiceConstants { private void logMessage (String msg) { if (mTorService != null) - mTorService.logMessage(msg); + mTorService.debug(msg); } public int clearTransparentProxyingAll(Context context) throws Exception
tor-commits@lists.torproject.org